mirror of
https://github.com/richard-loafle/fuse-angular.git
synced 2025-12-22 10:07:07 +00:00
Compare commits
86 Commits
v8.1.0
...
v6.1.1-ske
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41a93857b6 | ||
|
|
0e2dca00c0 | ||
|
|
c93cecdddd | ||
|
|
3bd2ad9519 | ||
|
|
eb231c5ca8 | ||
|
|
954d61b73a | ||
|
|
46c37042a2 | ||
|
|
47ee65a980 | ||
|
|
5f974c4ed2 | ||
|
|
605f4d9463 | ||
|
|
4be77a19ed | ||
|
|
8374c7d059 | ||
|
|
da615585d0 | ||
|
|
7c50487164 | ||
|
|
97c7f136bf | ||
|
|
1cddda02b1 | ||
|
|
c178eeedaa | ||
|
|
43b22e609e | ||
|
|
a914ad6dc1 | ||
|
|
b2e840cb60 | ||
|
|
d7c67ca5a8 | ||
|
|
cf7ab3861d | ||
|
|
ab4ed81cfc | ||
|
|
2022b7307e | ||
|
|
46de82a7fa | ||
|
|
bc2b2c75fa | ||
|
|
02653cd0f4 | ||
|
|
ff14879a94 | ||
|
|
49c49c46d1 | ||
|
|
915e9203ef | ||
|
|
33d295f42c | ||
|
|
91e277ce3f | ||
|
|
b7a3d35eb8 | ||
|
|
f29f11232f | ||
|
|
16ffb09350 | ||
|
|
643a129a46 | ||
|
|
de16f4f866 | ||
|
|
415d7cebfa | ||
|
|
f7d1995f63 | ||
|
|
3741abc063 | ||
|
|
54ccdd7de2 | ||
|
|
8b2e6b95b1 | ||
|
|
e86cea1e73 | ||
|
|
b81638690e | ||
|
|
20ac3abb25 | ||
|
|
f634cb06a7 | ||
|
|
7d67a481ff | ||
|
|
4659da7390 | ||
|
|
2a5d15694c | ||
|
|
8e6024c3ee | ||
|
|
f4c47daadc | ||
|
|
381bc6c0fe | ||
|
|
b5a139f81d | ||
|
|
914477da41 | ||
|
|
410802808e | ||
|
|
56dbc58d5e | ||
|
|
d7c6b2d617 | ||
|
|
80627bdde9 | ||
|
|
6595975f2b | ||
|
|
dcb8032758 | ||
|
|
fb214da5fe | ||
|
|
e20687034f | ||
|
|
f9bda99deb | ||
|
|
1d81e37a0f | ||
|
|
83f0ed5ec1 | ||
|
|
e486413872 | ||
|
|
576e167ef1 | ||
|
|
cf9e9fc209 | ||
|
|
ff0f2933d9 | ||
|
|
62467c8ddf | ||
|
|
024ab15b25 | ||
|
|
915ad52863 | ||
|
|
97bfaa9979 | ||
|
|
6ae3e154c3 | ||
|
|
49b6ff7292 | ||
|
|
903688ab43 | ||
|
|
19f822cbab | ||
|
|
1d21a14d0e | ||
|
|
4bf2ba73ad | ||
|
|
6a3972fff8 | ||
|
|
dca16238eb | ||
|
|
2b91119d00 | ||
|
|
ff4899e8d2 | ||
|
|
e818c53f1d | ||
|
|
ca96fffadf | ||
|
|
d7003711ee |
11
angular.json
11
angular.json
@@ -24,8 +24,7 @@
|
||||
"tsConfig": "src/tsconfig.app.json",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets",
|
||||
"src/app/main/angular-material-elements"
|
||||
"src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.scss"
|
||||
@@ -103,9 +102,7 @@
|
||||
"src/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**",
|
||||
"**/src/app/fake-db/**/*",
|
||||
"**/src/assets/angular-material-examples/**/*"
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -127,9 +124,7 @@
|
||||
"options": {
|
||||
"tsConfig": "e2e/tsconfig.e2e.json",
|
||||
"exclude": [
|
||||
"**/node_modules/**",
|
||||
"**/src/app/fake-db/**/*",
|
||||
"**/src/assets/angular-material-examples/**/*"
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { MatMomentDateModule } from '@angular/material-moment-adapter';
|
||||
import { MatButtonModule, MatIconModule } from '@angular/material';
|
||||
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import 'hammerjs';
|
||||
|
||||
@@ -15,35 +14,14 @@ import { FuseSidebarModule, FuseThemeOptionsModule } from '@fuse/components';
|
||||
|
||||
import { fuseConfig } from 'app/fuse-config';
|
||||
|
||||
import { FakeDbService } from 'app/fake-db/fake-db.service';
|
||||
import { AppComponent } from 'app/app.component';
|
||||
import { AppStoreModule } from 'app/store/store.module';
|
||||
import { LayoutModule } from 'app/layout/layout.module';
|
||||
import { SampleModule } from 'app/main/sample/sample.module';
|
||||
|
||||
const appRoutes: Routes = [
|
||||
{
|
||||
path : 'apps',
|
||||
loadChildren: './main/apps/apps.module#AppsModule'
|
||||
},
|
||||
{
|
||||
path : 'pages',
|
||||
loadChildren: './main/pages/pages.module#PagesModule'
|
||||
},
|
||||
{
|
||||
path : 'ui',
|
||||
loadChildren: './main/ui/ui.module#UIModule'
|
||||
},
|
||||
{
|
||||
path : 'documentation',
|
||||
loadChildren: './main/documentation/documentation.module#DocumentationModule'
|
||||
},
|
||||
{
|
||||
path : 'angular-material-elements',
|
||||
loadChildren: './main/angular-material-elements/angular-material-elements.module#AngularMaterialElementsModule'
|
||||
},
|
||||
{
|
||||
path : '**',
|
||||
redirectTo: 'apps/dashboards/analytics'
|
||||
redirectTo: 'sample'
|
||||
}
|
||||
];
|
||||
|
||||
@@ -58,10 +36,6 @@ const appRoutes: Routes = [
|
||||
RouterModule.forRoot(appRoutes),
|
||||
|
||||
TranslateModule.forRoot(),
|
||||
InMemoryWebApiModule.forRoot(FakeDbService, {
|
||||
delay : 0,
|
||||
passThruUnknownUrl: true
|
||||
}),
|
||||
|
||||
// Material moment date module
|
||||
MatMomentDateModule,
|
||||
@@ -78,7 +52,7 @@ const appRoutes: Routes = [
|
||||
|
||||
// App modules
|
||||
LayoutModule,
|
||||
AppStoreModule
|
||||
SampleModule
|
||||
],
|
||||
bootstrap : [
|
||||
AppComponent
|
||||
|
||||
@@ -1,773 +0,0 @@
|
||||
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
|
||||
}
|
||||
];
|
||||
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
import {
|
||||
startOfDay,
|
||||
endOfDay,
|
||||
subDays,
|
||||
addDays,
|
||||
endOfMonth,
|
||||
isSameDay,
|
||||
isSameMonth,
|
||||
addHours
|
||||
} from 'date-fns';
|
||||
|
||||
export class CalendarFakeDb
|
||||
{
|
||||
|
||||
public static data = [
|
||||
{
|
||||
id : 'events',
|
||||
data: [
|
||||
{
|
||||
start : subDays(startOfDay(new Date()), 1),
|
||||
end : addDays(new Date(), 1),
|
||||
title : 'A 3 day event',
|
||||
allDay : false,
|
||||
color : {
|
||||
primary : '#ad2121',
|
||||
secondary: '#FAE3E3'
|
||||
},
|
||||
resizable: {
|
||||
beforeStart: true,
|
||||
afterEnd : true
|
||||
},
|
||||
draggable: true,
|
||||
meta : {
|
||||
location: 'Los Angeles',
|
||||
notes : 'Eos eu verear adipiscing, ex ornatus denique iracundia sed, quodsi oportere appellantur an pri.'
|
||||
}
|
||||
},
|
||||
{
|
||||
start : startOfDay(new Date()),
|
||||
title : 'An event with no end date',
|
||||
allDay : false,
|
||||
color : {
|
||||
primary : '#e3bc08',
|
||||
secondary: '#FDF1BA'
|
||||
},
|
||||
resizable: {
|
||||
beforeStart: true,
|
||||
afterEnd : true
|
||||
},
|
||||
draggable: true,
|
||||
meta : {
|
||||
location: 'Los Angeles',
|
||||
notes : 'Eos eu verear adipiscing, ex ornatus denique iracundia sed, quodsi oportere appellantur an pri.'
|
||||
}
|
||||
},
|
||||
{
|
||||
start : subDays(endOfMonth(new Date()), 3),
|
||||
end : addDays(endOfMonth(new Date()), 3),
|
||||
title : 'A long event that spans 2 months',
|
||||
allDay : false,
|
||||
color : {
|
||||
primary : '#1e90ff',
|
||||
secondary: '#D1E8FF'
|
||||
},
|
||||
resizable: {
|
||||
beforeStart: true,
|
||||
afterEnd : true
|
||||
},
|
||||
draggable: true,
|
||||
meta : {
|
||||
location: 'Los Angeles',
|
||||
notes : 'Eos eu verear adipiscing, ex ornatus denique iracundia sed, quodsi oportere appellantur an pri.'
|
||||
}
|
||||
},
|
||||
{
|
||||
start : addHours(startOfDay(new Date()), 2),
|
||||
end : new Date(),
|
||||
title : 'A draggable and resizable event',
|
||||
allDay : false,
|
||||
color : {
|
||||
primary : '#e3bc08',
|
||||
secondary: '#FDF1BA'
|
||||
},
|
||||
resizable: {
|
||||
beforeStart: true,
|
||||
afterEnd : true
|
||||
},
|
||||
draggable: true,
|
||||
meta : {
|
||||
location: 'Los Angeles',
|
||||
notes : 'Eos eu verear adipiscing, ex ornatus denique iracundia sed, quodsi oportere appellantur an pri.'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -1,325 +0,0 @@
|
||||
export class ChatFakeDb
|
||||
{
|
||||
public static contacts = [
|
||||
{
|
||||
'id' : '5725a680b3249760ea21de52',
|
||||
'name' : 'Alice Freeman',
|
||||
'avatar': 'assets/images/avatars/alice.jpg',
|
||||
'status': 'online',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680606588342058356d',
|
||||
'name' : 'Arnold',
|
||||
'avatar': 'assets/images/avatars/Arnold.jpg',
|
||||
'status': 'do-not-disturb',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a68009e20d0a9e9acf2a',
|
||||
'name' : 'Barrera',
|
||||
'avatar': 'assets/images/avatars/Barrera.jpg',
|
||||
'status': 'do-not-disturb',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...',
|
||||
'unread': null
|
||||
},
|
||||
{
|
||||
'id' : '5725a6809fdd915739187ed5',
|
||||
'name' : 'Blair',
|
||||
'avatar': 'assets/images/avatars/Blair.jpg',
|
||||
'status': 'offline',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...',
|
||||
'unread': 3
|
||||
},
|
||||
{
|
||||
'id' : '5725a68007920cf75051da64',
|
||||
'name' : 'Boyle',
|
||||
'avatar': 'assets/images/avatars/Boyle.jpg',
|
||||
'status': 'offline',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a68031fdbb1db2c1af47',
|
||||
'name' : 'Christy',
|
||||
'avatar': 'assets/images/avatars/Christy.jpg',
|
||||
'status': 'offline',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680bc670af746c435e2',
|
||||
'name' : 'Copeland',
|
||||
'avatar': 'assets/images/avatars/Copeland.jpg',
|
||||
'status': 'online',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680e7eb988a58ddf303',
|
||||
'name' : 'Estes',
|
||||
'avatar': 'assets/images/avatars/Estes.jpg',
|
||||
'status': 'away',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680dcb077889f758961',
|
||||
'name' : 'Harper',
|
||||
'avatar': 'assets/images/avatars/Harper.jpg',
|
||||
'status': 'offline',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a6806acf030f9341e925',
|
||||
'name' : 'Helen',
|
||||
'avatar': 'assets/images/avatars/Helen.jpg',
|
||||
'status': 'away',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680ae1ae9a3c960d487',
|
||||
'name' : 'Henderson',
|
||||
'avatar': 'assets/images/avatars/Henderson.jpg',
|
||||
'status': 'offline',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680b8d240c011dd224b',
|
||||
'name' : 'Josefina',
|
||||
'avatar': 'assets/images/avatars/Josefina.jpg',
|
||||
'status': 'online',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a68034cb3968e1f79eac',
|
||||
'name' : 'Katina',
|
||||
'avatar': 'assets/images/avatars/Katina.jpg',
|
||||
'status': 'away',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a6801146cce777df2a08',
|
||||
'name' : 'Lily',
|
||||
'avatar': 'assets/images/avatars/Lily.jpg',
|
||||
'status': 'do-not-disturb',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a6808a178bfd034d6ecf',
|
||||
'name' : 'Mai',
|
||||
'avatar': 'assets/images/avatars/Mai.jpg',
|
||||
'status': 'away',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680653c265f5c79b5a9',
|
||||
'name' : 'Nancy',
|
||||
'avatar': 'assets/images/avatars/Nancy.jpg',
|
||||
'status': 'do-not-disturb',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680bbcec3cc32a8488a',
|
||||
'name' : 'Nora',
|
||||
'avatar': 'assets/images/avatars/Nora.jpg',
|
||||
'status': 'do-not-disturb',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a6803d87f1b77e17b62b',
|
||||
'name' : 'Odessa',
|
||||
'avatar': 'assets/images/avatars/Odessa.jpg',
|
||||
'status': 'away',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680e87cb319bd9bd673',
|
||||
'name' : 'Reyna',
|
||||
'avatar': 'assets/images/avatars/Reyna.jpg',
|
||||
'status': 'offline',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a6802d10e277a0f35775',
|
||||
'name' : 'Shauna',
|
||||
'avatar': 'assets/images/avatars/Shauna.jpg',
|
||||
'status': 'online',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...',
|
||||
'unread': null
|
||||
},
|
||||
{
|
||||
'id' : '5725a680aef1e5cf26dd3d1f',
|
||||
'name' : 'Shepard',
|
||||
'avatar': 'assets/images/avatars/Shepard.jpg',
|
||||
'status': 'online',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680cd7efa56a45aea5d',
|
||||
'name' : 'Tillman',
|
||||
'avatar': 'assets/images/avatars/Tillman.jpg',
|
||||
'status': 'do-not-disturb',
|
||||
'mood' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680fb65c91a82cb35e2',
|
||||
'name' : 'Trevino',
|
||||
'avatar': 'assets/images/avatars/Trevino.jpg',
|
||||
'status': 'away',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a68018c663044be49cbf',
|
||||
'name' : 'Tyson',
|
||||
'avatar': 'assets/images/avatars/Tyson.jpg',
|
||||
'status': 'do-not-disturb',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a6809413bf8a0a5272b1',
|
||||
'name' : 'Velazquez',
|
||||
'avatar': 'assets/images/avatars/Velazquez.jpg',
|
||||
'status': 'online',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
}
|
||||
];
|
||||
|
||||
public static chats = [
|
||||
{
|
||||
'id' : '1725a680b3249760ea21de52',
|
||||
'dialog': [
|
||||
{
|
||||
'who' : '5725a680b3249760ea21de52',
|
||||
'message': 'Quickly come to the meeting room 1B, we have a big server issue',
|
||||
'time' : '2017-03-22T08:54:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a6802d10e277a0f35724',
|
||||
'message': 'I’m having breakfast right now, can’t you wait for 10 minutes?',
|
||||
'time' : '2017-03-22T08:55:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a680b3249760ea21de52',
|
||||
'message': 'We are losing money! Quick!',
|
||||
'time' : '2017-03-22T09:00:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a6802d10e277a0f35724',
|
||||
'message': 'It’s not my money, you know. I will eat my breakfast and then I will come to the meeting room.',
|
||||
'time' : '2017-03-22T09:02:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a680b3249760ea21de52',
|
||||
'message': 'You are the worst!',
|
||||
'time' : '2017-03-22T09:05:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a680b3249760ea21de52',
|
||||
'message': 'We are losing money! Quick!',
|
||||
'time' : '2017-03-22T09:15:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a6802d10e277a0f35724',
|
||||
'message': 'It’s not my money, you know. I will eat my breakfast and then I will come to the meeting room.',
|
||||
'time' : '2017-03-22T09:20:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a680b3249760ea21de52',
|
||||
'message': 'You are the worst!',
|
||||
'time' : '2017-03-22T09:22:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a680b3249760ea21de52',
|
||||
'message': 'We are losing money! Quick!',
|
||||
'time' : '2017-03-22T09:25:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a6802d10e277a0f35724',
|
||||
'message': 'It’s not my money, you know. I will eat my breakfast and then I will come to the meeting room.',
|
||||
'time' : '2017-03-22T09:27:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a680b3249760ea21de52',
|
||||
'message': 'You are the worst!',
|
||||
'time' : '2017-03-22T09:33:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a680b3249760ea21de52',
|
||||
'message': 'We are losing money! Quick!',
|
||||
'time' : '2017-03-22T09:35:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a6802d10e277a0f35724',
|
||||
'message': 'It’s not my money, you know. I will eat my breakfast and then I will come to the meeting room.',
|
||||
'time' : '2017-03-22T09:45:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a680b3249760ea21de52',
|
||||
'message': 'You are the worst!',
|
||||
'time' : '2017-03-22T10:00:28.299Z'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'id' : '2725a680b8d240c011dd2243',
|
||||
'dialog': [
|
||||
{
|
||||
'who' : '5725a680b8d240c011dd224b',
|
||||
'message': 'Quickly come to the meeting room 1B, we have a big server issue',
|
||||
'time' : '2017-04-22T01:00:00.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a6802d10e277a0f35724',
|
||||
'message': 'I’m having breakfast right now, can’t you wait for 10 minutes?',
|
||||
'time' : '2017-04-22T01:05:00.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a680b8d240c011dd224b',
|
||||
'message': 'We are losing money! Quick!',
|
||||
'time' : '2017-04-22T01:10:00.299Z'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'id' : '3725a6809413bf8a0a5272b4',
|
||||
'dialog': [
|
||||
{
|
||||
'who' : '5725a6809413bf8a0a5272b1',
|
||||
'message': 'Quickly come to the meeting room 1B, we have a big server issue',
|
||||
'time' : '2017-04-22T02:10:00.299Z'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
public static user = [
|
||||
{
|
||||
'id' : '5725a6802d10e277a0f35724',
|
||||
'name' : 'John Doe',
|
||||
'avatar' : 'assets/images/avatars/profile.jpg',
|
||||
'status' : 'online',
|
||||
'mood' : 'it\'s a status....not your diary...',
|
||||
'chatList': [
|
||||
{
|
||||
'id' : '1725a680b3249760ea21de52',
|
||||
'contactId' : '5725a680b3249760ea21de52',
|
||||
'name' : 'Alice Freeman',
|
||||
'unread' : 4,
|
||||
'lastMessageTime': '2017-06-12T02:10:18.931Z'
|
||||
},
|
||||
{
|
||||
'id' : '2725a680b8d240c011dd2243',
|
||||
'contactId' : '5725a680b8d240c011dd224b',
|
||||
'name' : 'Josefina',
|
||||
'unread' : null,
|
||||
'lastMessageTime': '2017-02-18T10:30:18.931Z'
|
||||
},
|
||||
{
|
||||
'id' : '3725a6809413bf8a0a5272b4',
|
||||
'contactId' : '5725a6809413bf8a0a5272b1',
|
||||
'name' : 'Velazquez',
|
||||
'unread' : 2,
|
||||
'lastMessageTime': '2017-03-18T12:30:18.931Z'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
}
|
||||
@@ -1,411 +0,0 @@
|
||||
export class ContactsFakeDb
|
||||
{
|
||||
public static contacts = [
|
||||
{
|
||||
'id' : '5725a680b3249760ea21de52',
|
||||
'name' : 'Abbott',
|
||||
'lastName': 'Keitch',
|
||||
'avatar' : 'assets/images/avatars/Abbott.jpg',
|
||||
'nickname': 'Royalguard',
|
||||
'company' : 'Saois',
|
||||
'jobTitle': 'Digital Archivist',
|
||||
'email' : 'abbott@withinpixels.com',
|
||||
'phone' : '+1-202-555-0175',
|
||||
'address' : '933 8th Street Stamford, CT 06902',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680606588342058356d',
|
||||
'name' : 'Arnold',
|
||||
'lastName': 'Matlock',
|
||||
'avatar' : 'assets/images/avatars/Arnold.jpg',
|
||||
'nickname': 'Wanderer',
|
||||
'company' : 'Laotcone',
|
||||
'jobTitle': 'Graphic Artist',
|
||||
'email' : 'arnold@withinpixels.com',
|
||||
'phone' : '+1-202-555-0141',
|
||||
'address' : '906 Valley Road Michigan City, IN 46360',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a68009e20d0a9e9acf2a',
|
||||
'name' : 'Barrera',
|
||||
'lastName': 'Bradbury',
|
||||
'avatar' : 'assets/images/avatars/Barrera.jpg',
|
||||
'nickname': 'Jackal',
|
||||
'company' : 'Unizim',
|
||||
'jobTitle': 'Graphic Designer',
|
||||
'email' : 'barrera@withinpixels.com',
|
||||
'phone' : '+1-202-555-0196',
|
||||
'address' : '183 River Street Passaic, NJ 07055',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a6809fdd915739187ed5',
|
||||
'name' : 'Blair',
|
||||
'lastName': 'Strangeway',
|
||||
'avatar' : 'assets/images/avatars/Blair.jpg',
|
||||
'nickname': 'Knight',
|
||||
'company' : 'Conedubdax',
|
||||
'jobTitle': 'Visual Designer',
|
||||
'email' : 'blair@withinpixels.com',
|
||||
'phone' : '+1-202-555-0118',
|
||||
'address' : '143 Jones Street Eau Claire, WI 54701',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a68007920cf75051da64',
|
||||
'name' : 'Boyle',
|
||||
'lastName': 'Winters',
|
||||
'avatar' : 'assets/images/avatars/Boyle.jpg',
|
||||
'nickname': 'Jester',
|
||||
'company' : 'Newo',
|
||||
'jobTitle': 'Catalogue Illustrator',
|
||||
'email' : 'boyle@withinpixels.com',
|
||||
'phone' : '+1-202-555-0177',
|
||||
'address' : '218 Pearl Street Brandon, FL 33510',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a68031fdbb1db2c1af47',
|
||||
'name' : 'Christy',
|
||||
'lastName': 'Camacho',
|
||||
'avatar' : 'assets/images/avatars/Christy.jpg',
|
||||
'nickname': 'Mist',
|
||||
'company' : 'uniway',
|
||||
'jobTitle': '3D Animator',
|
||||
'email' : 'christy@withinpixels.com',
|
||||
'phone' : '+1-202-555-0136',
|
||||
'address' : '329 Bridge Street Desoto, TX 75115',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680bc670af746c435e2',
|
||||
'name' : 'Copeland',
|
||||
'lastName': 'Redcliff',
|
||||
'avatar' : 'assets/images/avatars/Copeland.jpg',
|
||||
'nickname': 'Cloudlaw',
|
||||
'company' : 'Tempron',
|
||||
'jobTitle': 'Multimedia Artist',
|
||||
'email' : 'copeland@withinpixels.com',
|
||||
'phone' : '+1-202-555-0107',
|
||||
'address' : '956 6th Avenue North Bergen, NJ 0704',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680e7eb988a58ddf303',
|
||||
'name' : 'Estes',
|
||||
'lastName': 'Stevens',
|
||||
'avatar' : 'assets/images/avatars/Estes.jpg',
|
||||
'nickname': 'Roamer',
|
||||
'company' : 'nam-dex',
|
||||
'jobTitle': 'Special Effects Artist',
|
||||
'email' : 'estes@withinpixels.com',
|
||||
'phone' : '+1-202-555-0113',
|
||||
'address' : '664 York Street Cambridge, MA 02138',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680dcb077889f758961',
|
||||
'name' : 'Harper',
|
||||
'lastName': 'MacGuffin',
|
||||
'avatar' : 'assets/images/avatars/Harper.jpg',
|
||||
'nickname': 'Tempest',
|
||||
'company' : 'runcane',
|
||||
'jobTitle': 'Application Developer',
|
||||
'email' : 'harper@withinpixels.com',
|
||||
'phone' : '+1-202-555-0173',
|
||||
'address' : '738 Route 11 Cornelius, NC 28031',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a6806acf030f9341e925',
|
||||
'name' : 'Helen',
|
||||
'lastName': 'Sheridan',
|
||||
'avatar' : 'assets/images/avatars/Helen.jpg',
|
||||
'nickname': 'Magicbattler',
|
||||
'company' : 'Subhow',
|
||||
'jobTitle': 'Content Developer',
|
||||
'email' : 'helen@withinpixels.com',
|
||||
'phone' : '+1-202-555-0163',
|
||||
'address' : '194 Washington Avenue Saint Petersburg, FL 33702',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680ae1ae9a3c960d487',
|
||||
'name' : 'Henderson',
|
||||
'lastName': 'Cambias',
|
||||
'avatar' : 'assets/images/avatars/Henderson.jpg',
|
||||
'nickname': 'Blizzard',
|
||||
'company' : 'Howcom',
|
||||
'jobTitle': 'Web Designer',
|
||||
'email' : 'henderson@withinpixels.com',
|
||||
'phone' : '+1-202-555-0151',
|
||||
'address' : '686 Roosevelt Avenue Oviedo, FL 32765',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680b8d240c011dd224b',
|
||||
'name' : 'Josefina',
|
||||
'lastName': 'Lakefield',
|
||||
'avatar' : 'assets/images/avatars/Josefina.jpg',
|
||||
'nickname': 'Violet',
|
||||
'company' : 'Gecko',
|
||||
'jobTitle': 'Web Developer',
|
||||
'email' : 'josefina@withinpixels.com',
|
||||
'phone' : '+1-202-555-0160',
|
||||
'address' : '202 Hartford Road Lynchburg, VA 24502',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a68034cb3968e1f79eac',
|
||||
'name' : 'Katina',
|
||||
'lastName': 'Bletchley',
|
||||
'avatar' : 'assets/images/avatars/Katina.jpg',
|
||||
'nickname': 'Rose',
|
||||
'company' : 'Lexicom',
|
||||
'jobTitle': 'Software Designer',
|
||||
'email' : 'katina@withinpixels.com',
|
||||
'phone' : '+1-202-555-0186',
|
||||
'address' : '219 Woodland Road Valrico, FL 33594',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a6801146cce777df2a08',
|
||||
'name' : 'Lily',
|
||||
'lastName': 'Peasegood',
|
||||
'avatar' : 'assets/images/avatars/Lily.jpg',
|
||||
'nickname': 'Star',
|
||||
'company' : 'zooflex',
|
||||
'jobTitle': 'Software Specialist',
|
||||
'email' : 'lily@withinpixels.com',
|
||||
'phone' : '+1-202-555-0115',
|
||||
'address' : '305 Willow Drive Superior, WI 54880',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a6808a178bfd034d6ecf',
|
||||
'name' : 'Mai',
|
||||
'lastName': 'Nox',
|
||||
'avatar' : 'assets/images/avatars/Mai.jpg',
|
||||
'nickname': 'Violetmage',
|
||||
'company' : 'quadzone',
|
||||
'jobTitle': 'Software Engineer',
|
||||
'email' : 'mai@withinpixels.com',
|
||||
'phone' : '+1-202-555-0199',
|
||||
'address' : '148 Heather Lane Mcminnville, TN 37110',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680653c265f5c79b5a9',
|
||||
'name' : 'Nancy',
|
||||
'lastName': 'Jaggers',
|
||||
'avatar' : 'assets/images/avatars/Nancy.jpg',
|
||||
'nickname': 'Silverwarden',
|
||||
'company' : 'Opetamnix',
|
||||
'jobTitle': 'Software Architect',
|
||||
'email' : 'nancy@withinpixels.com',
|
||||
'phone' : '+1-202-555-0120',
|
||||
'address' : '345 Laurel Lane Union City, NJ 07087',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680bbcec3cc32a8488a',
|
||||
'name' : 'Nora',
|
||||
'lastName': 'Franklin',
|
||||
'avatar' : 'assets/images/avatars/Nora.jpg',
|
||||
'nickname': 'Katanachanter',
|
||||
'company' : 'Saoway',
|
||||
'jobTitle': 'Database Coordinator',
|
||||
'email' : 'nora@withinpixels.com',
|
||||
'phone' : '+1-202-555-0172',
|
||||
'address' : '572 Rose Street Summerfield, FL 34491',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a6803d87f1b77e17b62b',
|
||||
'name' : 'Odessa',
|
||||
'lastName': 'Goodman',
|
||||
'avatar' : 'assets/images/avatars/Odessa.jpg',
|
||||
'nickname': 'Rose',
|
||||
'company' : 'transace',
|
||||
'jobTitle': 'Database Administration Manager',
|
||||
'email' : 'odessa@withinpixels.com',
|
||||
'phone' : '+1-202-555-0190',
|
||||
'address' : '527 Jefferson Court Conyers, GA 30012',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680e87cb319bd9bd673',
|
||||
'name' : 'Reyna',
|
||||
'lastName': 'Preece',
|
||||
'avatar' : 'assets/images/avatars/Reyna.jpg',
|
||||
'nickname': 'Holydawn',
|
||||
'company' : 'Dingex',
|
||||
'jobTitle': 'Data Processing Planner',
|
||||
'email' : 'reyna@withinpixels.com',
|
||||
'phone' : '+1-202-555-0116',
|
||||
'address' : '297 Strawberry Lane Faribault, MN 55021',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a6802d10e277a0f35775',
|
||||
'name' : 'Shauna',
|
||||
'lastName': 'Atherton',
|
||||
'avatar' : 'assets/images/avatars/Shauna.jpg',
|
||||
'nickname': 'Faunasoul',
|
||||
'company' : 'Vivaflex',
|
||||
'jobTitle': 'Art Director',
|
||||
'email' : 'shauna@withinpixels.com',
|
||||
'phone' : '+1-202-555-0159',
|
||||
'address' : '928 Canterbury Court Pittsburgh, PA 15206',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680aef1e5cf26dd3d1f',
|
||||
'name' : 'Shepard',
|
||||
'lastName': 'Rosco',
|
||||
'avatar' : 'assets/images/avatars/Shepard.jpg',
|
||||
'nickname': 'Fireking',
|
||||
'company' : 'Goldenla',
|
||||
'jobTitle': 'Magazine Designer',
|
||||
'email' : 'shepard@withinpixels.com',
|
||||
'phone' : '+1-202-555-0173',
|
||||
'address' : '904 Ridge Road Pickerington, OH 43147',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680cd7efa56a45aea5d',
|
||||
'name' : 'Tillman',
|
||||
'lastName': 'Lee',
|
||||
'avatar' : 'assets/images/avatars/Tillman.jpg',
|
||||
'nickname': 'Gust',
|
||||
'company' : 'K-techno',
|
||||
'jobTitle': 'News Photographer',
|
||||
'email' : 'tillman@withinpixels.com',
|
||||
'phone' : '+1-202-555-0183',
|
||||
'address' : '447 Charles Street Dorchester, MA 02125',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680fb65c91a82cb35e2',
|
||||
'name' : 'Trevino',
|
||||
'lastName': 'Bush',
|
||||
'avatar' : 'assets/images/avatars/Trevino.jpg',
|
||||
'nickname': 'Wolf',
|
||||
'company' : 'Dalthex',
|
||||
'jobTitle': 'Photojournalist',
|
||||
'email' : 'trevino@withinpixels.com',
|
||||
'phone' : '+1-202-555-0138',
|
||||
'address' : '84 Valley View Road Norman, OK 73072',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a68018c663044be49cbf',
|
||||
'name' : 'Tyson',
|
||||
'lastName': 'Marshall',
|
||||
'avatar' : 'assets/images/avatars/Tyson.jpg',
|
||||
'nickname': 'Honordread',
|
||||
'company' : 'Geocon',
|
||||
'jobTitle': 'Manuscript Editor',
|
||||
'email' : 'tyson@withinpixels.com',
|
||||
'phone' : '+1-202-555-0146',
|
||||
'address' : '204 Clark Street Monsey, NY 10952',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a6809413bf8a0a5272b1',
|
||||
'name' : 'Velazquez',
|
||||
'lastName': 'Smethley',
|
||||
'avatar' : 'assets/images/avatars/Velazquez.jpg',
|
||||
'nickname': 'Strifedream',
|
||||
'company' : 'ranex',
|
||||
'jobTitle': 'Publications Editor',
|
||||
'email' : 'velezquez@withinpixels.com',
|
||||
'phone' : '+1-202-555-0146',
|
||||
'address' : '261 Cleveland Street Riverside, NJ 08075',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
}
|
||||
];
|
||||
|
||||
public static user = [
|
||||
{
|
||||
'id' : '5725a6802d10e277a0f35724',
|
||||
'name' : 'John Doe',
|
||||
'avatar' : 'assets/images/avatars/profile.jpg',
|
||||
'starred' : [
|
||||
'5725a680ae1ae9a3c960d487',
|
||||
'5725a6801146cce777df2a08',
|
||||
'5725a680bbcec3cc32a8488a',
|
||||
'5725a680bc670af746c435e2',
|
||||
'5725a68009e20d0a9e9acf2a'
|
||||
],
|
||||
'frequentContacts': [
|
||||
'5725a6809fdd915739187ed5',
|
||||
'5725a68031fdbb1db2c1af47',
|
||||
'5725a680606588342058356d',
|
||||
'5725a680e7eb988a58ddf303',
|
||||
'5725a6806acf030f9341e925',
|
||||
'5725a68034cb3968e1f79eac',
|
||||
'5725a6801146cce777df2a08',
|
||||
'5725a680653c265f5c79b5a9'
|
||||
],
|
||||
'groups' : [
|
||||
{
|
||||
'id' : '5725a6802d10e277a0f35739',
|
||||
'name' : 'Friends',
|
||||
'contactIds': [
|
||||
'5725a680bbcec3cc32a8488a',
|
||||
'5725a680e87cb319bd9bd673',
|
||||
'5725a6802d10e277a0f35775'
|
||||
]
|
||||
},
|
||||
{
|
||||
'id' : '5725a6802d10e277a0f35749',
|
||||
'name' : 'Clients',
|
||||
'contactIds': [
|
||||
'5725a680cd7efa56a45aea5d',
|
||||
'5725a68018c663044be49cbf',
|
||||
'5725a6809413bf8a0a5272b1',
|
||||
'5725a6803d87f1b77e17b62b'
|
||||
]
|
||||
},
|
||||
{
|
||||
'id' : '5725a6802d10e277a0f35329',
|
||||
'name' : 'Recent Workers',
|
||||
'contactIds': [
|
||||
'5725a680bbcec3cc32a8488a',
|
||||
'5725a680653c265f5c79b5a9',
|
||||
'5725a6808a178bfd034d6ecf',
|
||||
'5725a6801146cce777df2a08'
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -1,602 +0,0 @@
|
||||
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
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,97 +0,0 @@
|
||||
import { InMemoryDbService } from 'angular-in-memory-web-api';
|
||||
|
||||
import { ProjectDashboardDb } from 'app/fake-db/dashboard-project';
|
||||
import { AnalyticsDashboardDb } from 'app/fake-db/dashboard-analytics';
|
||||
import { CalendarFakeDb } from 'app/fake-db/calendar';
|
||||
import { ECommerceFakeDb } from 'app/fake-db/e-commerce';
|
||||
import { AcademyFakeDb } from 'app/fake-db/academy';
|
||||
import { MailFakeDb } from 'app/fake-db/mail';
|
||||
import { ChatFakeDb } from 'app/fake-db/chat';
|
||||
import { FileManagerFakeDb } from 'app/fake-db/file-manager';
|
||||
import { ContactsFakeDb } from 'app/fake-db/contacts';
|
||||
import { TodoFakeDb } from 'app/fake-db/todo';
|
||||
import { ScrumboardFakeDb } from 'app/fake-db/scrumboard';
|
||||
import { InvoiceFakeDb } from 'app/fake-db/invoice';
|
||||
import { ProfileFakeDb } from 'app/fake-db/profile';
|
||||
import { SearchFakeDb } from 'app/fake-db/search';
|
||||
import { FaqFakeDb } from 'app/fake-db/faq';
|
||||
import { KnowledgeBaseFakeDb } from 'app/fake-db/knowledge-base';
|
||||
import { IconsFakeDb } from 'app/fake-db/icons';
|
||||
import { QuickPanelFakeDb } from 'app/fake-db/quick-panel';
|
||||
|
||||
export class FakeDbService implements InMemoryDbService
|
||||
{
|
||||
createDb(): any
|
||||
{
|
||||
return {
|
||||
// Dashboards
|
||||
'project-dashboard-projects' : ProjectDashboardDb.projects,
|
||||
'project-dashboard-widgets' : ProjectDashboardDb.widgets,
|
||||
'analytics-dashboard-widgets': AnalyticsDashboardDb.widgets,
|
||||
|
||||
// Calendar
|
||||
'calendar': CalendarFakeDb.data,
|
||||
|
||||
// E-Commerce
|
||||
'e-commerce-dashboard': ECommerceFakeDb.dashboard,
|
||||
'e-commerce-products' : ECommerceFakeDb.products,
|
||||
'e-commerce-orders' : ECommerceFakeDb.orders,
|
||||
|
||||
// Academy
|
||||
'academy-categories': AcademyFakeDb.categories,
|
||||
'academy-courses' : AcademyFakeDb.courses,
|
||||
'academy-course' : AcademyFakeDb.course,
|
||||
|
||||
// Mail
|
||||
'mail-mails' : MailFakeDb.mails,
|
||||
'mail-folders': MailFakeDb.folders,
|
||||
'mail-filters': MailFakeDb.filters,
|
||||
'mail-labels' : MailFakeDb.labels,
|
||||
|
||||
// Chat
|
||||
'chat-contacts': ChatFakeDb.contacts,
|
||||
'chat-chats' : ChatFakeDb.chats,
|
||||
'chat-user' : ChatFakeDb.user,
|
||||
|
||||
// File Manager
|
||||
'file-manager': FileManagerFakeDb.files,
|
||||
|
||||
// Contacts
|
||||
'contacts-contacts': ContactsFakeDb.contacts,
|
||||
'contacts-user' : ContactsFakeDb.user,
|
||||
|
||||
// Todo
|
||||
'todo-todos' : TodoFakeDb.todos,
|
||||
'todo-filters': TodoFakeDb.filters,
|
||||
'todo-tags' : TodoFakeDb.tags,
|
||||
|
||||
// Scrumboard
|
||||
'scrumboard-boards': ScrumboardFakeDb.boards,
|
||||
|
||||
// Invoice
|
||||
'invoice': InvoiceFakeDb.invoice,
|
||||
|
||||
// Profile
|
||||
'profile-timeline' : ProfileFakeDb.timeline,
|
||||
'profile-photos-videos': ProfileFakeDb.photosVideos,
|
||||
'profile-about' : ProfileFakeDb.about,
|
||||
|
||||
// Search
|
||||
'search-classic': SearchFakeDb.classic,
|
||||
'search-table' : SearchFakeDb.table,
|
||||
|
||||
// FAQ
|
||||
'faq': FaqFakeDb.data,
|
||||
|
||||
// Knowledge base
|
||||
'knowledge-base': KnowledgeBaseFakeDb.data,
|
||||
|
||||
// Icons
|
||||
'icons': IconsFakeDb.icons,
|
||||
|
||||
// Quick Panel
|
||||
'quick-panel-notes' : QuickPanelFakeDb.notes,
|
||||
'quick-panel-events': QuickPanelFakeDb.events
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
export class FaqFakeDb
|
||||
{
|
||||
public static data = [
|
||||
{
|
||||
'question': 'Proident tempor est nulla irure ad est?',
|
||||
'answer': 'Id nulla nulla proident deserunt deserunt proident in quis. Cillum reprehenderit labore id anim laborum.'
|
||||
},
|
||||
{
|
||||
'question': 'Ullamco duis commodo sint ad aliqua aute?',
|
||||
'answer': 'Sunt laborum enim nostrud ea fugiat cillum mollit aliqua exercitation ad elit.'
|
||||
},
|
||||
{
|
||||
'question': 'Eiusmod non occaecat pariatur Lorem in ex?',
|
||||
'answer': 'Nostrud anim mollit incididunt qui qui sit commodo duis. Anim amet irure aliquip duis nostrud sit quis fugiat ullamco non dolor labore. Lorem sunt voluptate laboris culpa proident. Aute eiusmod aliqua exercitation irure exercitation qui laboris mollit occaecat eu occaecat fugiat.'
|
||||
},
|
||||
{
|
||||
'question': 'Lorem magna cillum consequat consequat mollit?',
|
||||
'answer': 'Velit ipsum proident ea incididunt et. Consectetur eiusmod laborum voluptate duis occaecat ullamco sint enim proident.'
|
||||
},
|
||||
{
|
||||
'question': 'Quis irure cupidatat ad consequat reprehenderit excepteur?',
|
||||
'answer': 'Esse nisi mollit aliquip mollit aute consequat adipisicing. Do excepteur dolore proident cupidatat pariatur irure consequat incididunt.'
|
||||
},
|
||||
{
|
||||
'question': 'Officia voluptate tempor ut mollit ea cillum?',
|
||||
'answer': 'Deserunt veniam reprehenderit do elit magna ut.'
|
||||
},
|
||||
{
|
||||
'question': 'Sunt fugiat officia nisi minim sunt duis?',
|
||||
'answer': 'Eiusmod eiusmod sint aliquip exercitation cillum. Magna nulla officia ex consectetur ea ad excepteur in qui.'
|
||||
},
|
||||
{
|
||||
'question': 'Non cupidatat enim quis aliquip minim laborum?',
|
||||
'answer': 'Qui cillum eiusmod nostrud sunt dolore velit nostrud labore voluptate ad dolore. Eu Lorem anim pariatur aliqua. Ullamco ut dolor velit esse occaecat dolore eu cillum commodo qui. Nulla dolor consequat voluptate magna ut commodo magna consectetur non aute proident.'
|
||||
},
|
||||
{
|
||||
'question': 'Dolor ex occaecat magna labore laboris qui?',
|
||||
'answer': 'Incididunt qui excepteur eiusmod elit cillum occaecat voluptate cillum nostrud. Dolor ullamco ullamco eiusmod do sunt adipisicing pariatur. In esse esse labore id reprehenderit sint do. Pariatur culpa dolor tempor qui excepteur duis do anim minim ipsum.'
|
||||
},
|
||||
{
|
||||
'question': 'Nisi et ullamco minim ea proident tempor?',
|
||||
'answer': 'Dolor veniam dolor cillum Lorem magna nisi in occaecat nulla dolor ea eiusmod.'
|
||||
},
|
||||
{
|
||||
'question': 'Amet sunt et quis amet commodo quis?',
|
||||
'answer': 'Nulla dolore consequat aliqua sint consequat elit qui occaecat et.'
|
||||
},
|
||||
{
|
||||
'question': 'Ut eiusmod ex ea eiusmod culpa incididunt?',
|
||||
'answer': 'Fugiat non incididunt officia ex incididunt occaecat. Voluptate nostrud culpa aliquip mollit incididunt non dolore.'
|
||||
},
|
||||
{
|
||||
'question': 'Proident reprehenderit laboris pariatur ut et nisi?',
|
||||
'answer': 'Reprehenderit proident ut ad cillum quis velit quis aliqua ut aliquip tempor ullamco.'
|
||||
},
|
||||
{
|
||||
'question': 'Aliqua aliquip aliquip aliquip et exercitation aute?',
|
||||
'answer': 'Adipisicing Lorem tempor ex anim. Labore tempor laboris nostrud dolore voluptate ullamco. Fugiat ex deserunt anim minim esse velit laboris aute ea duis incididunt. Elit irure id Lorem incididunt laborum aliquip consectetur est irure sunt. Ut labore anim nisi aliqua tempor laborum nulla cillum. Duis irure consequat cillum magna cillum eiusmod ut. Et exercitation voluptate quis deserunt elit quis dolor deserunt ex ex esse ex.'
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
export class FileManagerFakeDb
|
||||
{
|
||||
public static files = [
|
||||
{
|
||||
'name' : 'Work Documents',
|
||||
'type' : 'folder',
|
||||
'owner' : 'me',
|
||||
'size' : '',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true
|
||||
},
|
||||
{
|
||||
'name' : 'Public Documents',
|
||||
'type' : 'folder',
|
||||
'owner' : 'public',
|
||||
'size' : '',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true
|
||||
},
|
||||
{
|
||||
'name' : 'Private Documents',
|
||||
'type' : 'folder',
|
||||
'owner' : 'me',
|
||||
'size' : '',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true
|
||||
},
|
||||
{
|
||||
'name' : 'Ongoing projects',
|
||||
'type' : 'document',
|
||||
'owner' : 'Emily Bennett',
|
||||
'size' : '1.2 Mb',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true,
|
||||
'preview' : 'assets/images/etc/sample-file-preview.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'Shopping list',
|
||||
'type' : 'document',
|
||||
'owner' : 'Emily Bennett',
|
||||
'size' : '980 Kb',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true,
|
||||
'preview' : 'assets/images/etc/sample-file-preview.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'Invoices',
|
||||
'type' : 'spreadsheet',
|
||||
'owner' : 'Emily Bennett',
|
||||
'size' : '750 Kb',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true,
|
||||
'preview' : 'assets/images/etc/sample-file-preview.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'Crash logs',
|
||||
'type' : 'document',
|
||||
'owner' : 'Emily Bennett',
|
||||
'size' : '980 Mb',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true,
|
||||
'preview' : 'assets/images/etc/sample-file-preview.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'System logs',
|
||||
'type' : 'document',
|
||||
'owner' : 'Emily Bennett',
|
||||
'size' : '52 Kb',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true,
|
||||
'preview' : 'assets/images/etc/sample-file-preview.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'Prices',
|
||||
'type' : 'spreadsheet',
|
||||
'owner' : 'Emily Bennett',
|
||||
'size' : '27 Mb',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true,
|
||||
'preview' : 'assets/images/etc/sample-file-preview.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'Anabelle Manual',
|
||||
'type' : 'document',
|
||||
'owner' : 'Emily Bennett',
|
||||
'size' : '1.1 Kb',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true,
|
||||
'preview' : 'assets/images/etc/sample-file-preview.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'Steam summer sale budget',
|
||||
'type' : 'spreadsheet',
|
||||
'owner' : 'Emily Bennett',
|
||||
'size' : '505 Kb',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true,
|
||||
'preview' : 'assets/images/etc/sample-file-preview.jpg'
|
||||
}
|
||||
];
|
||||
|
||||
}
|
||||
@@ -1,938 +0,0 @@
|
||||
export class IconsFakeDb
|
||||
{
|
||||
public static icons = [
|
||||
'3d_rotation',
|
||||
'ac_unit',
|
||||
'access_alarm',
|
||||
'access_alarms',
|
||||
'access_time',
|
||||
'accessibility',
|
||||
'accessible',
|
||||
'account_balance',
|
||||
'account_balance_wallet',
|
||||
'account_box',
|
||||
'account_circle',
|
||||
'adb',
|
||||
'add',
|
||||
'add_a_photo',
|
||||
'add_alarm',
|
||||
'add_alert',
|
||||
'add_box',
|
||||
'add_circle',
|
||||
'add_circle_outline',
|
||||
'add_location',
|
||||
'add_shopping_cart',
|
||||
'add_to_photos',
|
||||
'add_to_queue',
|
||||
'adjust',
|
||||
'airline_seat_flat',
|
||||
'airline_seat_flat_angled',
|
||||
'airline_seat_individual_suite',
|
||||
'airline_seat_legroom_extra',
|
||||
'airline_seat_legroom_normal',
|
||||
'airline_seat_legroom_reduced',
|
||||
'airline_seat_recline_extra',
|
||||
'airline_seat_recline_normal',
|
||||
'airplanemode_active',
|
||||
'airplanemode_inactive',
|
||||
'airplay',
|
||||
'airport_shuttle',
|
||||
'alarm',
|
||||
'alarm_add',
|
||||
'alarm_off',
|
||||
'alarm_on',
|
||||
'album',
|
||||
'all_inclusive',
|
||||
'all_out',
|
||||
'android',
|
||||
'announcement',
|
||||
'apps',
|
||||
'archive',
|
||||
'arrow_back',
|
||||
'arrow_downward',
|
||||
'arrow_drop_down',
|
||||
'arrow_drop_down_circle',
|
||||
'arrow_drop_up',
|
||||
'arrow_forward',
|
||||
'arrow_upward',
|
||||
'art_track',
|
||||
'aspect_ratio',
|
||||
'assessment',
|
||||
'assignment',
|
||||
'assignment_ind',
|
||||
'assignment_late',
|
||||
'assignment_return',
|
||||
'assignment_returned',
|
||||
'assignment_turned_in',
|
||||
'assistant',
|
||||
'assistant_photo',
|
||||
'attach_file',
|
||||
'attach_money',
|
||||
'attachment',
|
||||
'audiotrack',
|
||||
'autorenew',
|
||||
'av_timer',
|
||||
'backspace',
|
||||
'backup',
|
||||
'battery_alert',
|
||||
'battery_charging_full',
|
||||
'battery_full',
|
||||
'battery_std',
|
||||
'battery_unknown',
|
||||
'beach_access',
|
||||
'beenhere',
|
||||
'block',
|
||||
'bluetooth',
|
||||
'bluetooth_audio',
|
||||
'bluetooth_connected',
|
||||
'bluetooth_disabled',
|
||||
'bluetooth_searching',
|
||||
'blur_circular',
|
||||
'blur_linear',
|
||||
'blur_off',
|
||||
'blur_on',
|
||||
'book',
|
||||
'bookmark',
|
||||
'bookmark_border',
|
||||
'border_all',
|
||||
'border_bottom',
|
||||
'border_clear',
|
||||
'border_color',
|
||||
'border_horizontal',
|
||||
'border_inner',
|
||||
'border_left',
|
||||
'border_outer',
|
||||
'border_right',
|
||||
'border_style',
|
||||
'border_top',
|
||||
'border_vertical',
|
||||
'branding_watermark',
|
||||
'brightness_1',
|
||||
'brightness_2',
|
||||
'brightness_3',
|
||||
'brightness_4',
|
||||
'brightness_5',
|
||||
'brightness_6',
|
||||
'brightness_7',
|
||||
'brightness_auto',
|
||||
'brightness_high',
|
||||
'brightness_low',
|
||||
'brightness_medium',
|
||||
'broken_image',
|
||||
'brush',
|
||||
'bubble_chart',
|
||||
'bug_report',
|
||||
'build',
|
||||
'burst_mode',
|
||||
'business',
|
||||
'business_center',
|
||||
'cached',
|
||||
'cake',
|
||||
'call',
|
||||
'call_end',
|
||||
'call_made',
|
||||
'call_merge',
|
||||
'call_missed',
|
||||
'call_missed_outgoing',
|
||||
'call_received',
|
||||
'call_split',
|
||||
'call_to_action',
|
||||
'camera',
|
||||
'camera_alt',
|
||||
'camera_enhance',
|
||||
'camera_front',
|
||||
'camera_rear',
|
||||
'camera_roll',
|
||||
'cancel',
|
||||
'card_giftcard',
|
||||
'card_membership',
|
||||
'card_travel',
|
||||
'casino',
|
||||
'cast',
|
||||
'cast_connected',
|
||||
'center_focus_strong',
|
||||
'center_focus_weak',
|
||||
'change_history',
|
||||
'chat',
|
||||
'chat_bubble',
|
||||
'chat_bubble_outline',
|
||||
'check',
|
||||
'check_box',
|
||||
'check_box_outline_blank',
|
||||
'check_circle',
|
||||
'chevron_left',
|
||||
'chevron_right',
|
||||
'child_care',
|
||||
'child_friendly',
|
||||
'chrome_reader_mode',
|
||||
'class',
|
||||
'clear',
|
||||
'clear_all',
|
||||
'close',
|
||||
'closed_caption',
|
||||
'cloud',
|
||||
'cloud_circle',
|
||||
'cloud_done',
|
||||
'cloud_download',
|
||||
'cloud_off',
|
||||
'cloud_queue',
|
||||
'cloud_upload',
|
||||
'code',
|
||||
'collections',
|
||||
'collections_bookmark',
|
||||
'color_lens',
|
||||
'colorize',
|
||||
'comment',
|
||||
'compare',
|
||||
'compare_arrows',
|
||||
'computer',
|
||||
'confirmation_number',
|
||||
'contact_mail',
|
||||
'contact_phone',
|
||||
'contacts',
|
||||
'content_copy',
|
||||
'content_cut',
|
||||
'content_paste',
|
||||
'control_point',
|
||||
'control_point_duplicate',
|
||||
'copyright',
|
||||
'create',
|
||||
'create_new_folder',
|
||||
'credit_card',
|
||||
'crop',
|
||||
'crop_16_9',
|
||||
'crop_3_2',
|
||||
'crop_5_4',
|
||||
'crop_7_5',
|
||||
'crop_din',
|
||||
'crop_free',
|
||||
'crop_landscape',
|
||||
'crop_original',
|
||||
'crop_portrait',
|
||||
'crop_rotate',
|
||||
'crop_square',
|
||||
'dashboard',
|
||||
'data_usage',
|
||||
'date_range',
|
||||
'dehaze',
|
||||
'delete',
|
||||
'delete_forever',
|
||||
'delete_sweep',
|
||||
'description',
|
||||
'desktop_mac',
|
||||
'desktop_windows',
|
||||
'details',
|
||||
'developer_board',
|
||||
'developer_mode',
|
||||
'device_hub',
|
||||
'devices',
|
||||
'devices_other',
|
||||
'dialer_sip',
|
||||
'dialpad',
|
||||
'directions',
|
||||
'directions_bike',
|
||||
'directions_boat',
|
||||
'directions_bus',
|
||||
'directions_car',
|
||||
'directions_railway',
|
||||
'directions_run',
|
||||
'directions_subway',
|
||||
'directions_transit',
|
||||
'directions_walk',
|
||||
'disc_full',
|
||||
'dns',
|
||||
'do_not_disturb',
|
||||
'do_not_disturb_alt',
|
||||
'do_not_disturb_off',
|
||||
'do_not_disturb_on',
|
||||
'dock',
|
||||
'domain',
|
||||
'done',
|
||||
'done_all',
|
||||
'donut_large',
|
||||
'donut_small',
|
||||
'drafts',
|
||||
'drag_handle',
|
||||
'drive_eta',
|
||||
'dvr',
|
||||
'edit',
|
||||
'edit_location',
|
||||
'eject',
|
||||
'email',
|
||||
'enhanced_encryption',
|
||||
'equalizer',
|
||||
'error',
|
||||
'error_outline',
|
||||
'euro_symbol',
|
||||
'ev_station',
|
||||
'event',
|
||||
'event_available',
|
||||
'event_busy',
|
||||
'event_note',
|
||||
'event_seat',
|
||||
'exit_to_app',
|
||||
'expand_less',
|
||||
'expand_more',
|
||||
'explicit',
|
||||
'explore',
|
||||
'exposure',
|
||||
'exposure_neg_1',
|
||||
'exposure_neg_2',
|
||||
'exposure_plus_1',
|
||||
'exposure_plus_2',
|
||||
'exposure_zero',
|
||||
'extension',
|
||||
'face',
|
||||
'fast_forward',
|
||||
'fast_rewind',
|
||||
'favorite',
|
||||
'favorite_border',
|
||||
'featured_play_list',
|
||||
'featured_video',
|
||||
'feedback',
|
||||
'fiber_dvr',
|
||||
'fiber_manual_record',
|
||||
'fiber_new',
|
||||
'fiber_pin',
|
||||
'fiber_smart_record',
|
||||
'file_download',
|
||||
'file_upload',
|
||||
'filter',
|
||||
'filter_1',
|
||||
'filter_2',
|
||||
'filter_3',
|
||||
'filter_4',
|
||||
'filter_5',
|
||||
'filter_6',
|
||||
'filter_7',
|
||||
'filter_8',
|
||||
'filter_9',
|
||||
'filter_9_plus',
|
||||
'filter_b_and_w',
|
||||
'filter_center_focus',
|
||||
'filter_drama',
|
||||
'filter_frames',
|
||||
'filter_hdr',
|
||||
'filter_list',
|
||||
'filter_none',
|
||||
'filter_tilt_shift',
|
||||
'filter_vintage',
|
||||
'find_in_page',
|
||||
'find_replace',
|
||||
'fingerprint',
|
||||
'first_page',
|
||||
'fitness_center',
|
||||
'flag',
|
||||
'flare',
|
||||
'flash_auto',
|
||||
'flash_off',
|
||||
'flash_on',
|
||||
'flight',
|
||||
'flight_land',
|
||||
'flight_takeoff',
|
||||
'flip',
|
||||
'flip_to_back',
|
||||
'flip_to_front',
|
||||
'folder',
|
||||
'folder_open',
|
||||
'folder_shared',
|
||||
'folder_special',
|
||||
'font_download',
|
||||
'format_align_center',
|
||||
'format_align_justify',
|
||||
'format_align_left',
|
||||
'format_align_right',
|
||||
'format_bold',
|
||||
'format_clear',
|
||||
'format_color_fill',
|
||||
'format_color_reset',
|
||||
'format_color_text',
|
||||
'format_indent_decrease',
|
||||
'format_indent_increase',
|
||||
'format_italic',
|
||||
'format_line_spacing',
|
||||
'format_list_bulleted',
|
||||
'format_list_numbered',
|
||||
'format_paint',
|
||||
'format_quote',
|
||||
'format_shapes',
|
||||
'format_size',
|
||||
'format_strikethrough',
|
||||
'format_textdirection_l_to_r',
|
||||
'format_textdirection_r_to_l',
|
||||
'format_underlined',
|
||||
'forum',
|
||||
'forward',
|
||||
'forward_10',
|
||||
'forward_30',
|
||||
'forward_5',
|
||||
'free_breakfast',
|
||||
'fullscreen',
|
||||
'fullscreen_exit',
|
||||
'functions',
|
||||
'g_translate',
|
||||
'gamepad',
|
||||
'games',
|
||||
'gavel',
|
||||
'gesture',
|
||||
'get_app',
|
||||
'gif',
|
||||
'golf_course',
|
||||
'gps_fixed',
|
||||
'gps_not_fixed',
|
||||
'gps_off',
|
||||
'grade',
|
||||
'gradient',
|
||||
'grain',
|
||||
'graphic_eq',
|
||||
'grid_off',
|
||||
'grid_on',
|
||||
'group',
|
||||
'group_add',
|
||||
'group_work',
|
||||
'hd',
|
||||
'hdr_off',
|
||||
'hdr_on',
|
||||
'hdr_strong',
|
||||
'hdr_weak',
|
||||
'headset',
|
||||
'headset_mic',
|
||||
'healing',
|
||||
'hearing',
|
||||
'help',
|
||||
'help_outline',
|
||||
'high_quality',
|
||||
'highlight',
|
||||
'highlight_off',
|
||||
'history',
|
||||
'home',
|
||||
'hot_tub',
|
||||
'hotel',
|
||||
'hourglass_empty',
|
||||
'hourglass_full',
|
||||
'http',
|
||||
'https',
|
||||
'image',
|
||||
'image_aspect_ratio',
|
||||
'import_contacts',
|
||||
'import_export',
|
||||
'important_devices',
|
||||
'inbox',
|
||||
'indeterminate_check_box',
|
||||
'info',
|
||||
'info_outline',
|
||||
'input',
|
||||
'insert_chart',
|
||||
'insert_comment',
|
||||
'insert_drive_file',
|
||||
'insert_emoticon',
|
||||
'insert_invitation',
|
||||
'insert_link',
|
||||
'insert_photo',
|
||||
'invert_colors',
|
||||
'invert_colors_off',
|
||||
'iso',
|
||||
'keyboard',
|
||||
'keyboard_arrow_down',
|
||||
'keyboard_arrow_left',
|
||||
'keyboard_arrow_right',
|
||||
'keyboard_arrow_up',
|
||||
'keyboard_backspace',
|
||||
'keyboard_capslock',
|
||||
'keyboard_hide',
|
||||
'keyboard_return',
|
||||
'keyboard_tab',
|
||||
'keyboard_voice',
|
||||
'kitchen',
|
||||
'label',
|
||||
'label_outline',
|
||||
'landscape',
|
||||
'language',
|
||||
'laptop',
|
||||
'laptop_chromebook',
|
||||
'laptop_mac',
|
||||
'laptop_windows',
|
||||
'last_page',
|
||||
'launch',
|
||||
'layers',
|
||||
'layers_clear',
|
||||
'leak_add',
|
||||
'leak_remove',
|
||||
'lens',
|
||||
'library_add',
|
||||
'library_books',
|
||||
'library_music',
|
||||
'lightbulb_outline',
|
||||
'line_style',
|
||||
'line_weight',
|
||||
'linear_scale',
|
||||
'link',
|
||||
'linked_camera',
|
||||
'list',
|
||||
'live_help',
|
||||
'live_tv',
|
||||
'local_activity',
|
||||
'local_airport',
|
||||
'local_atm',
|
||||
'local_bar',
|
||||
'local_cafe',
|
||||
'local_car_wash',
|
||||
'local_convenience_store',
|
||||
'local_dining',
|
||||
'local_drink',
|
||||
'local_florist',
|
||||
'local_gas_station',
|
||||
'local_grocery_store',
|
||||
'local_hospital',
|
||||
'local_hotel',
|
||||
'local_laundry_service',
|
||||
'local_library',
|
||||
'local_mall',
|
||||
'local_movies',
|
||||
'local_offer',
|
||||
'local_parking',
|
||||
'local_pharmacy',
|
||||
'local_phone',
|
||||
'local_pizza',
|
||||
'local_play',
|
||||
'local_post_office',
|
||||
'local_printshop',
|
||||
'local_see',
|
||||
'local_shipping',
|
||||
'local_taxi',
|
||||
'location_city',
|
||||
'location_disabled',
|
||||
'location_off',
|
||||
'location_on',
|
||||
'location_searching',
|
||||
'lock',
|
||||
'lock_open',
|
||||
'lock_outline',
|
||||
'looks',
|
||||
'looks_3',
|
||||
'looks_4',
|
||||
'looks_5',
|
||||
'looks_6',
|
||||
'looks_one',
|
||||
'looks_two',
|
||||
'loop',
|
||||
'loupe',
|
||||
'low_priority',
|
||||
'loyalty',
|
||||
'mail',
|
||||
'mail_outline',
|
||||
'map',
|
||||
'markunread',
|
||||
'markunread_mailbox',
|
||||
'memory',
|
||||
'menu',
|
||||
'merge_type',
|
||||
'message',
|
||||
'mic',
|
||||
'mic_none',
|
||||
'mic_off',
|
||||
'mms',
|
||||
'mode_comment',
|
||||
'mode_edit',
|
||||
'monetization_on',
|
||||
'money_off',
|
||||
'monochrome_photos',
|
||||
'mood',
|
||||
'mood_bad',
|
||||
'more',
|
||||
'more_horiz',
|
||||
'more_vert',
|
||||
'motorcycle',
|
||||
'mouse',
|
||||
'move_to_inbox',
|
||||
'movie',
|
||||
'movie_creation',
|
||||
'movie_filter',
|
||||
'multiline_chart',
|
||||
'music_note',
|
||||
'music_video',
|
||||
'my_location',
|
||||
'nature',
|
||||
'nature_people',
|
||||
'navigate_before',
|
||||
'navigate_next',
|
||||
'navigation',
|
||||
'near_me',
|
||||
'network_cell',
|
||||
'network_check',
|
||||
'network_locked',
|
||||
'network_wifi',
|
||||
'new_releases',
|
||||
'next_week',
|
||||
'nfc',
|
||||
'no_encryption',
|
||||
'no_sim',
|
||||
'not_interested',
|
||||
'note',
|
||||
'note_add',
|
||||
'notifications',
|
||||
'notifications_active',
|
||||
'notifications_none',
|
||||
'notifications_off',
|
||||
'notifications_paused',
|
||||
'offline_pin',
|
||||
'ondemand_video',
|
||||
'opacity',
|
||||
'open_in_browser',
|
||||
'open_in_new',
|
||||
'open_with',
|
||||
'pages',
|
||||
'pageview',
|
||||
'palette',
|
||||
'pan_tool',
|
||||
'panorama',
|
||||
'panorama_fish_eye',
|
||||
'panorama_horizontal',
|
||||
'panorama_vertical',
|
||||
'panorama_wide_angle',
|
||||
'party_mode',
|
||||
'pause',
|
||||
'pause_circle_filled',
|
||||
'pause_circle_outline',
|
||||
'payment',
|
||||
'people',
|
||||
'people_outline',
|
||||
'perm_camera_mic',
|
||||
'perm_contact_calendar',
|
||||
'perm_data_setting',
|
||||
'perm_device_information',
|
||||
'perm_identity',
|
||||
'perm_media',
|
||||
'perm_phone_msg',
|
||||
'perm_scan_wifi',
|
||||
'person',
|
||||
'person_add',
|
||||
'person_outline',
|
||||
'person_pin',
|
||||
'person_pin_circle',
|
||||
'personal_video',
|
||||
'pets',
|
||||
'phone',
|
||||
'phone_android',
|
||||
'phone_bluetooth_speaker',
|
||||
'phone_forwarded',
|
||||
'phone_in_talk',
|
||||
'phone_iphone',
|
||||
'phone_locked',
|
||||
'phone_missed',
|
||||
'phone_paused',
|
||||
'phonelink',
|
||||
'phonelink_erase',
|
||||
'phonelink_lock',
|
||||
'phonelink_off',
|
||||
'phonelink_ring',
|
||||
'phonelink_setup',
|
||||
'photo',
|
||||
'photo_album',
|
||||
'photo_camera',
|
||||
'photo_filter',
|
||||
'photo_library',
|
||||
'photo_size_select_actual',
|
||||
'photo_size_select_large',
|
||||
'photo_size_select_small',
|
||||
'picture_as_pdf',
|
||||
'picture_in_picture',
|
||||
'picture_in_picture_alt',
|
||||
'pie_chart',
|
||||
'pie_chart_outlined',
|
||||
'pin_drop',
|
||||
'place',
|
||||
'play_arrow',
|
||||
'play_circle_filled',
|
||||
'play_circle_outline',
|
||||
'play_for_work',
|
||||
'playlist_add',
|
||||
'playlist_add_check',
|
||||
'playlist_play',
|
||||
'plus_one',
|
||||
'poll',
|
||||
'polymer',
|
||||
'pool',
|
||||
'portable_wifi_off',
|
||||
'portrait',
|
||||
'power',
|
||||
'power_input',
|
||||
'power_settings_new',
|
||||
'pregnant_woman',
|
||||
'present_to_all',
|
||||
'print',
|
||||
'priority_high',
|
||||
'public',
|
||||
'publish',
|
||||
'query_builder',
|
||||
'question_answer',
|
||||
'queue',
|
||||
'queue_music',
|
||||
'queue_play_next',
|
||||
'radio',
|
||||
'radio_button_checked',
|
||||
'radio_button_unchecked',
|
||||
'rate_review',
|
||||
'receipt',
|
||||
'recent_actors',
|
||||
'record_voice_over',
|
||||
'redeem',
|
||||
'redo',
|
||||
'refresh',
|
||||
'remove',
|
||||
'remove_circle',
|
||||
'remove_circle_outline',
|
||||
'remove_from_queue',
|
||||
'remove_red_eye',
|
||||
'remove_shopping_cart',
|
||||
'reorder',
|
||||
'repeat',
|
||||
'repeat_one',
|
||||
'replay',
|
||||
'replay_10',
|
||||
'replay_30',
|
||||
'replay_5',
|
||||
'reply',
|
||||
'reply_all',
|
||||
'report',
|
||||
'report_problem',
|
||||
'restaurant',
|
||||
'restaurant_menu',
|
||||
'restore',
|
||||
'restore_page',
|
||||
'ring_volume',
|
||||
'room',
|
||||
'room_service',
|
||||
'rotate_90_degrees_ccw',
|
||||
'rotate_left',
|
||||
'rotate_right',
|
||||
'rounded_corner',
|
||||
'router',
|
||||
'rowing',
|
||||
'rss_feed',
|
||||
'rv_hookup',
|
||||
'satellite',
|
||||
'save',
|
||||
'scanner',
|
||||
'schedule',
|
||||
'school',
|
||||
'screen_lock_landscape',
|
||||
'screen_lock_portrait',
|
||||
'screen_lock_rotation',
|
||||
'screen_rotation',
|
||||
'screen_share',
|
||||
'sd_card',
|
||||
'sd_storage',
|
||||
'search',
|
||||
'security',
|
||||
'select_all',
|
||||
'send',
|
||||
'sentiment_dissatisfied',
|
||||
'sentiment_neutral',
|
||||
'sentiment_satisfied',
|
||||
'sentiment_very_dissatisfied',
|
||||
'sentiment_very_satisfied',
|
||||
'settings',
|
||||
'settings_applications',
|
||||
'settings_backup_restore',
|
||||
'settings_bluetooth',
|
||||
'settings_brightness',
|
||||
'settings_cell',
|
||||
'settings_ethernet',
|
||||
'settings_input_antenna',
|
||||
'settings_input_component',
|
||||
'settings_input_composite',
|
||||
'settings_input_hdmi',
|
||||
'settings_input_svideo',
|
||||
'settings_overscan',
|
||||
'settings_phone',
|
||||
'settings_power',
|
||||
'settings_remote',
|
||||
'settings_system_daydream',
|
||||
'settings_voice',
|
||||
'share',
|
||||
'shop',
|
||||
'shop_two',
|
||||
'shopping_basket',
|
||||
'shopping_cart',
|
||||
'short_text',
|
||||
'show_chart',
|
||||
'shuffle',
|
||||
'signal_cellular_4_bar',
|
||||
'signal_cellular_connected_no_internet_4_bar',
|
||||
'signal_cellular_no_sim',
|
||||
'signal_cellular_null',
|
||||
'signal_cellular_off',
|
||||
'signal_wifi_4_bar',
|
||||
'signal_wifi_4_bar_lock',
|
||||
'signal_wifi_off',
|
||||
'sim_card',
|
||||
'sim_card_alert',
|
||||
'skip_next',
|
||||
'skip_previous',
|
||||
'slideshow',
|
||||
'slow_motion_video',
|
||||
'smartphone',
|
||||
'smoke_free',
|
||||
'smoking_rooms',
|
||||
'sms',
|
||||
'sms_failed',
|
||||
'snooze',
|
||||
'sort',
|
||||
'sort_by_alpha',
|
||||
'spa',
|
||||
'space_bar',
|
||||
'speaker',
|
||||
'speaker_group',
|
||||
'speaker_notes',
|
||||
'speaker_notes_off',
|
||||
'speaker_phone',
|
||||
'spellcheck',
|
||||
'star',
|
||||
'star_border',
|
||||
'star_half',
|
||||
'stars',
|
||||
'stay_current_landscape',
|
||||
'stay_current_portrait',
|
||||
'stay_primary_landscape',
|
||||
'stay_primary_portrait',
|
||||
'stop',
|
||||
'stop_screen_share',
|
||||
'storage',
|
||||
'store',
|
||||
'store_mall_directory',
|
||||
'straighten',
|
||||
'streetview',
|
||||
'strikethrough_s',
|
||||
'style',
|
||||
'subdirectory_arrow_left',
|
||||
'subdirectory_arrow_right',
|
||||
'subject',
|
||||
'subscriptions',
|
||||
'subtitles',
|
||||
'subway',
|
||||
'supervisor_account',
|
||||
'surround_sound',
|
||||
'swap_calls',
|
||||
'swap_horiz',
|
||||
'swap_vert',
|
||||
'swap_vertical_circle',
|
||||
'switch_camera',
|
||||
'switch_video',
|
||||
'sync',
|
||||
'sync_disabled',
|
||||
'sync_problem',
|
||||
'system_update',
|
||||
'system_update_alt',
|
||||
'tab',
|
||||
'tab_unselected',
|
||||
'tablet',
|
||||
'tablet_android',
|
||||
'tablet_mac',
|
||||
'tag_faces',
|
||||
'tap_and_play',
|
||||
'terrain',
|
||||
'text_fields',
|
||||
'text_format',
|
||||
'textsms',
|
||||
'texture',
|
||||
'theaters',
|
||||
'thumb_down',
|
||||
'thumb_up',
|
||||
'thumbs_up_down',
|
||||
'time_to_leave',
|
||||
'timelapse',
|
||||
'timeline',
|
||||
'timer',
|
||||
'timer_10',
|
||||
'timer_3',
|
||||
'timer_off',
|
||||
'title',
|
||||
'toc',
|
||||
'today',
|
||||
'toll',
|
||||
'tonality',
|
||||
'touch_app',
|
||||
'toys',
|
||||
'track_changes',
|
||||
'traffic',
|
||||
'train',
|
||||
'tram',
|
||||
'transfer_within_a_station',
|
||||
'transform',
|
||||
'translate',
|
||||
'trending_down',
|
||||
'trending_flat',
|
||||
'trending_up',
|
||||
'tune',
|
||||
'turned_in',
|
||||
'turned_in_not',
|
||||
'tv',
|
||||
'unarchive',
|
||||
'undo',
|
||||
'unfold_less',
|
||||
'unfold_more',
|
||||
'update',
|
||||
'usb',
|
||||
'verified_user',
|
||||
'vertical_align_bottom',
|
||||
'vertical_align_center',
|
||||
'vertical_align_top',
|
||||
'vibration',
|
||||
'video_call',
|
||||
'video_label',
|
||||
'video_library',
|
||||
'videocam',
|
||||
'videocam_off',
|
||||
'videogame_asset',
|
||||
'view_agenda',
|
||||
'view_array',
|
||||
'view_carousel',
|
||||
'view_column',
|
||||
'view_comfy',
|
||||
'view_compact',
|
||||
'view_day',
|
||||
'view_headline',
|
||||
'view_list',
|
||||
'view_module',
|
||||
'view_quilt',
|
||||
'view_stream',
|
||||
'view_week',
|
||||
'vignette',
|
||||
'visibility',
|
||||
'visibility_off',
|
||||
'voice_chat',
|
||||
'voicemail',
|
||||
'volume_down',
|
||||
'volume_mute',
|
||||
'volume_off',
|
||||
'volume_up',
|
||||
'vpn_key',
|
||||
'vpn_lock',
|
||||
'wallpaper',
|
||||
'warning',
|
||||
'watch',
|
||||
'watch_later',
|
||||
'wb_auto',
|
||||
'wb_cloudy',
|
||||
'wb_incandescent',
|
||||
'wb_iridescent',
|
||||
'wb_sunny',
|
||||
'wc',
|
||||
'web',
|
||||
'web_asset',
|
||||
'weekend',
|
||||
'whatshot',
|
||||
'widgets',
|
||||
'wifi',
|
||||
'wifi_lock',
|
||||
'wifi_tethering',
|
||||
'work',
|
||||
'wrap_text',
|
||||
'youtube_searched_for',
|
||||
'zoom_in',
|
||||
'zoom_out',
|
||||
'zoom_out_map'
|
||||
];
|
||||
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
export class InvoiceFakeDb
|
||||
{
|
||||
public static invoice = {
|
||||
'from' : {
|
||||
'title' : 'Fuse Inc.',
|
||||
'address': '2810 Country Club Road Cranford, NJ 07016',
|
||||
'phone' : '+66 123 455 87',
|
||||
'email' : 'hello@fuseinc.com',
|
||||
'website': 'www.fuseinc.com'
|
||||
},
|
||||
'client' : {
|
||||
'title' : 'John Doe',
|
||||
'address': '9301 Wood Street Philadelphia, PA 19111',
|
||||
'phone' : '+55 552 455 87',
|
||||
'email' : 'johndoe@mail.com'
|
||||
},
|
||||
'number' : 'P9-0004',
|
||||
'date' : 'Jul 19, 2015',
|
||||
'dueDate' : 'Aug 24, 2015',
|
||||
'services': [
|
||||
{
|
||||
'title' : 'Prototype & Design',
|
||||
'detail' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus accumsan, quam sed eleifend imperdiet.',
|
||||
'unit' : 'Hour',
|
||||
'unitPrice': '12.00',
|
||||
'quantity' : '240',
|
||||
'total' : '2880'
|
||||
},
|
||||
{
|
||||
'title' : 'Coding',
|
||||
'detail' : 'Vestibulum ligula sem, rutrum et libero id, porta vehicula metus. Cras dapibus neque sit amet laoreet vestibulum.',
|
||||
'unit' : 'Hour',
|
||||
'unitPrice': '10.50',
|
||||
'quantity' : '350',
|
||||
'total' : '3675'
|
||||
},
|
||||
{
|
||||
'title' : 'Testing',
|
||||
'detail' : 'Pellentesque luctus efficitur neque in finibus. Integer ut nunc in augue maximus porttitor id id nulla. In vitae erat.',
|
||||
'unit' : 'Hour',
|
||||
'unitPrice': '4.00',
|
||||
'quantity' : '50',
|
||||
'total' : '200'
|
||||
},
|
||||
{
|
||||
'title' : 'Documentation & Training',
|
||||
'detail' : 'Pellentesque luctus efficitur neque in finibus. Integer ut nunc in augue maximus porttitor id id nulla. In vitae erat.',
|
||||
'unit' : 'Hour',
|
||||
'unitPrice': '6.50',
|
||||
'quantity' : '260',
|
||||
'total' : '1690'
|
||||
}
|
||||
],
|
||||
'subtotal': '8445',
|
||||
'tax' : '675.60',
|
||||
'discount': '120.60',
|
||||
'total' : '9000'
|
||||
};
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
export class KnowledgeBaseFakeDb
|
||||
{
|
||||
public static data = [
|
||||
{
|
||||
'title' : 'Your Account',
|
||||
'path' : '/pages/knowledge-base',
|
||||
'articlesCount' : 17,
|
||||
'featuredArticles': [
|
||||
{
|
||||
'title' : 'Account limits',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
},
|
||||
{
|
||||
'title' : 'How do I change my username?',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
},
|
||||
{
|
||||
'title' : 'How do I change my password?',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
},
|
||||
{
|
||||
'title' : 'How do I change my email address?',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
},
|
||||
{
|
||||
'title' : 'How do I close my account?',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'title' : 'Selling',
|
||||
'path' : '/pages/knowledge-base',
|
||||
'articlesCount' : 12,
|
||||
'featuredArticles': [
|
||||
{
|
||||
'title' : 'A guide to the upload process',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
},
|
||||
{
|
||||
'title' : 'Author collaboration',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
},
|
||||
{
|
||||
'title' : 'Exclusivity policy',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
},
|
||||
{
|
||||
'title' : 'Promises you make as an author',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
},
|
||||
{
|
||||
'title' : 'An author’s introduction',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'title' : 'Buying',
|
||||
'path' : '/pages/knowledge-base',
|
||||
'articlesCount' : 19,
|
||||
'featuredArticles': [
|
||||
{
|
||||
'title' : 'Where is my purchase code?',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
},
|
||||
{
|
||||
'title' : 'Can I get a refund?',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
},
|
||||
{
|
||||
'title' : 'Contact us',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
},
|
||||
{
|
||||
'title' : 'How do I purchase an item?',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
},
|
||||
{
|
||||
'title' : 'I\'m trying to find a specific item',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'title' : 'Item Support',
|
||||
'path' : '/pages/knowledge-base',
|
||||
'articlesCount' : 24,
|
||||
'featuredArticles': [
|
||||
{
|
||||
'title' : 'What is Item Support?',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
},
|
||||
{
|
||||
'title' : 'How to contact an author',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
},
|
||||
{
|
||||
'title' : 'Rating or review removal policy',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
},
|
||||
{
|
||||
'title' : 'Purchasing unsupported items',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
},
|
||||
{
|
||||
'title' : 'Item installation guide',
|
||||
'content': '<p><b>The standard Lorem Ipsum passage, used since the 1500s</b></p>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur\n sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n</p>\n<p><b>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</b></p>\n<p>Sed ut perspiciatis unde omnis iste natus error sit\n voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et\n quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit\n aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt\n ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam\n corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui\n in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n</p>\n<p><b>1914 translation by H. Rackham</b></p>\n<p>\n But I must explain to you how all this mistaken idea of denouncing pleasure\n and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of\n the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure\n itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter\n consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of\n itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some\n great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain\n some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no\n annoying consequences, or one who avoids a pain that produces no resultant pleasure?\n</p>\n'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -1,483 +0,0 @@
|
||||
export class MailFakeDb
|
||||
{
|
||||
public static mails = [
|
||||
{
|
||||
'id' : '15459251a6d6b397565',
|
||||
'from' : {
|
||||
'name' : 'Alice Freeman',
|
||||
'avatar': 'assets/images/avatars/alice.jpg',
|
||||
'email' : 'alicefreeman@creapond.com'
|
||||
},
|
||||
'to' : [
|
||||
{
|
||||
'name' : 'me',
|
||||
'email': 'johndoe@creapond.com'
|
||||
}
|
||||
],
|
||||
'subject' : 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'message' : '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce lorem diam, pulvinar id nisl non, ultrices maximus nibh. Suspendisse ut justo velit. Nullam ac ultrices risus, quis auctor orci. Vestibulum volutpat nisi et neque porta ullamcorper. Maecenas porttitor porta erat ac suscipit. Sed cursus leo ut elementum fringilla. Maecenas semper viverra erat, vel ullamcorper dui efficitur in. Vestibulum placerat imperdiet tellus, et tincidunt eros posuere eget. Proin sit amet facilisis libero. Nulla eget est ut erat aliquet rhoncus. Quisque ac urna vitae dui hendrerit sollicitudin vel id sem. </p><p> In eget ante sapien. Quisque consequat velit non ante finibus, vel placerat erat ultricies. Aliquam bibendum justo erat, ultrices vehicula dolor elementum a. Mauris eu nisl feugiat ligula molestie eleifend. Aliquam efficitur venenatis velit ac porta. Vivamus vitae pulvinar tellus. Donec odio enim, auctor eget nibh mattis, ultricies dignissim lacus. Phasellus non tincidunt dui. Nulla eu arcu lorem. </p><p> Donec non hendrerit augue, lobortis sollicitudin odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis sit amet euismod enim, eget vestibulum justo. Fusce a placerat lectus, eget feugiat purus. Cras risus ante, faucibus eget justo commodo, volutpat tempor ante. Donec sit amet leo venenatis, gravida quam sit amet, blandit dui. In quam ante, elementum ut faucibus nec, tristique vitae dui. Praesent vel erat at enim placerat luctus vel ut ipsum. In congue tempor mi, non ornare lectus condimentum at. Aenean libero diam, finibus eget sapien et, tristique fermentum lorem. </p>',
|
||||
'time' : '28 Jun',
|
||||
'read' : false,
|
||||
'starred' : false,
|
||||
'important' : true,
|
||||
'hasAttachments': true,
|
||||
'attachments' : [
|
||||
{
|
||||
'type' : 'image',
|
||||
'fileName': 'flowers',
|
||||
'preview' : 'assets/images/etc/flowers-thumb.jpg',
|
||||
'url' : '',
|
||||
'size' : '1.1Mb'
|
||||
},
|
||||
{
|
||||
'type' : 'image',
|
||||
'fileName': 'snow',
|
||||
'preview' : 'assets/images/etc/snow-thumb.jpg',
|
||||
'url' : '',
|
||||
'size' : '380kb'
|
||||
},
|
||||
{
|
||||
'type' : 'image',
|
||||
'fileName': 'sunrise',
|
||||
'preview' : 'assets/images/etc/sunrise-thumb.jpg',
|
||||
'url' : 'assets/images/etc/early-sunrise.jpg',
|
||||
'size' : '17Mb'
|
||||
}
|
||||
],
|
||||
'labels' : [
|
||||
1
|
||||
],
|
||||
'folder' : 0
|
||||
},
|
||||
{
|
||||
'id' : '154588a0864d2881124',
|
||||
'from' : {
|
||||
'name' : 'Lawrence Collins',
|
||||
'avatar': 'assets/images/avatars/vincent.jpg',
|
||||
'email' : 'lawrencecollins@creapond.com'
|
||||
},
|
||||
'to' : [
|
||||
{
|
||||
'name' : 'me',
|
||||
'email': 'johndoe@creapond.com'
|
||||
}
|
||||
],
|
||||
'subject' : 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'message' : '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce lorem diam, pulvinar id nisl non, ultrices maximus nibh. Suspendisse ut justo velit. Nullam ac ultrices risus, quis auctor orci. Vestibulum volutpat nisi et neque porta ullamcorper. Maecenas porttitor porta erat ac suscipit. Sed cursus leo ut elementum fringilla. Maecenas semper viverra erat, vel ullamcorper dui efficitur in. Vestibulum placerat imperdiet tellus, et tincidunt eros posuere eget. Proin sit amet facilisis libero. Nulla eget est ut erat aliquet rhoncus. Quisque ac urna vitae dui hendrerit sollicitudin vel id sem. </p><p> In eget ante sapien. Quisque consequat velit non ante finibus, vel placerat erat ultricies. Aliquam bibendum justo erat, ultrices vehicula dolor elementum a. Mauris eu nisl feugiat ligula molestie eleifend. Aliquam efficitur venenatis velit ac porta. Vivamus vitae pulvinar tellus. Donec odio enim, auctor eget nibh mattis, ultricies dignissim lacus. Phasellus non tincidunt dui. Nulla eu arcu lorem. </p><p> Donec non hendrerit augue, lobortis sollicitudin odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis sit amet euismod enim, eget vestibulum justo. Fusce a placerat lectus, eget feugiat purus. Cras risus ante, faucibus eget justo commodo, volutpat tempor ante. Donec sit amet leo venenatis, gravida quam sit amet, blandit dui. In quam ante, elementum ut faucibus nec, tristique vitae dui. Praesent vel erat at enim placerat luctus vel ut ipsum. In congue tempor mi, non ornare lectus condimentum at. Aenean libero diam, finibus eget sapien et, tristique fermentum lorem. </p>',
|
||||
'time' : '28 Jun',
|
||||
'read' : false,
|
||||
'starred' : false,
|
||||
'important' : false,
|
||||
'hasAttachments': false,
|
||||
'labels' : [],
|
||||
'folder' : 0
|
||||
},
|
||||
{
|
||||
'id' : '15453ba60d3baa5daaf',
|
||||
'from' : {
|
||||
'name' : 'Judith Burton',
|
||||
'avatar': 'assets/images/avatars/joyce.jpg',
|
||||
'email' : 'judithburton@creapond.com'
|
||||
},
|
||||
'to' : [
|
||||
{
|
||||
'name' : 'me',
|
||||
'email': 'johndoe@creapond.com'
|
||||
}
|
||||
],
|
||||
'subject' : 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'message' : '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce lorem diam, pulvinar id nisl non, ultrices maximus nibh. Suspendisse ut justo velit. Nullam ac ultrices risus, quis auctor orci. Vestibulum volutpat nisi et neque porta ullamcorper. Maecenas porttitor porta erat ac suscipit. Sed cursus leo ut elementum fringilla. Maecenas semper viverra erat, vel ullamcorper dui efficitur in. Vestibulum placerat imperdiet tellus, et tincidunt eros posuere eget. Proin sit amet facilisis libero. Nulla eget est ut erat aliquet rhoncus. Quisque ac urna vitae dui hendrerit sollicitudin vel id sem. </p><p> In eget ante sapien. Quisque consequat velit non ante finibus, vel placerat erat ultricies. Aliquam bibendum justo erat, ultrices vehicula dolor elementum a. Mauris eu nisl feugiat ligula molestie eleifend. Aliquam efficitur venenatis velit ac porta. Vivamus vitae pulvinar tellus. Donec odio enim, auctor eget nibh mattis, ultricies dignissim lacus. Phasellus non tincidunt dui. Nulla eu arcu lorem. </p><p> Donec non hendrerit augue, lobortis sollicitudin odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis sit amet euismod enim, eget vestibulum justo. Fusce a placerat lectus, eget feugiat purus. Cras risus ante, faucibus eget justo commodo, volutpat tempor ante. Donec sit amet leo venenatis, gravida quam sit amet, blandit dui. In quam ante, elementum ut faucibus nec, tristique vitae dui. Praesent vel erat at enim placerat luctus vel ut ipsum. In congue tempor mi, non ornare lectus condimentum at. Aenean libero diam, finibus eget sapien et, tristique fermentum lorem. </p>',
|
||||
'time' : '28 Jun',
|
||||
'read' : true,
|
||||
'starred' : false,
|
||||
'important' : false,
|
||||
'hasAttachments': false,
|
||||
'labels' : [
|
||||
3,
|
||||
2
|
||||
],
|
||||
'folder' : 0
|
||||
},
|
||||
{
|
||||
'id' : '15453a06c08fb021776',
|
||||
'from' : {
|
||||
'name' : 'Danielle Obrien',
|
||||
'avatar': 'assets/images/avatars/danielle.jpg',
|
||||
'email' : 'danielleobrien@creapond.com'
|
||||
},
|
||||
'to' : [
|
||||
{
|
||||
'name' : 'me',
|
||||
'email': 'johndoe@creapond.com'
|
||||
}
|
||||
],
|
||||
'subject' : 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'message' : '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce lorem diam, pulvinar id nisl non, ultrices maximus nibh. Suspendisse ut justo velit. Nullam ac ultrices risus, quis auctor orci. Vestibulum volutpat nisi et neque porta ullamcorper. Maecenas porttitor porta erat ac suscipit. Sed cursus leo ut elementum fringilla. Maecenas semper viverra erat, vel ullamcorper dui efficitur in. Vestibulum placerat imperdiet tellus, et tincidunt eros posuere eget. Proin sit amet facilisis libero. Nulla eget est ut erat aliquet rhoncus. Quisque ac urna vitae dui hendrerit sollicitudin vel id sem. </p><p> In eget ante sapien. Quisque consequat velit non ante finibus, vel placerat erat ultricies. Aliquam bibendum justo erat, ultrices vehicula dolor elementum a. Mauris eu nisl feugiat ligula molestie eleifend. Aliquam efficitur venenatis velit ac porta. Vivamus vitae pulvinar tellus. Donec odio enim, auctor eget nibh mattis, ultricies dignissim lacus. Phasellus non tincidunt dui. Nulla eu arcu lorem. </p><p> Donec non hendrerit augue, lobortis sollicitudin odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis sit amet euismod enim, eget vestibulum justo. Fusce a placerat lectus, eget feugiat purus. Cras risus ante, faucibus eget justo commodo, volutpat tempor ante. Donec sit amet leo venenatis, gravida quam sit amet, blandit dui. In quam ante, elementum ut faucibus nec, tristique vitae dui. Praesent vel erat at enim placerat luctus vel ut ipsum. In congue tempor mi, non ornare lectus condimentum at. Aenean libero diam, finibus eget sapien et, tristique fermentum lorem. </p>',
|
||||
'time' : '28 Jun',
|
||||
'read' : true,
|
||||
'starred' : true,
|
||||
'important' : false,
|
||||
'hasAttachments': false,
|
||||
'labels' : [
|
||||
1,
|
||||
3
|
||||
],
|
||||
'folder' : 0
|
||||
},
|
||||
{
|
||||
'id' : '154537435d5b32bf11a',
|
||||
'from' : {
|
||||
'name' : 'Brian Flores',
|
||||
'avatar': '',
|
||||
'email' : 'brianflores@creapond.com'
|
||||
},
|
||||
'to' : [
|
||||
{
|
||||
'name' : 'me',
|
||||
'email': 'johndoe@creapond.com'
|
||||
}
|
||||
],
|
||||
'subject' : 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'message' : '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce lorem diam, pulvinar id nisl non, ultrices maximus nibh. Suspendisse ut justo velit. Nullam ac ultrices risus, quis auctor orci. Vestibulum volutpat nisi et neque porta ullamcorper. Maecenas porttitor porta erat ac suscipit. Sed cursus leo ut elementum fringilla. Maecenas semper viverra erat, vel ullamcorper dui efficitur in. Vestibulum placerat imperdiet tellus, et tincidunt eros posuere eget. Proin sit amet facilisis libero. Nulla eget est ut erat aliquet rhoncus. Quisque ac urna vitae dui hendrerit sollicitudin vel id sem. </p><p> In eget ante sapien. Quisque consequat velit non ante finibus, vel placerat erat ultricies. Aliquam bibendum justo erat, ultrices vehicula dolor elementum a. Mauris eu nisl feugiat ligula molestie eleifend. Aliquam efficitur venenatis velit ac porta. Vivamus vitae pulvinar tellus. Donec odio enim, auctor eget nibh mattis, ultricies dignissim lacus. Phasellus non tincidunt dui. Nulla eu arcu lorem. </p><p> Donec non hendrerit augue, lobortis sollicitudin odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis sit amet euismod enim, eget vestibulum justo. Fusce a placerat lectus, eget feugiat purus. Cras risus ante, faucibus eget justo commodo, volutpat tempor ante. Donec sit amet leo venenatis, gravida quam sit amet, blandit dui. In quam ante, elementum ut faucibus nec, tristique vitae dui. Praesent vel erat at enim placerat luctus vel ut ipsum. In congue tempor mi, non ornare lectus condimentum at. Aenean libero diam, finibus eget sapien et, tristique fermentum lorem. </p>',
|
||||
'time' : '26 Jun',
|
||||
'read' : true,
|
||||
'starred' : false,
|
||||
'important' : false,
|
||||
'hasAttachments': false,
|
||||
'labels' : [],
|
||||
'folder' : 0
|
||||
},
|
||||
{
|
||||
'id' : '1544e43dcdae6ebf876',
|
||||
'from' : {
|
||||
'name' : 'Charles Kim',
|
||||
'avatar': 'assets/images/avatars/garry.jpg',
|
||||
'email' : 'charleskim@creapond.com'
|
||||
},
|
||||
'to' : [
|
||||
{
|
||||
'name' : 'me',
|
||||
'email': 'johndoe@creapond.com'
|
||||
}
|
||||
],
|
||||
'subject' : 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'message' : '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce lorem diam, pulvinar id nisl non, ultrices maximus nibh. Suspendisse ut justo velit. Nullam ac ultrices risus, quis auctor orci. Vestibulum volutpat nisi et neque porta ullamcorper. Maecenas porttitor porta erat ac suscipit. Sed cursus leo ut elementum fringilla. Maecenas semper viverra erat, vel ullamcorper dui efficitur in. Vestibulum placerat imperdiet tellus, et tincidunt eros posuere eget. Proin sit amet facilisis libero. Nulla eget est ut erat aliquet rhoncus. Quisque ac urna vitae dui hendrerit sollicitudin vel id sem. </p><p> In eget ante sapien. Quisque consequat velit non ante finibus, vel placerat erat ultricies. Aliquam bibendum justo erat, ultrices vehicula dolor elementum a. Mauris eu nisl feugiat ligula molestie eleifend. Aliquam efficitur venenatis velit ac porta. Vivamus vitae pulvinar tellus. Donec odio enim, auctor eget nibh mattis, ultricies dignissim lacus. Phasellus non tincidunt dui. Nulla eu arcu lorem. </p><p> Donec non hendrerit augue, lobortis sollicitudin odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis sit amet euismod enim, eget vestibulum justo. Fusce a placerat lectus, eget feugiat purus. Cras risus ante, faucibus eget justo commodo, volutpat tempor ante. Donec sit amet leo venenatis, gravida quam sit amet, blandit dui. In quam ante, elementum ut faucibus nec, tristique vitae dui. Praesent vel erat at enim placerat luctus vel ut ipsum. In congue tempor mi, non ornare lectus condimentum at. Aenean libero diam, finibus eget sapien et, tristique fermentum lorem. </p>',
|
||||
'time' : '18 Jun',
|
||||
'read' : true,
|
||||
'starred' : false,
|
||||
'important' : true,
|
||||
'hasAttachments': false,
|
||||
'labels' : [
|
||||
2
|
||||
],
|
||||
'folder' : 0
|
||||
},
|
||||
{
|
||||
'id' : '1543ee3a5b43e0f9f45',
|
||||
'from' : {
|
||||
'name' : 'Patricia White',
|
||||
'avatar': '',
|
||||
'email' : 'patriciawhite@creapond.com'
|
||||
},
|
||||
'to' : [
|
||||
{
|
||||
'name' : 'me',
|
||||
'email': 'johndoe@creapond.com'
|
||||
}
|
||||
],
|
||||
'subject' : 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'message' : '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce lorem diam, pulvinar id nisl non, ultrices maximus nibh. Suspendisse ut justo velit. Nullam ac ultrices risus, quis auctor orci. Vestibulum volutpat nisi et neque porta ullamcorper. Maecenas porttitor porta erat ac suscipit. Sed cursus leo ut elementum fringilla. Maecenas semper viverra erat, vel ullamcorper dui efficitur in. Vestibulum placerat imperdiet tellus, et tincidunt eros posuere eget. Proin sit amet facilisis libero. Nulla eget est ut erat aliquet rhoncus. Quisque ac urna vitae dui hendrerit sollicitudin vel id sem. </p><p> In eget ante sapien. Quisque consequat velit non ante finibus, vel placerat erat ultricies. Aliquam bibendum justo erat, ultrices vehicula dolor elementum a. Mauris eu nisl feugiat ligula molestie eleifend. Aliquam efficitur venenatis velit ac porta. Vivamus vitae pulvinar tellus. Donec odio enim, auctor eget nibh mattis, ultricies dignissim lacus. Phasellus non tincidunt dui. Nulla eu arcu lorem. </p><p> Donec non hendrerit augue, lobortis sollicitudin odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis sit amet euismod enim, eget vestibulum justo. Fusce a placerat lectus, eget feugiat purus. Cras risus ante, faucibus eget justo commodo, volutpat tempor ante. Donec sit amet leo venenatis, gravida quam sit amet, blandit dui. In quam ante, elementum ut faucibus nec, tristique vitae dui. Praesent vel erat at enim placerat luctus vel ut ipsum. In congue tempor mi, non ornare lectus condimentum at. Aenean libero diam, finibus eget sapien et, tristique fermentum lorem. </p>',
|
||||
'time' : '15 Jun',
|
||||
'read' : true,
|
||||
'starred' : false,
|
||||
'important' : false,
|
||||
'hasAttachments': false,
|
||||
'labels' : [],
|
||||
'folder' : 0
|
||||
},
|
||||
{
|
||||
'id' : '1543cc4515df3146112',
|
||||
'from' : {
|
||||
'name' : 'Juan Carpenter',
|
||||
'avatar': 'assets/images/avatars/james.jpg',
|
||||
'email' : 'juancarpenter@creapond.com'
|
||||
},
|
||||
'to' : [
|
||||
{
|
||||
'name' : 'me',
|
||||
'email': 'johndoe@creapond.com'
|
||||
}
|
||||
],
|
||||
'subject' : 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'message' : '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce lorem diam, pulvinar id nisl non, ultrices maximus nibh. Suspendisse ut justo velit. Nullam ac ultrices risus, quis auctor orci. Vestibulum volutpat nisi et neque porta ullamcorper. Maecenas porttitor porta erat ac suscipit. Sed cursus leo ut elementum fringilla. Maecenas semper viverra erat, vel ullamcorper dui efficitur in. Vestibulum placerat imperdiet tellus, et tincidunt eros posuere eget. Proin sit amet facilisis libero. Nulla eget est ut erat aliquet rhoncus. Quisque ac urna vitae dui hendrerit sollicitudin vel id sem. </p><p> In eget ante sapien. Quisque consequat velit non ante finibus, vel placerat erat ultricies. Aliquam bibendum justo erat, ultrices vehicula dolor elementum a. Mauris eu nisl feugiat ligula molestie eleifend. Aliquam efficitur venenatis velit ac porta. Vivamus vitae pulvinar tellus. Donec odio enim, auctor eget nibh mattis, ultricies dignissim lacus. Phasellus non tincidunt dui. Nulla eu arcu lorem. </p><p> Donec non hendrerit augue, lobortis sollicitudin odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis sit amet euismod enim, eget vestibulum justo. Fusce a placerat lectus, eget feugiat purus. Cras risus ante, faucibus eget justo commodo, volutpat tempor ante. Donec sit amet leo venenatis, gravida quam sit amet, blandit dui. In quam ante, elementum ut faucibus nec, tristique vitae dui. Praesent vel erat at enim placerat luctus vel ut ipsum. In congue tempor mi, non ornare lectus condimentum at. Aenean libero diam, finibus eget sapien et, tristique fermentum lorem. </p>',
|
||||
'time' : '11 Jun',
|
||||
'read' : true,
|
||||
'starred' : false,
|
||||
'important' : false,
|
||||
'hasAttachments': false,
|
||||
'labels' : [],
|
||||
'folder' : 0
|
||||
},
|
||||
{
|
||||
'id' : '154398a4770d7aaf9a2',
|
||||
'from' : {
|
||||
'name' : 'Maria Gilbert',
|
||||
'avatar': 'assets/images/avatars/danielle.jpg',
|
||||
'email' : 'mariagilbert@creapond.com'
|
||||
},
|
||||
'to' : [
|
||||
{
|
||||
'name' : 'me',
|
||||
'email': 'johndoe@creapond.com'
|
||||
}
|
||||
],
|
||||
'subject' : 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'message' : '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce lorem diam, pulvinar id nisl non, ultrices maximus nibh. Suspendisse ut justo velit. Nullam ac ultrices risus, quis auctor orci. Vestibulum volutpat nisi et neque porta ullamcorper. Maecenas porttitor porta erat ac suscipit. Sed cursus leo ut elementum fringilla. Maecenas semper viverra erat, vel ullamcorper dui efficitur in. Vestibulum placerat imperdiet tellus, et tincidunt eros posuere eget. Proin sit amet facilisis libero. Nulla eget est ut erat aliquet rhoncus. Quisque ac urna vitae dui hendrerit sollicitudin vel id sem. </p><p> In eget ante sapien. Quisque consequat velit non ante finibus, vel placerat erat ultricies. Aliquam bibendum justo erat, ultrices vehicula dolor elementum a. Mauris eu nisl feugiat ligula molestie eleifend. Aliquam efficitur venenatis velit ac porta. Vivamus vitae pulvinar tellus. Donec odio enim, auctor eget nibh mattis, ultricies dignissim lacus. Phasellus non tincidunt dui. Nulla eu arcu lorem. </p><p> Donec non hendrerit augue, lobortis sollicitudin odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis sit amet euismod enim, eget vestibulum justo. Fusce a placerat lectus, eget feugiat purus. Cras risus ante, faucibus eget justo commodo, volutpat tempor ante. Donec sit amet leo venenatis, gravida quam sit amet, blandit dui. In quam ante, elementum ut faucibus nec, tristique vitae dui. Praesent vel erat at enim placerat luctus vel ut ipsum. In congue tempor mi, non ornare lectus condimentum at. Aenean libero diam, finibus eget sapien et, tristique fermentum lorem. </p>',
|
||||
'time' : '5 Jun',
|
||||
'read' : true,
|
||||
'starred' : false,
|
||||
'important' : false,
|
||||
'hasAttachments': false,
|
||||
'labels' : [],
|
||||
'folder' : 0
|
||||
},
|
||||
{
|
||||
'id' : '15438351f87dcd68567',
|
||||
'from' : {
|
||||
'name' : 'Tammy Brooks',
|
||||
'avatar': '',
|
||||
'email' : 'tammybrooks@creapond.com'
|
||||
},
|
||||
'to' : [
|
||||
{
|
||||
'name' : 'me',
|
||||
'email': 'johndoe@creapond.com'
|
||||
}
|
||||
],
|
||||
'subject' : 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'message' : '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce lorem diam, pulvinar id nisl non, ultrices maximus nibh. Suspendisse ut justo velit. Nullam ac ultrices risus, quis auctor orci. Vestibulum volutpat nisi et neque porta ullamcorper. Maecenas porttitor porta erat ac suscipit. Sed cursus leo ut elementum fringilla. Maecenas semper viverra erat, vel ullamcorper dui efficitur in. Vestibulum placerat imperdiet tellus, et tincidunt eros posuere eget. Proin sit amet facilisis libero. Nulla eget est ut erat aliquet rhoncus. Quisque ac urna vitae dui hendrerit sollicitudin vel id sem. </p><p> In eget ante sapien. Quisque consequat velit non ante finibus, vel placerat erat ultricies. Aliquam bibendum justo erat, ultrices vehicula dolor elementum a. Mauris eu nisl feugiat ligula molestie eleifend. Aliquam efficitur venenatis velit ac porta. Vivamus vitae pulvinar tellus. Donec odio enim, auctor eget nibh mattis, ultricies dignissim lacus. Phasellus non tincidunt dui. Nulla eu arcu lorem. </p><p> Donec non hendrerit augue, lobortis sollicitudin odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis sit amet euismod enim, eget vestibulum justo. Fusce a placerat lectus, eget feugiat purus. Cras risus ante, faucibus eget justo commodo, volutpat tempor ante. Donec sit amet leo venenatis, gravida quam sit amet, blandit dui. In quam ante, elementum ut faucibus nec, tristique vitae dui. Praesent vel erat at enim placerat luctus vel ut ipsum. In congue tempor mi, non ornare lectus condimentum at. Aenean libero diam, finibus eget sapien et, tristique fermentum lorem. </p>',
|
||||
'time' : '1 Jun',
|
||||
'read' : true,
|
||||
'starred' : false,
|
||||
'important' : false,
|
||||
'hasAttachments': false,
|
||||
'labels' : [],
|
||||
'folder' : 0
|
||||
},
|
||||
{
|
||||
'id' : '1542d75d929a603125',
|
||||
'from' : {
|
||||
'name' : 'Kathy Price',
|
||||
'avatar': '',
|
||||
'email' : 'kathyprice@creapond.com'
|
||||
},
|
||||
'to' : [
|
||||
{
|
||||
'name' : 'me',
|
||||
'email': 'johndoe@creapond.com'
|
||||
}
|
||||
],
|
||||
'subject' : 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'message' : '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce lorem diam, pulvinar id nisl non, ultrices maximus nibh. Suspendisse ut justo velit. Nullam ac ultrices risus, quis auctor orci. Vestibulum volutpat nisi et neque porta ullamcorper. Maecenas porttitor porta erat ac suscipit. Sed cursus leo ut elementum fringilla. Maecenas semper viverra erat, vel ullamcorper dui efficitur in. Vestibulum placerat imperdiet tellus, et tincidunt eros posuere eget. Proin sit amet facilisis libero. Nulla eget est ut erat aliquet rhoncus. Quisque ac urna vitae dui hendrerit sollicitudin vel id sem. </p><p> In eget ante sapien. Quisque consequat velit non ante finibus, vel placerat erat ultricies. Aliquam bibendum justo erat, ultrices vehicula dolor elementum a. Mauris eu nisl feugiat ligula molestie eleifend. Aliquam efficitur venenatis velit ac porta. Vivamus vitae pulvinar tellus. Donec odio enim, auctor eget nibh mattis, ultricies dignissim lacus. Phasellus non tincidunt dui. Nulla eu arcu lorem. </p><p> Donec non hendrerit augue, lobortis sollicitudin odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis sit amet euismod enim, eget vestibulum justo. Fusce a placerat lectus, eget feugiat purus. Cras risus ante, faucibus eget justo commodo, volutpat tempor ante. Donec sit amet leo venenatis, gravida quam sit amet, blandit dui. In quam ante, elementum ut faucibus nec, tristique vitae dui. Praesent vel erat at enim placerat luctus vel ut ipsum. In congue tempor mi, non ornare lectus condimentum at. Aenean libero diam, finibus eget sapien et, tristique fermentum lorem. </p> ',
|
||||
'time' : '1 Jun',
|
||||
'read' : true,
|
||||
'starred' : false,
|
||||
'important' : false,
|
||||
'hasAttachments': false,
|
||||
'labels' : [],
|
||||
'folder' : 0
|
||||
},
|
||||
{
|
||||
'id' : '1541ca7af66da284177',
|
||||
'from' : {
|
||||
'name' : 'Alan Coleman',
|
||||
'avatar': '',
|
||||
'email' : 'alancoleman@creapond.com'
|
||||
},
|
||||
'to' : [
|
||||
{
|
||||
'name' : 'me',
|
||||
'email': 'johndoe@creapond.com'
|
||||
}
|
||||
],
|
||||
'subject' : 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'message' : '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce lorem diam, pulvinar id nisl non, ultrices maximus nibh. Suspendisse ut justo velit. Nullam ac ultrices risus, quis auctor orci. Vestibulum volutpat nisi et neque porta ullamcorper. Maecenas porttitor porta erat ac suscipit. Sed cursus leo ut elementum fringilla. Maecenas semper viverra erat, vel ullamcorper dui efficitur in. Vestibulum placerat imperdiet tellus, et tincidunt eros posuere eget. Proin sit amet facilisis libero. Nulla eget est ut erat aliquet rhoncus. Quisque ac urna vitae dui hendrerit sollicitudin vel id sem. </p><p> In eget ante sapien. Quisque consequat velit non ante finibus, vel placerat erat ultricies. Aliquam bibendum justo erat, ultrices vehicula dolor elementum a. Mauris eu nisl feugiat ligula molestie eleifend. Aliquam efficitur venenatis velit ac porta. Vivamus vitae pulvinar tellus. Donec odio enim, auctor eget nibh mattis, ultricies dignissim lacus. Phasellus non tincidunt dui. Nulla eu arcu lorem. </p><p> Donec non hendrerit augue, lobortis sollicitudin odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis sit amet euismod enim, eget vestibulum justo. Fusce a placerat lectus, eget feugiat purus. Cras risus ante, faucibus eget justo commodo, volutpat tempor ante. Donec sit amet leo venenatis, gravida quam sit amet, blandit dui. In quam ante, elementum ut faucibus nec, tristique vitae dui. Praesent vel erat at enim placerat luctus vel ut ipsum. In congue tempor mi, non ornare lectus condimentum at. Aenean libero diam, finibus eget sapien et, tristique fermentum lorem. </p> ',
|
||||
'time' : '28 June',
|
||||
'read' : true,
|
||||
'starred' : false,
|
||||
'important' : false,
|
||||
'hasAttachments': false,
|
||||
'labels' : [],
|
||||
'folder' : 0
|
||||
},
|
||||
{
|
||||
'id' : '154297167e781781745',
|
||||
'from' : {
|
||||
'name' : 'Thomas Silva',
|
||||
'avatar': '',
|
||||
'email' : 'thomassilva@creapond.com'
|
||||
},
|
||||
'to' : [
|
||||
{
|
||||
'name' : 'me',
|
||||
'email': 'johndoe@creapond.com'
|
||||
}
|
||||
],
|
||||
'subject' : 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'message' : '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce lorem diam, pulvinar id nisl non, ultrices maximus nibh. Suspendisse ut justo velit. Nullam ac ultrices risus, quis auctor orci. Vestibulum volutpat nisi et neque porta ullamcorper. Maecenas porttitor porta erat ac suscipit. Sed cursus leo ut elementum fringilla. Maecenas semper viverra erat, vel ullamcorper dui efficitur in. Vestibulum placerat imperdiet tellus, et tincidunt eros posuere eget. Proin sit amet facilisis libero. Nulla eget est ut erat aliquet rhoncus. Quisque ac urna vitae dui hendrerit sollicitudin vel id sem. </p><p> In eget ante sapien. Quisque consequat velit non ante finibus, vel placerat erat ultricies. Aliquam bibendum justo erat, ultrices vehicula dolor elementum a. Mauris eu nisl feugiat ligula molestie eleifend. Aliquam efficitur venenatis velit ac porta. Vivamus vitae pulvinar tellus. Donec odio enim, auctor eget nibh mattis, ultricies dignissim lacus. Phasellus non tincidunt dui. Nulla eu arcu lorem. </p><p> Donec non hendrerit augue, lobortis sollicitudin odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis sit amet euismod enim, eget vestibulum justo. Fusce a placerat lectus, eget feugiat purus. Cras risus ante, faucibus eget justo commodo, volutpat tempor ante. Donec sit amet leo venenatis, gravida quam sit amet, blandit dui. In quam ante, elementum ut faucibus nec, tristique vitae dui. Praesent vel erat at enim placerat luctus vel ut ipsum. In congue tempor mi, non ornare lectus condimentum at. Aenean libero diam, finibus eget sapien et, tristique fermentum lorem. </p> ',
|
||||
'time' : '16 Jun',
|
||||
'read' : true,
|
||||
'starred' : false,
|
||||
'important' : false,
|
||||
'hasAttachments': false,
|
||||
'labels' : [],
|
||||
'folder' : 0
|
||||
},
|
||||
{
|
||||
'id' : '15427f4c1b7f3953234',
|
||||
'from' : {
|
||||
'name' : 'Jessica Robertson',
|
||||
'avatar': '',
|
||||
'email' : 'jessicarobertson@creapond.com'
|
||||
},
|
||||
'to' : [
|
||||
{
|
||||
'name' : 'me',
|
||||
'email': 'johndoe@creapond.com'
|
||||
}
|
||||
],
|
||||
'subject' : 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'message' : '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce lorem diam, pulvinar id nisl non, ultrices maximus nibh. Suspendisse ut justo velit. Nullam ac ultrices risus, quis auctor orci. Vestibulum volutpat nisi et neque porta ullamcorper. Maecenas porttitor porta erat ac suscipit. Sed cursus leo ut elementum fringilla. Maecenas semper viverra erat, vel ullamcorper dui efficitur in. Vestibulum placerat imperdiet tellus, et tincidunt eros posuere eget. Proin sit amet facilisis libero. Nulla eget est ut erat aliquet rhoncus. Quisque ac urna vitae dui hendrerit sollicitudin vel id sem. </p><p> In eget ante sapien. Quisque consequat velit non ante finibus, vel placerat erat ultricies. Aliquam bibendum justo erat, ultrices vehicula dolor elementum a. Mauris eu nisl feugiat ligula molestie eleifend. Aliquam efficitur venenatis velit ac porta. Vivamus vitae pulvinar tellus. Donec odio enim, auctor eget nibh mattis, ultricies dignissim lacus. Phasellus non tincidunt dui. Nulla eu arcu lorem. </p><p> Donec non hendrerit augue, lobortis sollicitudin odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis sit amet euismod enim, eget vestibulum justo. Fusce a placerat lectus, eget feugiat purus. Cras risus ante, faucibus eget justo commodo, volutpat tempor ante. Donec sit amet leo venenatis, gravida quam sit amet, blandit dui. In quam ante, elementum ut faucibus nec, tristique vitae dui. Praesent vel erat at enim placerat luctus vel ut ipsum. In congue tempor mi, non ornare lectus condimentum at. Aenean libero diam, finibus eget sapien et, tristique fermentum lorem. </p> ',
|
||||
'time' : '19 May',
|
||||
'read' : true,
|
||||
'starred' : false,
|
||||
'important' : false,
|
||||
'hasAttachments': false,
|
||||
'labels' : [],
|
||||
'folder' : 3
|
||||
},
|
||||
{
|
||||
'id' : '154204e45a59b168453',
|
||||
'from' : {
|
||||
'name' : 'John Palmer',
|
||||
'avatar': '',
|
||||
'email' : 'johnpalmer@creapond.com'
|
||||
},
|
||||
'to' : [
|
||||
{
|
||||
'name' : 'me',
|
||||
'email': 'johndoe@creapond.com'
|
||||
}
|
||||
],
|
||||
'subject' : 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'message' : '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce lorem diam, pulvinar id nisl non, ultrices maximus nibh. Suspendisse ut justo velit. Nullam ac ultrices risus, quis auctor orci. Vestibulum volutpat nisi et neque porta ullamcorper. Maecenas porttitor porta erat ac suscipit. Sed cursus leo ut elementum fringilla. Maecenas semper viverra erat, vel ullamcorper dui efficitur in. Vestibulum placerat imperdiet tellus, et tincidunt eros posuere eget. Proin sit amet facilisis libero. Nulla eget est ut erat aliquet rhoncus. Quisque ac urna vitae dui hendrerit sollicitudin vel id sem. </p><p> In eget ante sapien. Quisque consequat velit non ante finibus, vel placerat erat ultricies. Aliquam bibendum justo erat, ultrices vehicula dolor elementum a. Mauris eu nisl feugiat ligula molestie eleifend. Aliquam efficitur venenatis velit ac porta. Vivamus vitae pulvinar tellus. Donec odio enim, auctor eget nibh mattis, ultricies dignissim lacus. Phasellus non tincidunt dui. Nulla eu arcu lorem. </p><p> Donec non hendrerit augue, lobortis sollicitudin odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis sit amet euismod enim, eget vestibulum justo. Fusce a placerat lectus, eget feugiat purus. Cras risus ante, faucibus eget justo commodo, volutpat tempor ante. Donec sit amet leo venenatis, gravida quam sit amet, blandit dui. In quam ante, elementum ut faucibus nec, tristique vitae dui. Praesent vel erat at enim placerat luctus vel ut ipsum. In congue tempor mi, non ornare lectus condimentum at. Aenean libero diam, finibus eget sapien et, tristique fermentum lorem. </p> ',
|
||||
'time' : '8 May',
|
||||
'read' : true,
|
||||
'starred' : false,
|
||||
'important' : false,
|
||||
'hasAttachments': false,
|
||||
'labels' : [],
|
||||
'folder' : 3
|
||||
},
|
||||
{
|
||||
'id' : '1541dd1e05dfc439216',
|
||||
'from' : {
|
||||
'name' : 'David Butler',
|
||||
'avatar': '',
|
||||
'email' : 'davidbutler@creapond.com'
|
||||
},
|
||||
'to' : [
|
||||
{
|
||||
'name' : 'me',
|
||||
'email': 'johndoe@creapond.com'
|
||||
}
|
||||
],
|
||||
'subject' : 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'message' : '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce lorem diam, pulvinar id nisl non, ultrices maximus nibh. Suspendisse ut justo velit. Nullam ac ultrices risus, quis auctor orci. Vestibulum volutpat nisi et neque porta ullamcorper. Maecenas porttitor porta erat ac suscipit. Sed cursus leo ut elementum fringilla. Maecenas semper viverra erat, vel ullamcorper dui efficitur in. Vestibulum placerat imperdiet tellus, et tincidunt eros posuere eget. Proin sit amet facilisis libero. Nulla eget est ut erat aliquet rhoncus. Quisque ac urna vitae dui hendrerit sollicitudin vel id sem. </p><p> In eget ante sapien. Quisque consequat velit non ante finibus, vel placerat erat ultricies. Aliquam bibendum justo erat, ultrices vehicula dolor elementum a. Mauris eu nisl feugiat ligula molestie eleifend. Aliquam efficitur venenatis velit ac porta. Vivamus vitae pulvinar tellus. Donec odio enim, auctor eget nibh mattis, ultricies dignissim lacus. Phasellus non tincidunt dui. Nulla eu arcu lorem. </p><p> Donec non hendrerit augue, lobortis sollicitudin odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis sit amet euismod enim, eget vestibulum justo. Fusce a placerat lectus, eget feugiat purus. Cras risus ante, faucibus eget justo commodo, volutpat tempor ante. Donec sit amet leo venenatis, gravida quam sit amet, blandit dui. In quam ante, elementum ut faucibus nec, tristique vitae dui. Praesent vel erat at enim placerat luctus vel ut ipsum. In congue tempor mi, non ornare lectus condimentum at. Aenean libero diam, finibus eget sapien et, tristique fermentum lorem. </p> ',
|
||||
'time' : '7 May',
|
||||
'read' : true,
|
||||
'starred' : false,
|
||||
'important' : false,
|
||||
'hasAttachments': false,
|
||||
'labels' : [],
|
||||
'folder' : 3
|
||||
}
|
||||
];
|
||||
|
||||
public static folders = [
|
||||
{
|
||||
'id' : 0,
|
||||
'handle': 'inbox',
|
||||
'title' : 'Inbox',
|
||||
'icon' : 'inbox'
|
||||
},
|
||||
{
|
||||
'id' : 1,
|
||||
'handle': 'sent',
|
||||
'title' : 'Sent',
|
||||
'icon' : 'send'
|
||||
},
|
||||
{
|
||||
'id' : 2,
|
||||
'handle': 'drafts',
|
||||
'title' : 'Drafts',
|
||||
'icon' : 'email_open'
|
||||
},
|
||||
{
|
||||
'id' : 3,
|
||||
'handle': 'spam',
|
||||
'title' : 'Spam',
|
||||
'icon' : 'error'
|
||||
},
|
||||
{
|
||||
'id' : 4,
|
||||
'handle': 'trash',
|
||||
'title' : 'Trash',
|
||||
'icon' : 'delete'
|
||||
}
|
||||
];
|
||||
|
||||
public static filters = [
|
||||
{
|
||||
'id' : 0,
|
||||
'handle': 'starred',
|
||||
'title' : 'Starred',
|
||||
'icon' : 'star',
|
||||
'color' : 'amber-fg'
|
||||
},
|
||||
{
|
||||
'id' : 1,
|
||||
'handle': 'important',
|
||||
'title' : 'Important',
|
||||
'icon' : 'label',
|
||||
'color' : 'red-fg'
|
||||
}
|
||||
];
|
||||
|
||||
public static labels = [
|
||||
{
|
||||
'id' : 0,
|
||||
'handle': 'note',
|
||||
'title' : 'Note',
|
||||
'color' : '#7cb342'
|
||||
},
|
||||
{
|
||||
'id' : 1,
|
||||
'handle': 'paypal',
|
||||
'title' : 'Paypal',
|
||||
'color' : '#d84315'
|
||||
},
|
||||
{
|
||||
'id' : 2,
|
||||
'handle': 'invoice',
|
||||
'title' : 'Invoice',
|
||||
'color' : '#607d8b'
|
||||
},
|
||||
{
|
||||
'id' : 3,
|
||||
'handle': 'amazon',
|
||||
'title' : 'Amazon',
|
||||
'color' : '#03a9f4'
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -1,360 +0,0 @@
|
||||
export class ProfileFakeDb
|
||||
{
|
||||
public static timeline = {
|
||||
activities: [
|
||||
{
|
||||
'user' : {
|
||||
'name' : 'Alice Freeman',
|
||||
'avatar': 'assets/images/avatars/alice.jpg'
|
||||
},
|
||||
'message': 'started following you.',
|
||||
'time' : '13 mins. ago'
|
||||
},
|
||||
{
|
||||
'user' : {
|
||||
'name' : 'Andrew Green',
|
||||
'avatar': 'assets/images/avatars/andrew.jpg'
|
||||
},
|
||||
'message': 'sent you a message.',
|
||||
'time' : 'June 10,2015'
|
||||
},
|
||||
{
|
||||
'user' : {
|
||||
'name' : 'Garry Newman',
|
||||
'avatar': 'assets/images/avatars/garry.jpg'
|
||||
},
|
||||
'message': 'shared a public post with your group.',
|
||||
'time' : 'June 9,2015'
|
||||
},
|
||||
{
|
||||
'user' : {
|
||||
'name' : 'Carl Henderson',
|
||||
'avatar': 'assets/images/avatars/carl.jpg'
|
||||
},
|
||||
'message': 'wants to play Fallout Shelter with you.',
|
||||
'time' : 'June 8,2015'
|
||||
},
|
||||
{
|
||||
'user' : {
|
||||
'name' : 'Jane Dean',
|
||||
'avatar': 'assets/images/avatars/jane.jpg'
|
||||
},
|
||||
'message': 'started following you.',
|
||||
'time' : 'June 7,2015'
|
||||
},
|
||||
{
|
||||
'user' : {
|
||||
'name' : 'Juan Carpenter',
|
||||
'avatar': 'assets/images/avatars/james.jpg'
|
||||
},
|
||||
'message': 'sent you a message.',
|
||||
'time' : 'June 6,2015'
|
||||
},
|
||||
{
|
||||
'user' : {
|
||||
'name' : 'Judith Burton',
|
||||
'avatar': 'assets/images/avatars/joyce.jpg'
|
||||
},
|
||||
'message': 'shared a photo with you.',
|
||||
'time' : 'June 5,2015'
|
||||
},
|
||||
{
|
||||
'user' : {
|
||||
'name' : 'Vincent Munoz',
|
||||
'avatar': 'assets/images/avatars/vincent.jpg'
|
||||
},
|
||||
'message': 'shared a photo with you.',
|
||||
'time' : 'June 4,2015'
|
||||
}
|
||||
],
|
||||
posts : [
|
||||
{
|
||||
'user' : {
|
||||
'name' : 'Garry Newman',
|
||||
'avatar': 'assets/images/avatars/garry.jpg'
|
||||
},
|
||||
'message' : 'Remember the place we were talking about the other night? Found it!',
|
||||
'time' : '32 minutes ago',
|
||||
'type' : 'post',
|
||||
'like' : 5,
|
||||
'share' : 21,
|
||||
'media' : {
|
||||
'type' : 'image',
|
||||
'preview': 'assets/images/etc/early-sunrise.jpg'
|
||||
},
|
||||
'comments': [
|
||||
{
|
||||
'user' : {
|
||||
'name' : 'Alice Freeman',
|
||||
'avatar': 'assets/images/avatars/alice.jpg'
|
||||
},
|
||||
'time' : 'June 10, 2015',
|
||||
'message': 'That’s a wonderful place. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce et eleifend ligula. Fusce posuere in sapien ac facilisis. Etiam sit amet justo non felis ornare feugiat.'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'user' : {
|
||||
'name' : 'Andrew Green',
|
||||
'avatar': 'assets/images/avatars/andrew.jpg'
|
||||
},
|
||||
'message' : 'Hey, man! Check this, it’s pretty awesome!',
|
||||
'time' : 'June 12, 2015',
|
||||
'type' : 'article',
|
||||
'like' : 98,
|
||||
'share' : 6,
|
||||
'article' : {
|
||||
'title' : 'The Fallout 4 Pip-Boy Edition Is Back In Stock Now',
|
||||
'subtitle': 'Kotaku',
|
||||
'excerpt' : 'The Fallout 4 Pip-Boy edition is back in stock at Gamestop, for all 3 platforms. Additionally, Walmart also has it in stock for the PS4 and Xbox One as of this writing, as does Best Buy.',
|
||||
'media' : {
|
||||
'type' : 'image',
|
||||
'preview': 'assets/images/etc/fallout.jpg'
|
||||
}
|
||||
},
|
||||
'comments': [
|
||||
{
|
||||
'user' : {
|
||||
'name' : 'Alice Freeman',
|
||||
'avatar': 'assets/images/avatars/alice.jpg'
|
||||
},
|
||||
'time' : 'June 10, 2015',
|
||||
'message': 'That’s a wonderful place. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce et eleifend ligula. Fusce posuere in sapien ac facilisis. Etiam sit amet justo non felis ornare feugiat.'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'user' : {
|
||||
'name' : 'Carl Henderson',
|
||||
'avatar': 'assets/images/avatars/carl.jpg'
|
||||
},
|
||||
'message': 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce et eleifend ligula. Fusce posuere in sapien ac facilisis. Etiam sit amet justo non felis ornare feugiat. Aenean lorem ex, ultrices sit amet ligula sed...',
|
||||
'time' : 'June 10, 2015',
|
||||
'type' : 'something',
|
||||
'like' : 4,
|
||||
'share' : 1
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
public static photosVideos = [
|
||||
{
|
||||
'name' : 'June 2015',
|
||||
'info' : '5 Photos',
|
||||
'media': [
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Mountain Sunset',
|
||||
'preview': 'assets/images/etc/mountain-sunset.jpg'
|
||||
},
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Mountain Lake',
|
||||
'preview': 'assets/images/etc/mountain-lake.jpg'
|
||||
},
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Hot air balloons',
|
||||
'preview': 'assets/images/etc/air-balloons.jpg'
|
||||
},
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Cactus',
|
||||
'preview': 'assets/images/etc/cactus.jpg'
|
||||
},
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Road Trip',
|
||||
'preview': 'assets/images/etc/road-trip.jpg'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'name' : 'May 2015',
|
||||
'info' : '7 Photos, 3 Videos',
|
||||
'media': [
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Mountain Sunset',
|
||||
'preview': 'assets/images/etc/mountain-sunset.jpg'
|
||||
},
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Mountain Lake',
|
||||
'preview': 'assets/images/etc/mountain-lake.jpg'
|
||||
},
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Hot air balloons',
|
||||
'preview': 'assets/images/etc/air-balloons.jpg'
|
||||
},
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Cactus',
|
||||
'preview': 'assets/images/etc/cactus.jpg'
|
||||
},
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Road Trip',
|
||||
'preview': 'assets/images/etc/road-trip.jpg'
|
||||
},
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Mountain Sunset',
|
||||
'preview': 'assets/images/etc/mountain-sunset.jpg'
|
||||
},
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Mountain Lake',
|
||||
'preview': 'assets/images/etc/mountain-lake.jpg'
|
||||
},
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Hot air balloons',
|
||||
'preview': 'assets/images/etc/air-balloons.jpg'
|
||||
},
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Cactus',
|
||||
'preview': 'assets/images/etc/cactus.jpg'
|
||||
},
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Road Trip',
|
||||
'preview': 'assets/images/etc/road-trip.jpg'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'name' : 'April 2015',
|
||||
'info' : '5 Photos',
|
||||
'media': [
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Mountain Sunset',
|
||||
'preview': 'assets/images/etc/mountain-sunset.jpg'
|
||||
},
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Mountain Lake',
|
||||
'preview': 'assets/images/etc/mountain-lake.jpg'
|
||||
},
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Hot air balloons',
|
||||
'preview': 'assets/images/etc/air-balloons.jpg'
|
||||
},
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Cactus',
|
||||
'preview': 'assets/images/etc/cactus.jpg'
|
||||
},
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Road Trip',
|
||||
'preview': 'assets/images/etc/road-trip.jpg'
|
||||
},
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Mountain Sunset',
|
||||
'preview': 'assets/images/etc/mountain-sunset.jpg'
|
||||
},
|
||||
{
|
||||
'type' : 'photo',
|
||||
'title' : 'Mountain Lake',
|
||||
'preview': 'assets/images/etc/mountain-lake.jpg'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
public static about = {
|
||||
'general': {
|
||||
'gender' : 'Female',
|
||||
'birthday' : 'May 8th, 1988',
|
||||
'locations': [
|
||||
'Istanbul, Turkey',
|
||||
'New York, USA'
|
||||
],
|
||||
'about' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis eget pharetra felis, sed ullamcorper dui. Sed et elementum neque. Vestibulum pellente viverra ultrices. Etiam justo augue, vehicula ac gravida a, interdum sit amet nisl. Integer vitae nisi id nibh dictum mollis in vitae tortor.'
|
||||
},
|
||||
'work' : {
|
||||
'occupation': 'Developer',
|
||||
'skills' : 'C#, PHP, Javascript, Angular, JS, HTML, CSS',
|
||||
'jobs' : [
|
||||
{
|
||||
'company': 'Self-Employed',
|
||||
'date' : '2010 - Now'
|
||||
},
|
||||
{
|
||||
'company': 'Google',
|
||||
'date' : '2008 - 2010'
|
||||
}
|
||||
]
|
||||
},
|
||||
'contact': {
|
||||
'address' : 'Ut pharetra luctus est quis sodales. Duis nisi tortor, bibendum eget tincidunt, aliquam ac elit. Mauris nec euismod odio.',
|
||||
'tel' : [
|
||||
'+6 555 6600',
|
||||
'+9 555 5255'
|
||||
],
|
||||
'websites': [
|
||||
'withinpixels.com'
|
||||
],
|
||||
'emails' : [
|
||||
'mail@withinpixels.com',
|
||||
'mail@creapond.com'
|
||||
]
|
||||
},
|
||||
'groups' : [
|
||||
{
|
||||
'logo' : 'assets/images/logos/android.png',
|
||||
'name' : 'Android',
|
||||
'category': 'Technology',
|
||||
'members' : '1.856.546'
|
||||
},
|
||||
{
|
||||
'logo' : 'assets/images/logos/google.png',
|
||||
'name' : 'Google',
|
||||
'category': 'Web',
|
||||
'members' : '1.226.121'
|
||||
},
|
||||
{
|
||||
'logo' : 'assets/images/logos/fallout.png',
|
||||
'name' : 'Fallout',
|
||||
'category': 'Games',
|
||||
'members' : '526.142'
|
||||
}
|
||||
],
|
||||
'friends': [
|
||||
{
|
||||
'name' : 'Garry Newman',
|
||||
'avatar': 'assets/images/avatars/garry.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'Carl Henderson',
|
||||
'avatar': 'assets/images/avatars/carl.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'Jane Dean',
|
||||
'avatar': 'assets/images/avatars/jane.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'Garry Arnold',
|
||||
'avatar': 'assets/images/avatars/garry.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'Vincent Munoz',
|
||||
'avatar': 'assets/images/avatars/vincent.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'Alice Freeman',
|
||||
'avatar': 'assets/images/avatars/alice.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'Andrew Green',
|
||||
'avatar': 'assets/images/avatars/andrew.jpg'
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
export class QuickPanelFakeDb
|
||||
{
|
||||
public static notes = [
|
||||
{
|
||||
'title' : 'Best songs to listen while working',
|
||||
'detail': 'Last edit: May 8th, 2015'
|
||||
},
|
||||
{
|
||||
'title' : 'Useful subreddits',
|
||||
'detail': 'Last edit: January 12th, 2015'
|
||||
}
|
||||
];
|
||||
|
||||
public static events = [
|
||||
{
|
||||
'title' : 'Group Meeting',
|
||||
'detail': 'In 32 Minutes, Room 1B'
|
||||
},
|
||||
{
|
||||
'title' : 'Public Beta Release',
|
||||
'detail': '11:00 PM'
|
||||
},
|
||||
{
|
||||
'title' : 'Dinner with David',
|
||||
'detail': '17:30 PM'
|
||||
},
|
||||
{
|
||||
'title' : 'Q&A Session',
|
||||
'detail': '20:30 PM'
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -1,787 +0,0 @@
|
||||
export class ScrumboardFakeDb
|
||||
{
|
||||
public static boards = [
|
||||
{
|
||||
'id' : '32gfhaf2',
|
||||
'name' : 'ACME Frontend Application',
|
||||
'uri' : 'acme-frontend-application',
|
||||
'settings': {
|
||||
'color' : 'fuse-dark',
|
||||
'subscribed' : false,
|
||||
'cardCoverImages': true
|
||||
},
|
||||
'lists' : [
|
||||
{
|
||||
'id' : '56027cf5a2ca3839a5d36103',
|
||||
'name' : 'Design',
|
||||
'idCards': [
|
||||
'5603a2a3cab0c8300f6096b3',
|
||||
'44d1.2b51ea6cc2b5d.21f4a3412e857.8ffa2d8b44ad9.ac87215ed53a1.67d4921ad8f8d.9f318bcb2'
|
||||
]
|
||||
},
|
||||
{
|
||||
'id' : '56127cf2a2ca3539g7d36103',
|
||||
'name' : 'Development',
|
||||
'idCards': [
|
||||
'2837273da9b93dd84243s0f9',
|
||||
'5787b7e4740c57bf0dffd5b6',
|
||||
'5637273da9b93bb84743a0f9',
|
||||
'7987.9740ba532b0d4.f9d12243f7362.507c0738dc561.87fba0a03df6e.75e6508cacf10.7a9835b54'
|
||||
]
|
||||
},
|
||||
{
|
||||
'id' : 'faf244627326f1249525763d',
|
||||
'name' : 'Upcoming Features',
|
||||
'idCards': [
|
||||
'd9005a4b89ed2aadca48a6ad',
|
||||
'f6b9d7a9247e5d794a081927',
|
||||
'80ed.24ad3b18e2668.f28fbbceeeff9.5a834620a42f1.5909be19a2bf2.6c4a54947ce2d.da356b0c1',
|
||||
'0ad2.7862f947bc456.f42b446df54cb.d1dd9e93601a1.9deb1406d1404.0b3c278fc7001.733341b42',
|
||||
'bad3.51be8ad33acaf.9540ecb37f7e8.6bee596cfe7d3.44c68bee289c4.b96ed0b9f0af7.e14846035'
|
||||
]
|
||||
},
|
||||
{
|
||||
'id' : 'ad7d.9fffac5dff412.c83bca6853767.8fd7549b2b1ca.ceda8a01774c4.a5cf3976e87e4.ce79eeeea',
|
||||
'name' : 'Known Bugs',
|
||||
'idCards': [
|
||||
'acc6.9c673cd2f5e35.521e91d8d5991.4b2a95e0539d1.027930c0743c5.7ad1ea7bea476.e8fbe6347',
|
||||
'3279.3d69b40cc0b75.690252b6bea08.1e1789b0b7c2e.2f264b8661ce2.84d5f56910e23.429be5e8a',
|
||||
'ba01.8e1a43f92a03a.0022bd5cbb9ba.275c64d911d8c.880e0846a3966.f75ff43e53ad.48ad612e7'
|
||||
]
|
||||
}
|
||||
],
|
||||
'cards' : [
|
||||
{
|
||||
'id' : '2837273da9b93dd84243s0f9',
|
||||
'name' : 'Update generators',
|
||||
'description' : 'Current generator doesn\'t support Node.js 6 and above.',
|
||||
'idAttachmentCover': '',
|
||||
'idMembers' : [
|
||||
'26027s1930450d8bf7b10828'
|
||||
],
|
||||
'idLabels' : [
|
||||
'26022e4129ad3a5sc28b36cd'
|
||||
],
|
||||
'attachments' : [],
|
||||
'subscribed' : false,
|
||||
'checklists' : [],
|
||||
'checkItems' : 0,
|
||||
'checkItemsChecked': 0,
|
||||
'comments' : [
|
||||
{
|
||||
'idMember': '36027j1930450d8bf7b10158',
|
||||
'message' : 'AngularCLI could be a nice alternative.',
|
||||
'time' : 'now'
|
||||
}
|
||||
],
|
||||
'activities' : [],
|
||||
'due' : null
|
||||
},
|
||||
{
|
||||
'id' : '5603a2a3cab0c8300f6096b3',
|
||||
'name' : 'Change background colors',
|
||||
'description' : '',
|
||||
'idAttachmentCover': '67027cahbe3b52ecf2dc631c',
|
||||
'idMembers' : [
|
||||
'76027g1930450d8bf7b10958'
|
||||
],
|
||||
'idLabels' : [
|
||||
'56027e4119ad3a5dc28b36cd',
|
||||
'5640635e19ad3a5dc21416b2'
|
||||
],
|
||||
'attachments' : [
|
||||
{
|
||||
'id' : '67027cahbe3b52ecf2dc631c',
|
||||
'name': 'mail.jpg',
|
||||
'src' : 'assets/images/scrumboard/mail.jpg',
|
||||
'time': 'Added Nov 3 at 15:22AM',
|
||||
'type': 'image'
|
||||
},
|
||||
{
|
||||
'id' : '56027cfcbe1b72ecf1fc452a',
|
||||
'name': 'calendar.jpg',
|
||||
'src' : 'assets/images/scrumboard/calendar.jpg',
|
||||
'time': 'Added Nov 1 at 12:34PM',
|
||||
'type': 'image'
|
||||
}
|
||||
],
|
||||
'subscribed' : true,
|
||||
'checklists' : [
|
||||
{
|
||||
'id' : '63021cfdbe1x72wcf1fc451v',
|
||||
'name' : 'Checklist',
|
||||
'checkItemsChecked': 1,
|
||||
'checkItems' : [
|
||||
{
|
||||
'name' : 'Implement a calendar library',
|
||||
'checked': false
|
||||
},
|
||||
{
|
||||
'name' : 'Replace event colors with Material Design colors',
|
||||
'checked': true
|
||||
},
|
||||
{
|
||||
'name' : 'Replace icons with Material Design icons',
|
||||
'checked': false
|
||||
},
|
||||
{
|
||||
'name' : 'Use moment.js',
|
||||
'checked': false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'name' : 'Checklist 2',
|
||||
'id' : '74031cfdbe1x72wcz1dc166z',
|
||||
'checkItemsChecked': 1,
|
||||
'checkItems' : [
|
||||
{
|
||||
'name' : 'Replace event colors with Material Design colors',
|
||||
'checked': true
|
||||
},
|
||||
{
|
||||
'name' : 'Replace icons with Material Design icons',
|
||||
'checked': false
|
||||
},
|
||||
{
|
||||
'name' : 'Use moment.js',
|
||||
'checked': false
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
'checkItems' : 7,
|
||||
'checkItemsChecked': 2,
|
||||
'comments' : [
|
||||
{
|
||||
'idMember': '56027c1930450d8bf7b10758',
|
||||
'message' : 'We should be able to add moment.js without any problems',
|
||||
'time' : '12 mins. ago'
|
||||
},
|
||||
{
|
||||
'idMember': '36027j1930450d8bf7b10158',
|
||||
'message' : 'I added a link for a page that might help us deciding the colors',
|
||||
'time' : '30 mins. ago'
|
||||
}
|
||||
],
|
||||
'activities' : [
|
||||
{
|
||||
'idMember': '56027c1930450d8bf7b10758',
|
||||
'message' : 'added a comment',
|
||||
'time' : '12 mins. ago'
|
||||
},
|
||||
{
|
||||
'idMember': '36027j1930450d8bf7b10158',
|
||||
'message' : 'added a comment',
|
||||
'time' : '30 mins. ago'
|
||||
},
|
||||
{
|
||||
'idMember': '36027j1930450d8bf7b10158',
|
||||
'message' : 'attached a link',
|
||||
'time' : '45 mins. ago'
|
||||
}
|
||||
],
|
||||
'due' : '2017-08-29T10:16:34.000Z'
|
||||
},
|
||||
{
|
||||
'id' : '5637273da9b93bb84743a0f9',
|
||||
'name' : 'Fix splash screen bugs',
|
||||
'description' : '',
|
||||
'idAttachmentCover': '',
|
||||
'idMembers' : [
|
||||
'56027c1930450d8bf7b10758'
|
||||
],
|
||||
'idLabels' : [
|
||||
'5640635e19ad3a5dc21416b2'
|
||||
],
|
||||
'attachments' : [],
|
||||
'subscribed' : true,
|
||||
'checklists' : [],
|
||||
'checkItems' : 0,
|
||||
'checkItemsChecked': 0,
|
||||
'comments' : [],
|
||||
'activities' : [],
|
||||
'due' : null
|
||||
},
|
||||
{
|
||||
'id' : 'd9005a4b89ed2aadca48a6ad',
|
||||
'name' : 'Add alternative authentication pages',
|
||||
'description' : '',
|
||||
'idAttachmentCover': '',
|
||||
'idMembers' : [
|
||||
'36027j1930450d8bf7b10158'
|
||||
],
|
||||
'idLabels' : [
|
||||
'6540635g19ad3s5dc31412b2',
|
||||
'56027e4119ad3a5dc28b36cd'
|
||||
],
|
||||
'attachments' : [],
|
||||
'subscribed' : false,
|
||||
'checklists' : [
|
||||
{
|
||||
'id' : 'dbfb.99bd0ad37dabc.e05046f0c824d.18f26bb524c96.78bebc8488634.240c0ee6a5e45.4cb872965',
|
||||
'name' : 'Pages',
|
||||
'checkItemsChecked': 2,
|
||||
'checkItems' : [
|
||||
{
|
||||
'name' : 'Login',
|
||||
'checked': true
|
||||
},
|
||||
{
|
||||
'name' : 'Register',
|
||||
'checked': true
|
||||
},
|
||||
{
|
||||
'name' : 'Lost Password',
|
||||
'checked': false
|
||||
},
|
||||
{
|
||||
'name' : 'Recover Password',
|
||||
'checked': false
|
||||
},
|
||||
{
|
||||
'name' : 'Activate Account',
|
||||
'checked': false
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
'checkItems' : 5,
|
||||
'checkItemsChecked': 2,
|
||||
'comments' : [],
|
||||
'activities' : [],
|
||||
'due' : null
|
||||
},
|
||||
{
|
||||
'id' : '5787b7e4740c57bf0dffd5b6',
|
||||
'name' : 'Fix the console',
|
||||
'description' : 'We need to fix the console asap!',
|
||||
'idAttachmentCover': '',
|
||||
'idMembers' : [],
|
||||
'idLabels' : [
|
||||
'26022e4129ad3a5sc28b36cd'
|
||||
],
|
||||
'attachments' : [],
|
||||
'subscribed' : true,
|
||||
'checklists' : [],
|
||||
'checkItems' : 0,
|
||||
'checkItemsChecked': 0,
|
||||
'comments' : [
|
||||
{
|
||||
'idMember': '36027j1930450d8bf7b10158',
|
||||
'message' : 'I\'m on it!',
|
||||
'time' : 'now'
|
||||
}
|
||||
],
|
||||
'activities' : [],
|
||||
'due' : '2018-09-07T12:00:00.000Z'
|
||||
},
|
||||
{
|
||||
'id' : 'f6b9d7a9247e5d794a081927',
|
||||
'name' : 'New media player',
|
||||
'description' : '',
|
||||
'idAttachmentCover': '',
|
||||
'idMembers' : [
|
||||
'76027g1930450d8bf7b10958',
|
||||
'56027c1930450d8bf7b10758',
|
||||
'26027s1930450d8bf7b10828'
|
||||
],
|
||||
'idLabels' : [
|
||||
'5640635e19ad3a5dc21416b2',
|
||||
'6540635g19ad3s5dc31412b2'
|
||||
],
|
||||
'attachments' : [],
|
||||
'subscribed' : false,
|
||||
'checklists' : [],
|
||||
'checkItems' : 0,
|
||||
'checkItemsChecked': 0,
|
||||
'comments' : [],
|
||||
'activities' : [],
|
||||
'due' : null
|
||||
},
|
||||
{
|
||||
'id' : 'acc6.9c673cd2f5e35.521e91d8d5991.4b2a95e0539d1.027930c0743c5.7ad1ea7bea476.e8fbe6347',
|
||||
'name' : 'Memory Leak',
|
||||
'description' : '',
|
||||
'idAttachmentCover': '',
|
||||
'idMembers' : [
|
||||
'36027j1930450d8bf7b10158'
|
||||
],
|
||||
'idLabels' : [
|
||||
'26022e4129ad3a5sc28b36cd',
|
||||
'5640635e19ad3a5dc21416b2'
|
||||
],
|
||||
'attachments' : [],
|
||||
'subscribed' : false,
|
||||
'checklists' : [],
|
||||
'checkItems' : 0,
|
||||
'checkItemsChecked': 0,
|
||||
'comments' : [],
|
||||
'activities' : [],
|
||||
'due' : null
|
||||
},
|
||||
{
|
||||
'id' : '3279.3d69b40cc0b75.690252b6bea08.1e1789b0b7c2e.2f264b8661ce2.84d5f56910e23.429be5e8a',
|
||||
'name' : 'Broken toolbar on profile page',
|
||||
'description' : '',
|
||||
'idAttachmentCover': '',
|
||||
'idMembers' : [
|
||||
'26027s1930450d8bf7b10828'
|
||||
],
|
||||
'idLabels' : [
|
||||
'26022e4129ad3a5sc28b36cd'
|
||||
],
|
||||
'attachments' : [],
|
||||
'subscribed' : false,
|
||||
'checklists' : [],
|
||||
'checkItems' : 0,
|
||||
'checkItemsChecked': 0,
|
||||
'comments' : [
|
||||
{
|
||||
'idMember': '36027j1930450d8bf7b10158',
|
||||
'message' : 'This should be a medium priority bug, shouldn\'t it?',
|
||||
'time' : 'now'
|
||||
}
|
||||
],
|
||||
'activities' : [],
|
||||
'due' : null
|
||||
},
|
||||
{
|
||||
'id' : 'ba01.8e1a43f92a03a.0022bd5cbb9ba.275c64d911d8c.880e0846a3966.f75ff43e53ad.48ad612e7',
|
||||
'name' : 'Button hover style',
|
||||
'description' : 'If there are 3 or more buttons in certain page, weird flashing happens when you hover over the red ones.',
|
||||
'idAttachmentCover': '',
|
||||
'idMembers' : [
|
||||
'26027s1930450d8bf7b10828'
|
||||
],
|
||||
'idLabels' : [
|
||||
'26022e4129ad3a5sc28b36cd',
|
||||
'5640635e19ad3a5dc21416b2'
|
||||
],
|
||||
'attachments' : [],
|
||||
'subscribed' : true,
|
||||
'checklists' : [],
|
||||
'checkItems' : 0,
|
||||
'checkItemsChecked': 0,
|
||||
'comments' : [],
|
||||
'activities' : [],
|
||||
'due' : '2017-03-08T09:00:00.000Z'
|
||||
},
|
||||
{
|
||||
'id' : '80ed.24ad3b18e2668.f28fbbceeeff9.5a834620a42f1.5909be19a2bf2.6c4a54947ce2d.da356b0c1',
|
||||
'name' : 'New header designs',
|
||||
'description' : '',
|
||||
'idAttachmentCover': '12027cafbe3b52ecf2ef632c',
|
||||
'idMembers' : [],
|
||||
'idLabels' : [
|
||||
'56027e4119ad3a5dc28b36cd',
|
||||
'6540635g19ad3s5dc31412b2',
|
||||
'5640635e19ad3a5dc21416b2'
|
||||
],
|
||||
'attachments' : [
|
||||
{
|
||||
'id' : '12027cafbe3b52ecf2ef632c',
|
||||
'name': 'header-.jpg',
|
||||
'src' : 'assets/images/scrumboard/header-1.jpg',
|
||||
'time': 'Added Nov 3 at 15:22AM',
|
||||
'type': 'image'
|
||||
},
|
||||
{
|
||||
'id' : '55027ced1e1a12ecf1fced2a',
|
||||
'name': 'header-2.jpg',
|
||||
'src' : 'assets/images/scrumboard/header-2.jpg',
|
||||
'time': 'Added Nov 1 at 12:34PM',
|
||||
'type': 'image'
|
||||
}
|
||||
],
|
||||
'subscribed' : false,
|
||||
'checklists' : [],
|
||||
'checkItems' : 0,
|
||||
'checkItemsChecked': 0,
|
||||
'comments' : [
|
||||
{
|
||||
'idMember': '36027j1930450d8bf7b10158',
|
||||
'message' : 'Currently we have two new designs ready to ship.',
|
||||
'time' : 'now'
|
||||
}
|
||||
],
|
||||
'activities' : [],
|
||||
'due' : null
|
||||
},
|
||||
{
|
||||
'id' : '0ad2.7862f947bc456.f42b446df54cb.d1dd9e93601a1.9deb1406d1404.0b3c278fc7001.733341b42',
|
||||
'name' : 'Fixed footer',
|
||||
'description' : '',
|
||||
'idAttachmentCover': '',
|
||||
'idMembers' : [
|
||||
'26027s1930450d8bf7b10828',
|
||||
'56027c1930450d8bf7b10758'
|
||||
],
|
||||
'idLabels' : [
|
||||
'6540635g19ad3s5dc31412b2'
|
||||
],
|
||||
'attachments' : [],
|
||||
'subscribed' : true,
|
||||
'checklists' : [],
|
||||
'checkItems' : 0,
|
||||
'checkItemsChecked': 0,
|
||||
'comments' : [],
|
||||
'activities' : [],
|
||||
'due' : null
|
||||
},
|
||||
{
|
||||
'id' : 'bad3.51be8ad33acaf.9540ecb37f7e8.6bee596cfe7d3.44c68bee289c4.b96ed0b9f0af7.e14846035',
|
||||
'name' : 'Collapsable navigation',
|
||||
'description' : '',
|
||||
'idAttachmentCover': '',
|
||||
'idMembers' : [],
|
||||
'idLabels' : [
|
||||
'6540635g19ad3s5dc31412b2'
|
||||
],
|
||||
'attachments' : [],
|
||||
'subscribed' : false,
|
||||
'checklists' : [],
|
||||
'checkItems' : 0,
|
||||
'checkItemsChecked': 0,
|
||||
'comments' : [
|
||||
{
|
||||
'idMember': '36027j1930450d8bf7b10158',
|
||||
'message' : 'I\'m not sure why we re-doing the navigation. The current collapsable navigation works flawlessly.',
|
||||
'time' : 'now'
|
||||
}
|
||||
],
|
||||
'activities' : [],
|
||||
'due' : null
|
||||
},
|
||||
{
|
||||
'id' : '44d1.2b51ea6cc2b5d.21f4a3412e857.8ffa2d8b44ad9.ac87215ed53a1.67d4921ad8f8d.9f318bcb2',
|
||||
'name' : 'Mail app new layout',
|
||||
'description' : 'Current layout has lots of flaws in mobile. Outlook view should help with that.',
|
||||
'idAttachmentCover': '',
|
||||
'idMembers' : [
|
||||
'56027c1930450d8bf7b10758',
|
||||
'26027s1930450d8bf7b10828',
|
||||
'76027g1930450d8bf7b10958',
|
||||
'36027j1930450d8bf7b10158'
|
||||
],
|
||||
'idLabels' : [
|
||||
'56027e4119ad3a5dc28b36cd',
|
||||
'26022e4129ad3a5sc28b36cd'
|
||||
],
|
||||
'attachments' : [],
|
||||
'subscribed' : false,
|
||||
'checklists' : [],
|
||||
'checkItems' : 0,
|
||||
'checkItemsChecked': 0,
|
||||
'comments' : [],
|
||||
'activities' : [],
|
||||
'due' : null
|
||||
},
|
||||
{
|
||||
'id' : '7987.9740ba532b0d4.f9d12243f7362.507c0738dc561.87fba0a03df6e.75e6508cacf10.7a9835b54',
|
||||
'name' : 'API recover and monitoring',
|
||||
'description' : 'We need a service to monitor and recover failed APIs.',
|
||||
'idAttachmentCover': '',
|
||||
'idMembers' : [
|
||||
'36027j1930450d8bf7b10158',
|
||||
'76027g1930450d8bf7b10958'
|
||||
],
|
||||
'idLabels' : [
|
||||
'26022e4129ad3a5sc28b36cd',
|
||||
'5640635e19ad3a5dc21416b2'
|
||||
],
|
||||
'attachments' : [],
|
||||
'subscribed' : true,
|
||||
'checklists' : [
|
||||
{
|
||||
'id' : '6926.2b31d119e4a.889401e0ca7a0.13ad8ce2e569d.976e54e8b5d87.456afccd7e820.d6c77106a',
|
||||
'name' : 'API Monitoring',
|
||||
'checkItemsChecked': 2,
|
||||
'checkItems' : [
|
||||
{
|
||||
'name' : 'Simple dashboard design',
|
||||
'checked': false
|
||||
},
|
||||
{
|
||||
'name' : 'Should be able to see different time periods on the same dashboard',
|
||||
'checked': true
|
||||
},
|
||||
{
|
||||
'name' : 'Different colors for different clusters',
|
||||
'checked': true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'id' : '7c22.5261c7924387f.248e8b1d32205.003f7a9f501d1.1d48dcdbe8b23.8099dcc5f75a7.29a966196',
|
||||
'name' : 'API Recovery',
|
||||
'checkItemsChecked': 1,
|
||||
'checkItems' : [
|
||||
{
|
||||
'name' : 'Warning notifications to all developers',
|
||||
'checked': false
|
||||
},
|
||||
{
|
||||
'name' : 'Immediate recovery options attached to the notifications',
|
||||
'checked': true
|
||||
},
|
||||
{
|
||||
'name' : 'Backups every 6hours',
|
||||
'checked': false
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
'checkItems' : 6,
|
||||
'checkItemsChecked': 3,
|
||||
'comments' : [],
|
||||
'activities' : [],
|
||||
'due' : '2017-02-02T11:20:34.000Z'
|
||||
}
|
||||
],
|
||||
'members' : [
|
||||
{
|
||||
'id' : '56027c1930450d8bf7b10758',
|
||||
'name' : 'Alice Freeman',
|
||||
'avatar': 'assets/images/avatars/alice.jpg'
|
||||
},
|
||||
{
|
||||
'id' : '26027s1930450d8bf7b10828',
|
||||
'name' : 'Danielle Obrien',
|
||||
'avatar': 'assets/images/avatars/danielle.jpg'
|
||||
},
|
||||
{
|
||||
'id' : '76027g1930450d8bf7b10958',
|
||||
'name' : 'James Lewis',
|
||||
'avatar': 'assets/images/avatars/james.jpg'
|
||||
},
|
||||
{
|
||||
'id' : '36027j1930450d8bf7b10158',
|
||||
'name' : 'Vincent Munoz',
|
||||
'avatar': 'assets/images/avatars/vincent.jpg'
|
||||
}
|
||||
],
|
||||
'labels' : [
|
||||
{
|
||||
'id' : '26022e4129ad3a5sc28b36cd',
|
||||
'name' : 'High Priority',
|
||||
'color': 'mat-red-500-bg'
|
||||
},
|
||||
{
|
||||
'id' : '56027e4119ad3a5dc28b36cd',
|
||||
'name' : 'Design',
|
||||
'color': 'mat-orange-400-bg'
|
||||
},
|
||||
{
|
||||
'id' : '5640635e19ad3a5dc21416b2',
|
||||
'name' : 'App',
|
||||
'color': 'mat-blue-600-bg'
|
||||
},
|
||||
{
|
||||
'id' : '6540635g19ad3s5dc31412b2',
|
||||
'name' : 'Feature',
|
||||
'color': 'mat-green-400-bg'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'id' : '27cfcbe1',
|
||||
'name' : 'ACME Backend Application',
|
||||
'uri' : 'acme-backend-application',
|
||||
'settings': {
|
||||
'color' : 'blue-grey',
|
||||
'subscribed' : false,
|
||||
'cardCoverImages': true
|
||||
},
|
||||
'lists' : [
|
||||
{
|
||||
'id' : '56027cf5a2ca3839a5d36103',
|
||||
'name' : 'Designs',
|
||||
'idCards': [
|
||||
'5603a2a3cab0c8300f6096b3'
|
||||
]
|
||||
},
|
||||
{
|
||||
'id' : '56127cf2a2ca3539g7d36103',
|
||||
'name' : 'Development',
|
||||
'idCards': [
|
||||
'5637273da9b93bb84743a0f9'
|
||||
]
|
||||
}
|
||||
],
|
||||
'cards' : [
|
||||
{
|
||||
'id' : '5603a2a3cab0c8300f6096b3',
|
||||
'name' : 'Calendar App Design',
|
||||
'description' : '',
|
||||
'idAttachmentCover': '56027cfcbe1b72ecf1fc452a',
|
||||
'idMembers' : [
|
||||
'56027c1930450d8bf7b10758',
|
||||
'36027j1930450d8bf7b10158'
|
||||
],
|
||||
'idLabels' : [
|
||||
'56027e4119ad3a5dc28b36cd',
|
||||
'5640635e19ad3a5dc21416b2'
|
||||
],
|
||||
'attachments' : [
|
||||
{
|
||||
'id' : '56027cfcbe1b72ecf1fc452a',
|
||||
'name': 'calendar-app-design.jpg',
|
||||
'src' : 'assets/images/scrumboard/calendar.jpg',
|
||||
'time': 'Added Nov 1 at 12:34PM',
|
||||
'type': 'image'
|
||||
},
|
||||
{
|
||||
'id' : '67027cahbe3b52ecf2dc631c',
|
||||
'url' : 'assets/images/scrumboard/calendar.jpg',
|
||||
'time': 'Added Nov 3 at 15:22AM',
|
||||
'type': 'link'
|
||||
}
|
||||
],
|
||||
'subscribed' : true,
|
||||
'checklists' : [
|
||||
{
|
||||
'id' : '63021cfdbe1x72wcf1fc451v',
|
||||
'name' : 'Checklist',
|
||||
'checkItemsChecked': 1,
|
||||
'checkItems' : [
|
||||
{
|
||||
'name' : 'Implement a calendar library',
|
||||
'checked': false
|
||||
},
|
||||
{
|
||||
'name' : 'Replace event colors with Material Design colors',
|
||||
'checked': true
|
||||
},
|
||||
{
|
||||
'name' : 'Replace icons with Material Design icons',
|
||||
'checked': false
|
||||
},
|
||||
{
|
||||
'name' : 'Use moment.js',
|
||||
'checked': false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'name' : 'Checklist 2',
|
||||
'id' : '74031cfdbe1x72wcz1dc166z',
|
||||
'checkItemsChecked': 1,
|
||||
'checkItems' : [
|
||||
{
|
||||
'name' : 'Replace event colors with Material Design colors',
|
||||
'checked': true
|
||||
},
|
||||
{
|
||||
'name' : 'Replace icons with Material Design icons',
|
||||
'checked': false
|
||||
},
|
||||
{
|
||||
'name' : 'Use moment.js',
|
||||
'checked': false
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
'checkItems' : 7,
|
||||
'checkItemsChecked': 2,
|
||||
'comments' : [
|
||||
{
|
||||
'idMember': '56027c1930450d8bf7b10758',
|
||||
'message' : 'We should be able to add moment.js without any problems',
|
||||
'time' : '12 mins. ago'
|
||||
},
|
||||
{
|
||||
'idMember': '36027j1930450d8bf7b10158',
|
||||
'message' : 'I added a link for a page that might help us deciding the colors',
|
||||
'time' : '30 mins. ago'
|
||||
}
|
||||
],
|
||||
'activities' : [
|
||||
{
|
||||
'idMember': '56027c1930450d8bf7b10758',
|
||||
'message' : 'added a comment',
|
||||
'time' : '12 mins. ago'
|
||||
},
|
||||
{
|
||||
'idMember': '36027j1930450d8bf7b10158',
|
||||
'message' : 'added a comment',
|
||||
'time' : '30 mins. ago'
|
||||
},
|
||||
{
|
||||
'idMember': '36027j1930450d8bf7b10158',
|
||||
'message' : 'attached a link',
|
||||
'time' : '45 mins. ago'
|
||||
}
|
||||
],
|
||||
'due' : null
|
||||
},
|
||||
{
|
||||
'id' : '5637273da9b93bb84743a0f9',
|
||||
'name' : 'Fix Splash Screen bugs',
|
||||
'description' : '',
|
||||
'idAttachmentCover': '5603a2ae2bbd55bb2db57478',
|
||||
'idMembers' : [
|
||||
'56027c1930450d8bf7b10758'
|
||||
],
|
||||
'idLabels' : [],
|
||||
'attachments' : [
|
||||
{
|
||||
'id' : '5603a2ae2bbd55bb2db57478',
|
||||
'name': 'mail-app-design.jpg',
|
||||
'src' : 'assets/images/scrumboard/mail.jpg',
|
||||
'time': 'Added Nov 1 at 12:34PM',
|
||||
'type': 'image'
|
||||
}
|
||||
],
|
||||
'subscribed' : true,
|
||||
'checklists' : [],
|
||||
'checkItems' : 0,
|
||||
'checkItemsChecked': 0,
|
||||
'comments' : [],
|
||||
'activities' : [],
|
||||
'due' : null
|
||||
}
|
||||
],
|
||||
'members' : [
|
||||
{
|
||||
'id' : '56027c1930450d8bf7b10758',
|
||||
'name' : 'Alice Freeman',
|
||||
'avatar': 'assets/images/avatars/alice.jpg'
|
||||
},
|
||||
{
|
||||
'id' : '26027s1930450d8bf7b10828',
|
||||
'name' : 'Danielle Obrien',
|
||||
'avatar': 'assets/images/avatars/danielle.jpg'
|
||||
},
|
||||
{
|
||||
'id' : '76027g1930450d8bf7b10958',
|
||||
'name' : 'James Lewis',
|
||||
'avatar': 'assets/images/avatars/james.jpg'
|
||||
},
|
||||
{
|
||||
'id' : '36027j1930450d8bf7b10158',
|
||||
'name' : 'Vincent Munoz',
|
||||
'avatar': 'assets/images/avatars/vincent.jpg'
|
||||
}
|
||||
],
|
||||
'labels' : [
|
||||
{
|
||||
'id' : '56027e4119ad3a5dc28b36cd',
|
||||
'name' : 'Design',
|
||||
'color': 'mat-red-500-bg'
|
||||
},
|
||||
{
|
||||
'id' : '5640635e19ad3a5dc21416b2',
|
||||
'name' : 'App',
|
||||
'color': 'mat-blue-500-bg'
|
||||
},
|
||||
{
|
||||
'id' : '6540635g19ad3s5dc31412b2',
|
||||
'name' : 'Feature',
|
||||
'color': 'mat-green-400-bg'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
export class SearchFakeDb
|
||||
{
|
||||
public static classic = [
|
||||
{
|
||||
'title' : 'Dynamically Procrastinate B2C',
|
||||
'url' : 'ourwebaddress.com/articles/procrastinate',
|
||||
'excerpt': 'Collaboratively administrate empowered markets via plug-and-play networks. Dynamically procrastinate B2C users after installed base benefits.'
|
||||
},
|
||||
{
|
||||
'title' : 'Cross Media',
|
||||
'url' : 'ourwebaddress.com/articles/cross-media',
|
||||
'excerpt': 'Efficiently unleash cross-media information without cross-media value. Quickly maximize timely deliverables for real-time schemas.'
|
||||
},
|
||||
{
|
||||
'title' : 'Synergize',
|
||||
'url' : 'ourwebaddress.com/articles/synergize',
|
||||
'excerpt': 'Completely synergize resource taxing relationships via premier niche markets. Professionally cultivate one-to-one customer service with robust ideas.'
|
||||
},
|
||||
{
|
||||
'title' : 'Parallel Platforms',
|
||||
'url' : 'ourwebaddress.com/articles/parallel-paltforms',
|
||||
'excerpt': 'Objectively innovate empowered manufactured products whereas parallel platforms. Holisticly predominate extensible testing procedures for reliable supply chains.'
|
||||
},
|
||||
{
|
||||
'title' : 'Growth Strategies',
|
||||
'url' : 'ourwebaddress.com/articles/growth-strategies',
|
||||
'excerpt': 'Proactively envisioned multimedia based expertise and cross-media growth strategies. Holistically pontificate installed base portals after maintainable products.'
|
||||
},
|
||||
{
|
||||
'title' : 'Methodologies',
|
||||
'url' : 'ourwebaddress.com/articles/methodologies',
|
||||
'excerpt': 'Phosfluorescently engage worldwide methodologies with web-enabled technology. Completely pursue scalable customer service through sustainable potentialities.'
|
||||
},
|
||||
{
|
||||
'title' : 'E-tailers',
|
||||
'url' : 'ourwebaddress.com/articles/e-trailers',
|
||||
'excerpt': 'Collaboratively administrate turnkey channels whereas virtual e-tailers. Objectively seize scalable metrics whereas proactive e-services.'
|
||||
},
|
||||
{
|
||||
'title' : 'Web Readiness',
|
||||
'url' : 'ourwebaddress.com/articles/web-readiness',
|
||||
'excerpt': 'Credibly innovate granular internal or organic sources whereas high standards in web-readiness. Dramatically synthesize integrated schemas with optimal networks.'
|
||||
}
|
||||
];
|
||||
|
||||
public static table = [
|
||||
{
|
||||
'name' : 'Airi Satou',
|
||||
'position' : 'Accountant',
|
||||
'office' : 'Tokyo',
|
||||
'age' : '33',
|
||||
'startDate': '2008/11/28',
|
||||
'salary' : '162700',
|
||||
'email' : 'a.satou@mail.com'
|
||||
},
|
||||
{
|
||||
'name' : 'Angellica Ramos',
|
||||
'position' : 'Chief Executive Officer (CEO)',
|
||||
'office' : 'London',
|
||||
'age' : '47',
|
||||
'startDate': '2009/10/09',
|
||||
'salary' : '1200000',
|
||||
'email' : 'a.ramos@mail.com'
|
||||
},
|
||||
{
|
||||
'name' : 'Ashton Cox',
|
||||
'position' : 'Hunior Technical Author',
|
||||
'office' : 'San Fransisco',
|
||||
'age' : '66',
|
||||
'startDate': '2009/01/12',
|
||||
'salary' : '86000',
|
||||
'email' : 'a.cox@mail.com'
|
||||
},
|
||||
{
|
||||
'name' : 'Bradley Greer',
|
||||
'position' : 'Software Engineer',
|
||||
'office' : 'London',
|
||||
'age' : '41',
|
||||
'startDate': '2012/10/13',
|
||||
'salary' : '132000',
|
||||
'email' : 'b.greer@mail.com'
|
||||
},
|
||||
{
|
||||
'name' : 'Brenden Wagner',
|
||||
'position' : 'Software Engineer',
|
||||
'office' : 'San Fransisco',
|
||||
'age' : '28',
|
||||
'startDate': '2011/06/07',
|
||||
'salary' : '206850',
|
||||
'email' : 'b.wagner@mail.com'
|
||||
},
|
||||
{
|
||||
'name' : 'Brielle Williamson',
|
||||
'position' : 'Integration Specialist',
|
||||
'office' : 'New York',
|
||||
'age' : '61',
|
||||
'startDate': '2012/12/02',
|
||||
'salary' : '372000',
|
||||
'email' : 'b.williamson@mail.com'
|
||||
},
|
||||
{
|
||||
'name' : 'Bruno Nash',
|
||||
'position' : 'Software Engineer',
|
||||
'office' : 'London',
|
||||
'age' : '38',
|
||||
'startDate': '2011/05/03',
|
||||
'salary' : '163500',
|
||||
'email' : 'b.nash@mail.com'
|
||||
},
|
||||
{
|
||||
'name' : 'Caesar Vance',
|
||||
'position' : 'Pre-Sales Support',
|
||||
'office' : 'New York',
|
||||
'age' : '21',
|
||||
'startDate': '2011/12/12',
|
||||
'salary' : '106450',
|
||||
'email' : 'c.vance@mail.com'
|
||||
},
|
||||
{
|
||||
'name' : 'Cara Stevens',
|
||||
'position' : 'Sales Assistant',
|
||||
'office' : 'New York',
|
||||
'age' : '46',
|
||||
'startDate': '2011/12/06',
|
||||
'salary' : '145600',
|
||||
'email' : 'c.stevens@mail.com'
|
||||
},
|
||||
{
|
||||
'name' : 'Cedric Kelly',
|
||||
'position' : 'Senior Javascript Developer',
|
||||
'office' : 'Edinburg',
|
||||
'age' : '22',
|
||||
'startDate': '2012/03/29',
|
||||
'salary' : '433060',
|
||||
'email' : 'c.kelly@mail.com'
|
||||
}
|
||||
];
|
||||
|
||||
}
|
||||
@@ -1,324 +0,0 @@
|
||||
export class TodoFakeDb
|
||||
{
|
||||
public static todos = [
|
||||
{
|
||||
'id' : '561551bd7fe2ff461101c192',
|
||||
'title' : 'Proident tempor est nulla irure ad est',
|
||||
'notes' : 'Id nulla nulla proident deserunt deserunt proident in quis. Cillum reprehenderit labore id anim laborum.',
|
||||
'startDate': 'Wednesday, January 29, 2014 3:17 PM',
|
||||
'dueDate' : null,
|
||||
'completed': false,
|
||||
'starred' : false,
|
||||
'important': false,
|
||||
'deleted' : false,
|
||||
'tags' : [1]
|
||||
},
|
||||
{
|
||||
'id' : '561551bd4ac1e7eb77a3a750',
|
||||
'title' : 'Magna quis irure quis ea pariatur laborum',
|
||||
'notes' : '',
|
||||
'startDate': 'Sunday, February 1, 2015 1:30 PM',
|
||||
'dueDate' : 'Friday, December 30, 2016 10:07 AM',
|
||||
'completed': false,
|
||||
'starred' : false,
|
||||
'important': true,
|
||||
'deleted' : false,
|
||||
'tags' : [1, 4]
|
||||
},
|
||||
{
|
||||
'id' : '561551bd917bfec2ddef2d49',
|
||||
'title' : 'Ullamco duis commodo sint ad aliqua aute',
|
||||
'notes' : 'Sunt laborum enim nostrud ea fugiat cillum mollit aliqua exercitation ad elit.',
|
||||
'startDate': 'Friday, April 11, 2014 3:43 AM',
|
||||
'dueDate' : 'Wednesday, July 26, 2017 11:14 AM',
|
||||
'completed': false,
|
||||
'starred' : true,
|
||||
'important': true,
|
||||
'deleted' : false,
|
||||
'tags' : [3]
|
||||
},
|
||||
{
|
||||
'id' : '561551bdeeb2fd6877e18c29',
|
||||
'title' : 'Eiusmod non occaecat pariatur Lorem in ex',
|
||||
'notes' : 'Nostrud anim mollit incididunt qui qui sit commodo duis. Anim amet irure aliquip duis nostrud sit quis fugiat ullamco non dolor labore. Lorem sunt voluptate laboris culpa proident. Aute eiusmod aliqua exercitation irure exercitation qui laboris mollit occaecat eu occaecat fugiat.',
|
||||
'startDate': 'Wednesday, May 7, 2014 4:14 AM',
|
||||
'dueDate' : 'Friday, December 15, 2017 4:01 AM',
|
||||
'completed': true,
|
||||
'starred' : true,
|
||||
'important': false,
|
||||
'deleted' : false,
|
||||
'tags' : [2]
|
||||
},
|
||||
{
|
||||
'id' : '561551bdf38eae0134ae43d4',
|
||||
'title' : 'Lorem magna cillum consequat consequat mollit',
|
||||
'notes' : 'Velit ipsum proident ea incididunt et. Consectetur eiusmod laborum voluptate duis occaecat ullamco sint enim proident.',
|
||||
'startDate': 'Sunday, August 23, 2015 11:19 PM',
|
||||
'dueDate' : 'Friday, July 8, 2016 10:49 AM',
|
||||
'completed': false,
|
||||
'starred' : false,
|
||||
'important': false,
|
||||
'deleted' : false,
|
||||
'tags' : [5, 4]
|
||||
},
|
||||
{
|
||||
'id' : '561551bd32f1588c814a0ccd',
|
||||
'title' : 'Quis irure cupidatat ad consequat reprehenderit excepteur',
|
||||
'notes' : 'Esse nisi mollit aliquip mollit aute consequat adipisicing. Do excepteur dolore proident cupidatat pariatur irure consequat incididunt.',
|
||||
'startDate': 'Sunday, June 7, 2015 10:49 AM',
|
||||
'dueDate' : 'Monday, January 9, 2017 8:34 AM',
|
||||
'completed': false,
|
||||
'starred' : true,
|
||||
'important': false,
|
||||
'deleted' : false,
|
||||
'tags' : [2, 3]
|
||||
},
|
||||
{
|
||||
'id' : '561551bd0bb4b08ca77038ef',
|
||||
'title' : 'Officia voluptate tempor ut mollit ea cillum',
|
||||
'notes' : 'Deserunt veniam reprehenderit do elit magna ut.',
|
||||
'startDate': 'Saturday, October 18, 2014 4:25 AM',
|
||||
'dueDate' : 'Sunday, August 21, 2016 10:48 PM',
|
||||
'completed': true,
|
||||
'starred' : false,
|
||||
'important': false,
|
||||
'deleted' : false,
|
||||
'tags' : [2, 4]
|
||||
},
|
||||
{
|
||||
'id' : '561551bdf84eec913835ebe5',
|
||||
'title' : 'Sit exercitation cupidatat minim est ipsum excepteur',
|
||||
'notes' : '',
|
||||
'startDate': 'Friday, August 8, 2014 5:45 AM',
|
||||
'dueDate' : 'Wednesday, June 15, 2016 1:53 PM',
|
||||
'completed': true,
|
||||
'starred' : false,
|
||||
'important': true,
|
||||
'deleted' : false,
|
||||
'tags' : [1, 3]
|
||||
},
|
||||
{
|
||||
'id' : '561551bd2047cc709af0f670',
|
||||
'title' : 'Sunt fugiat officia nisi minim sunt duis',
|
||||
'notes' : 'Eiusmod eiusmod sint aliquip exercitation cillum. Magna nulla officia ex consectetur ea ad excepteur in qui.',
|
||||
'startDate': 'Monday, July 13, 2015 1:55 PM',
|
||||
'dueDate' : 'Thursday, March 3, 2016 2:26 PM',
|
||||
'completed': false,
|
||||
'starred' : false,
|
||||
'important': false,
|
||||
'deleted' : false,
|
||||
'tags' : [
|
||||
{
|
||||
'id' : 5,
|
||||
'name' : 'mobile',
|
||||
'label': 'Mobile',
|
||||
'color': '#9C27B0'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'id' : '561551bd73d1a627e97005ce',
|
||||
'title' : 'Non cupidatat enim quis aliquip minim laborum',
|
||||
'notes' : 'Qui cillum eiusmod nostrud sunt dolore velit nostrud labore voluptate ad dolore. Eu Lorem anim pariatur aliqua. Ullamco ut dolor velit esse occaecat dolore eu cillum commodo qui. Nulla dolor consequat voluptate magna ut commodo magna consectetur non aute proident.',
|
||||
'startDate': 'Tuesday, November 11, 2014 6:36 PM',
|
||||
'dueDate' : 'Tuesday, August 9, 2016 7:18 AM',
|
||||
'completed': false,
|
||||
'starred' : false,
|
||||
'important': false,
|
||||
'deleted' : false,
|
||||
'tags' : [2]
|
||||
},
|
||||
{
|
||||
'id' : '561551bd8f7d793ded0a2353',
|
||||
'title' : 'Dolor ex occaecat magna labore laboris qui',
|
||||
'notes' : 'Incididunt qui excepteur eiusmod elit cillum occaecat voluptate cillum nostrud. Dolor ullamco ullamco eiusmod do sunt adipisicing pariatur. In esse esse labore id reprehenderit sint do. Pariatur culpa dolor tempor qui excepteur duis do anim minim ipsum.',
|
||||
'startDate': 'Monday, June 9, 2014 3:15 PM',
|
||||
'dueDate' : 'Wednesday, October 19, 2016 3:38 PM',
|
||||
'completed': false,
|
||||
'starred' : false,
|
||||
'important': true,
|
||||
'deleted' : false,
|
||||
'tags' : [3]
|
||||
},
|
||||
{
|
||||
'id' : '561551bdaa586f72d0be02cc',
|
||||
'title' : 'Ex nisi amet id dolore nostrud esse',
|
||||
'notes' : '',
|
||||
'startDate': 'Thursday, January 15, 2015 6:11 PM',
|
||||
'dueDate' : 'Sunday, August 20, 2017 10:02 AM',
|
||||
'completed': false,
|
||||
'starred' : true,
|
||||
'important': true,
|
||||
'deleted' : false,
|
||||
'tags' : [4]
|
||||
},
|
||||
{
|
||||
'id' : '561551bd9f1c2de5b27f537b',
|
||||
'title' : 'In dolor velit labore dolore ex eiusmod',
|
||||
'notes' : '',
|
||||
'startDate': 'Monday, March 10, 2014 12:50 AM',
|
||||
'dueDate' : 'Thursday, January 26, 2017 3:10 PM',
|
||||
'completed': false,
|
||||
'starred' : false,
|
||||
'important': false,
|
||||
'deleted' : false,
|
||||
'tags' : [4]
|
||||
},
|
||||
{
|
||||
'id' : '561551bd26e21bb5e85b35cb',
|
||||
'title' : 'Sunt voluptate aliquip exercitation minim magna sit',
|
||||
'notes' : '',
|
||||
'startDate': 'Tuesday, March 24, 2015 10:54 PM',
|
||||
'dueDate' : 'Wednesday, August 23, 2017 5:35 PM',
|
||||
'completed': false,
|
||||
'starred' : false,
|
||||
'important': false,
|
||||
'deleted' : false,
|
||||
'tags' : [4]
|
||||
},
|
||||
{
|
||||
'id' : '561551bd719860cf0ad2011a',
|
||||
'title' : 'Nisi et ullamco minim ea proident tempor',
|
||||
'notes' : 'Dolor veniam dolor cillum Lorem magna nisi in occaecat nulla dolor ea eiusmod.',
|
||||
'startDate': 'Friday, February 14, 2014 10:03 AM',
|
||||
'dueDate' : 'Saturday, July 8, 2017 11:54 PM',
|
||||
'completed': false,
|
||||
'starred' : true,
|
||||
'important': false,
|
||||
'deleted' : false,
|
||||
'tags' : [2, 4]
|
||||
},
|
||||
{
|
||||
'id' : '561551bd49d800c243264a91',
|
||||
'title' : 'Sit ipsum mollit cupidatat adipisicing officia aliquip',
|
||||
'notes' : '',
|
||||
'startDate': 'Wednesday, December 10, 2014 9:25 AM',
|
||||
'dueDate' : 'Friday, March 25, 2016 12:29 AM',
|
||||
'completed': true,
|
||||
'starred' : false,
|
||||
'important': false,
|
||||
'deleted' : false,
|
||||
'tags' : [1]
|
||||
},
|
||||
{
|
||||
'id' : '561551bd061990eaf40fb64f',
|
||||
'title' : 'Amet sunt et quis amet commodo quis',
|
||||
'notes' : 'Nulla dolore consequat aliqua sint consequat elit qui occaecat et.',
|
||||
'startDate': 'Saturday, March 1, 2014 3:59 PM',
|
||||
'dueDate' : 'Saturday, November 7, 2015 2:00 PM',
|
||||
'completed': false,
|
||||
'starred' : false,
|
||||
'important': true,
|
||||
'deleted' : false,
|
||||
'tags' : [1]
|
||||
},
|
||||
{
|
||||
'id' : '561551be81d05fa94711e7f3',
|
||||
'title' : 'Ut eiusmod ex ea eiusmod culpa incididunt',
|
||||
'notes' : 'Fugiat non incididunt officia ex incididunt occaecat. Voluptate nostrud culpa aliquip mollit incididunt non dolore.',
|
||||
'startDate': 'Monday, February 2, 2015 3:07 PM',
|
||||
'dueDate' : 'Saturday, October 14, 2017 6:57 AM',
|
||||
'completed': false,
|
||||
'starred' : false,
|
||||
'important': false,
|
||||
'deleted' : false,
|
||||
'tags' : [2]
|
||||
},
|
||||
{
|
||||
'id' : '561551be05c093a80e0c8d05',
|
||||
'title' : 'Proident reprehenderit laboris pariatur ut et nisi',
|
||||
'notes' : 'Reprehenderit proident ut ad cillum quis velit quis aliqua ut aliquip tempor ullamco.',
|
||||
'startDate': 'Sunday, June 14, 2015 4:40 AM',
|
||||
'dueDate' : 'Wednesday, February 10, 2016 10:47 AM',
|
||||
'completed': true,
|
||||
'starred' : true,
|
||||
'important': true,
|
||||
'deleted' : false,
|
||||
'tags' : [5]
|
||||
},
|
||||
{
|
||||
'id' : '561551be3bb43a5bd431c2fc',
|
||||
'title' : 'Aliqua aliquip aliquip aliquip et exercitation aute',
|
||||
'notes' : 'Adipisicing Lorem tempor ex anim. Labore tempor laboris nostrud dolore voluptate ullamco. Fugiat ex deserunt anim minim esse velit laboris aute ea duis incididunt. Elit irure id Lorem incididunt laborum aliquip consectetur est irure sunt. Ut labore anim nisi aliqua tempor laborum nulla cillum. Duis irure consequat cillum magna cillum eiusmod ut. Et exercitation voluptate quis deserunt elit quis dolor deserunt ex ex esse ex.',
|
||||
'startDate': 'Saturday, May 3, 2014 1:32 AM',
|
||||
'dueDate' : 'Monday, September 12, 2016 9:16 PM',
|
||||
'completed': true,
|
||||
'starred' : false,
|
||||
'important': true,
|
||||
'deleted' : true,
|
||||
'tags' : [3]
|
||||
}
|
||||
];
|
||||
|
||||
public static filters = [
|
||||
{
|
||||
'id' : 0,
|
||||
'handle': 'starred',
|
||||
'title' : 'Starred',
|
||||
'icon' : 'star'
|
||||
},
|
||||
{
|
||||
'id' : 1,
|
||||
'handle': 'important',
|
||||
'title' : 'Priority',
|
||||
'icon' : 'error'
|
||||
},
|
||||
{
|
||||
'id' : 2,
|
||||
'handle': 'dueDate',
|
||||
'title' : 'Sheduled',
|
||||
'icon' : 'schedule'
|
||||
},
|
||||
{
|
||||
'id' : 3,
|
||||
'handle': 'today',
|
||||
'title' : 'Today',
|
||||
'icon' : 'today'
|
||||
},
|
||||
{
|
||||
'id' : 4,
|
||||
'handle': 'completed',
|
||||
'title' : 'Done',
|
||||
'icon' : 'check'
|
||||
},
|
||||
{
|
||||
'id' : 4,
|
||||
'handle': 'deleted',
|
||||
'title' : 'Deleted',
|
||||
'icon' : 'delete'
|
||||
}
|
||||
];
|
||||
|
||||
public static tags = [
|
||||
{
|
||||
'id' : 1,
|
||||
'handle': 'frontend',
|
||||
'title' : 'Frontend',
|
||||
'color' : '#388E3C'
|
||||
},
|
||||
{
|
||||
'id' : 2,
|
||||
'handle': 'backend',
|
||||
'title' : 'Backend',
|
||||
'color' : '#F44336'
|
||||
},
|
||||
{
|
||||
'id' : 3,
|
||||
'handle': 'api',
|
||||
'title' : 'API',
|
||||
'color' : '#FF9800'
|
||||
},
|
||||
{
|
||||
'id' : 4,
|
||||
'handle': 'issue',
|
||||
'title' : 'Issue',
|
||||
'color' : '#0091EA'
|
||||
},
|
||||
{
|
||||
'id' : 5,
|
||||
'handle': 'mobile',
|
||||
'title' : 'Mobile',
|
||||
'color' : '#9C27B0'
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -1,7 +1,4 @@
|
||||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Component, ViewEncapsulation } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector : 'quick-panel',
|
||||
@@ -9,24 +6,17 @@ import { takeUntil } from 'rxjs/operators';
|
||||
styleUrls : ['./quick-panel.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class QuickPanelComponent implements OnInit, OnDestroy
|
||||
export class QuickPanelComponent
|
||||
{
|
||||
date: Date;
|
||||
events: any[];
|
||||
notes: any[];
|
||||
settings: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {HttpClient} _httpClient
|
||||
*/
|
||||
constructor(
|
||||
private _httpClient: HttpClient
|
||||
)
|
||||
constructor()
|
||||
{
|
||||
// Set the defaults
|
||||
this.date = new Date();
|
||||
@@ -35,42 +25,5 @@ export class QuickPanelComponent implements OnInit, OnDestroy
|
||||
cloud : false,
|
||||
retro : true
|
||||
};
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to the events
|
||||
this._httpClient.get('api/quick-panel-events')
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((response: any) => {
|
||||
this.events = response;
|
||||
});
|
||||
|
||||
// Subscribe to the notes
|
||||
this._httpClient.get('api/quick-panel-notes')
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((response: any) => {
|
||||
this.notes = response;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,12 +79,6 @@
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<button mat-menu-item [routerLink]="'/components/multi-language'">
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<span>Learn more</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
</mat-menu>
|
||||
|
||||
<div class="toolbar-separator" fxHide fxShow.gt-xs></div>
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
<div class="page-layout simple fullwidth angular-material-elements">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24 h-160" fxLayout="column" fxLayoutAlign="center center" fxLayout.gt-xs="row"
|
||||
fxLayoutAlign.gt-xs="space-between center">
|
||||
|
||||
<div fxLayout="column" fxLayoutAlign="center center" fxLayout.gt-xs="column" fxLayoutAlign.gt-xs="center start">
|
||||
<div class="black-fg" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="secondary-text s-18">home</mat-icon>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Components</span>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Angular Material Elements</span>
|
||||
</div>
|
||||
<div class="h2 mt-16">{{title}}</div>
|
||||
</div>
|
||||
|
||||
<a mat-raised-button class="reference-button mat-white-bg mt-16 mt-sm-0" href="https://material.angular.io/"
|
||||
target="_blank">
|
||||
<mat-icon class="mr-8">link</mat-icon>
|
||||
<span>Reference</span>
|
||||
</a>
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content p-24">
|
||||
<div *ngFor="let example of examples">
|
||||
<example-viewer [example]="example"></example-viewer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
:host {
|
||||
|
||||
.angular-material-elements {
|
||||
|
||||
> .content {
|
||||
max-width: 960px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { COMPONENT_MAP } from 'app/main/angular-material-elements/example-components';
|
||||
|
||||
@Component({
|
||||
selector : 'angular-material',
|
||||
templateUrl: './angular-material-elements.component.html',
|
||||
styleUrls : ['./angular-material-elements.component.scss']
|
||||
})
|
||||
export class AngularMaterialElementsComponent implements OnInit, OnDestroy
|
||||
{
|
||||
id: string;
|
||||
title: string;
|
||||
examples: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ActivatedRoute} _activatedRoute
|
||||
*/
|
||||
constructor(
|
||||
private _activatedRoute: ActivatedRoute
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._activatedRoute.params
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(params => {
|
||||
this.id = params['id'];
|
||||
const _title = this.id.replace('-', ' ');
|
||||
this.title = _title.charAt(0).toUpperCase() + _title.substring(1);
|
||||
this.examples = COMPONENT_MAP[this.id];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { FuseSharedModule } from '@fuse/shared.module';
|
||||
import { FuseHighlightModule } from '@fuse/components/index';
|
||||
import { FuseWidgetModule } from '@fuse/components/widget/widget.module';
|
||||
|
||||
import { MaterialModule } from 'app/main/angular-material-elements/material.module';
|
||||
import { EXAMPLE_LIST } from 'app/main/angular-material-elements/example-components';
|
||||
import { AngularMaterialElementsComponent } from 'app/main/angular-material-elements/angular-material-elements.component';
|
||||
import { ExampleViewerComponent } from 'app/main/angular-material-elements/example-viewer/example-viewer';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path : '',
|
||||
children: [
|
||||
{
|
||||
path : ':id',
|
||||
component: AngularMaterialElementsComponent
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations : [
|
||||
[...EXAMPLE_LIST],
|
||||
AngularMaterialElementsComponent,
|
||||
ExampleViewerComponent
|
||||
],
|
||||
imports : [
|
||||
RouterModule.forChild(routes),
|
||||
|
||||
MaterialModule,
|
||||
|
||||
FuseSharedModule,
|
||||
FuseHighlightModule,
|
||||
FuseWidgetModule
|
||||
],
|
||||
entryComponents: EXAMPLE_LIST,
|
||||
})
|
||||
export class AngularMaterialElementsModule
|
||||
{
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,71 +0,0 @@
|
||||
<div class="example-viewer-wrapper mat-white-bg mat-elevation-z2">
|
||||
|
||||
<div class="example-viewer-header">
|
||||
|
||||
<div class="example-viewer-title">{{exampleData?.title}}</div>
|
||||
|
||||
<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">
|
||||
<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>
|
||||
</svg>
|
||||
</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="example-viewer-source" [fxShow]="showSource">
|
||||
|
||||
<mat-tab-group [(selectedIndex)]="selectedIndex">
|
||||
<mat-tab label="HTML"></mat-tab>
|
||||
<mat-tab label="TS"></mat-tab>
|
||||
<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'}}">
|
||||
<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>
|
||||
<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'}}">
|
||||
<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>
|
||||
<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'}}">
|
||||
<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>
|
||||
<fuse-highlight lang="css"
|
||||
[path]="'/assets/angular-material-examples/'+example+'/'+example+'-example.css'">
|
||||
</fuse-highlight>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="example-viewer-body" [fxHide]="showSource">
|
||||
<!--<ng-template [cdkPortalOutlet]="selectedPortal"></ng-template>-->
|
||||
<!--<ng-template [cdkPortalOutlet]="selectedPortal"></ng-template>-->
|
||||
<div #previewContainer></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,75 +0,0 @@
|
||||
@import "../../../../@fuse/scss/fuse";
|
||||
|
||||
example-viewer {
|
||||
display: block;
|
||||
padding: 24px 0;
|
||||
|
||||
.example-viewer-wrapper {
|
||||
border: 1px solid rgba(mat-color($foreground, secondary-text), .03);
|
||||
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.24), 0 0 2px rgba(0, 0, 0, 0.12);
|
||||
margin: 4px;
|
||||
h3 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.example-viewer-header {
|
||||
align-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 8px 20px;
|
||||
color: mat-color($foreground, secondary-text);
|
||||
background: rgba(mat-color($foreground, secondary-text), .03);
|
||||
flex: 1 1 auto;
|
||||
|
||||
.example-viewer-title {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.example-viewer-source {
|
||||
|
||||
.tab-content {
|
||||
background: #263238;
|
||||
|
||||
.tab {
|
||||
position: relative;
|
||||
|
||||
.example-source-copy {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
display: none;
|
||||
right: 8px;
|
||||
|
||||
mat-icon {
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.example-source-copy {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.example-source {
|
||||
display: flex;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
min-height: 150px;
|
||||
border-bottom: 1px solid mat-color($foreground, divider);
|
||||
|
||||
> pre {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.example-viewer-body {
|
||||
padding: 24px;
|
||||
}
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
import { AfterViewInit, Component, ComponentFactoryResolver, ComponentRef, Input, OnDestroy, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material';
|
||||
import 'prismjs/components/prism-scss';
|
||||
import 'prismjs/components/prism-typescript';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations/index';
|
||||
import { FuseCopierService } from '@fuse/services/copier.service';
|
||||
|
||||
import { EXAMPLE_COMPONENTS } from 'app/main/angular-material-elements/example-components';
|
||||
|
||||
export interface LiveExample
|
||||
{
|
||||
title: string;
|
||||
component: any;
|
||||
additionalFiles?: string[];
|
||||
selectorName?: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector : 'example-viewer',
|
||||
templateUrl : './example-viewer.html',
|
||||
styleUrls : ['./example-viewer.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class ExampleViewerComponent implements AfterViewInit, OnDestroy
|
||||
{
|
||||
_example: string;
|
||||
exampleData: LiveExample;
|
||||
showSource: boolean;
|
||||
previewRef: ComponentRef<any>;
|
||||
selectedIndex: number;
|
||||
|
||||
@ViewChild('previewContainer', {read: ViewContainerRef})
|
||||
private _previewContainer: ViewContainerRef;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {MatSnackBar} _matSnackBar
|
||||
* @param {FuseCopierService} _fuseCopierService
|
||||
* @param {ComponentFactoryResolver} _componentFactoryResolver
|
||||
*/
|
||||
constructor(
|
||||
private _matSnackBar: MatSnackBar,
|
||||
private _fuseCopierService: FuseCopierService,
|
||||
private _componentFactoryResolver: ComponentFactoryResolver
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.selectedIndex = 0;
|
||||
this.showSource = false;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Accessors
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Container
|
||||
*
|
||||
* @param {ViewContainerRef} value
|
||||
*/
|
||||
set container(value: ViewContainerRef)
|
||||
{
|
||||
this._previewContainer = value;
|
||||
}
|
||||
|
||||
get container(): ViewContainerRef
|
||||
{
|
||||
return this._previewContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Example
|
||||
*
|
||||
* @param {string} example
|
||||
*/
|
||||
@Input()
|
||||
set example(example: string)
|
||||
{
|
||||
if ( example && EXAMPLE_COMPONENTS[example] )
|
||||
{
|
||||
this._example = example;
|
||||
this.exampleData = EXAMPLE_COMPONENTS[example];
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('MISSING EXAMPLE: ', example);
|
||||
}
|
||||
}
|
||||
|
||||
get example(): string
|
||||
{
|
||||
return this._example;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* After view init
|
||||
*/
|
||||
ngAfterViewInit(): void
|
||||
{
|
||||
setTimeout(() => {
|
||||
const cmpFactory = this._componentFactoryResolver.resolveComponentFactory(this.exampleData.component);
|
||||
this.previewRef = this._previewContainer.createComponent(cmpFactory);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
if ( this.previewRef )
|
||||
{
|
||||
this.previewRef.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Toggle source view
|
||||
*/
|
||||
toggleSourceView(): void
|
||||
{
|
||||
this.showSource = !this.showSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the source
|
||||
*
|
||||
* @param {string} text
|
||||
*/
|
||||
copySource(text: string): void
|
||||
{
|
||||
if ( this._fuseCopierService.copyText(text) )
|
||||
{
|
||||
this._matSnackBar.open('Code copied', '', {duration: 2500});
|
||||
}
|
||||
else
|
||||
{
|
||||
this._matSnackBar.open('Copy failed. Please try again!', '', {duration: 2500});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { CdkTableModule } from '@angular/cdk/table';
|
||||
import { CdkTreeModule } from '@angular/cdk/tree';
|
||||
import {
|
||||
MatAutocompleteModule, MatBadgeModule, MatBottomSheetModule, MatButtonModule,
|
||||
MatButtonToggleModule, MatCardModule, MatCheckboxModule, MatChipsModule, MatDatepickerModule,
|
||||
MatDialogModule, MatDividerModule, MatExpansionModule, MatFormFieldModule, MatGridListModule,
|
||||
MatIconModule, MatInputModule, MatListModule, MatMenuModule, MatPaginatorModule,
|
||||
MatProgressBarModule, MatProgressSpinnerModule, MatRadioModule, MatRippleModule, MatSelectModule,
|
||||
MatSidenavModule, MatSliderModule, MatSlideToggleModule, MatSnackBarModule, MatSortModule,
|
||||
MatStepperModule, MatTableModule, MatTabsModule, MatToolbarModule, MatTooltipModule, MatTreeModule
|
||||
} from '@angular/material';
|
||||
import { MatMomentDateModule } from '@angular/material-moment-adapter';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CdkTableModule,
|
||||
CdkTreeModule,
|
||||
MatAutocompleteModule,
|
||||
MatBadgeModule,
|
||||
MatBottomSheetModule,
|
||||
MatButtonModule,
|
||||
MatButtonToggleModule,
|
||||
MatCardModule,
|
||||
MatCheckboxModule,
|
||||
MatChipsModule,
|
||||
MatDatepickerModule,
|
||||
MatDialogModule,
|
||||
MatDividerModule,
|
||||
MatExpansionModule,
|
||||
MatFormFieldModule,
|
||||
MatGridListModule,
|
||||
MatIconModule,
|
||||
MatInputModule,
|
||||
MatListModule,
|
||||
MatMenuModule,
|
||||
MatMomentDateModule,
|
||||
MatPaginatorModule,
|
||||
MatProgressBarModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatRadioModule,
|
||||
MatRippleModule,
|
||||
MatSelectModule,
|
||||
MatSidenavModule,
|
||||
MatSlideToggleModule,
|
||||
MatSliderModule,
|
||||
MatSnackBarModule,
|
||||
MatSortModule,
|
||||
MatStepperModule,
|
||||
MatTableModule,
|
||||
MatTabsModule,
|
||||
MatToolbarModule,
|
||||
MatTooltipModule,
|
||||
MatTreeModule
|
||||
],
|
||||
exports: [
|
||||
CdkTableModule,
|
||||
CdkTreeModule,
|
||||
MatAutocompleteModule,
|
||||
MatBadgeModule,
|
||||
MatBottomSheetModule,
|
||||
MatButtonModule,
|
||||
MatButtonToggleModule,
|
||||
MatCardModule,
|
||||
MatCheckboxModule,
|
||||
MatChipsModule,
|
||||
MatDatepickerModule,
|
||||
MatDialogModule,
|
||||
MatDividerModule,
|
||||
MatExpansionModule,
|
||||
MatFormFieldModule,
|
||||
MatGridListModule,
|
||||
MatIconModule,
|
||||
MatInputModule,
|
||||
MatListModule,
|
||||
MatMenuModule,
|
||||
MatMomentDateModule,
|
||||
MatPaginatorModule,
|
||||
MatProgressBarModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatRadioModule,
|
||||
MatRippleModule,
|
||||
MatSelectModule,
|
||||
MatSidenavModule,
|
||||
MatSlideToggleModule,
|
||||
MatSliderModule,
|
||||
MatSnackBarModule,
|
||||
MatSortModule,
|
||||
MatStepperModule,
|
||||
MatTableModule,
|
||||
MatTabsModule,
|
||||
MatToolbarModule,
|
||||
MatTooltipModule,
|
||||
MatTreeModule
|
||||
]
|
||||
})
|
||||
export class MaterialModule
|
||||
{
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { MatButtonModule, MatFormFieldModule, MatIconModule, MatInputModule, MatSelectModule } from '@angular/material';
|
||||
|
||||
import { FuseSharedModule } from '@fuse/shared.module';
|
||||
|
||||
import { AcademyCoursesComponent } from 'app/main/apps/academy/courses/courses.component';
|
||||
import { AcademyCourseComponent } from 'app/main/apps/academy/course/course.component';
|
||||
import { AcademyCoursesService } from 'app/main/apps/academy/courses.service';
|
||||
import { AcademyCourseService } from 'app/main/apps/academy/course.service';
|
||||
import { FuseSidebarModule } from '@fuse/components';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path : 'courses',
|
||||
component: AcademyCoursesComponent,
|
||||
resolve : {
|
||||
academy: AcademyCoursesService
|
||||
}
|
||||
},
|
||||
{
|
||||
path : 'courses/:courseId/:courseSlug',
|
||||
component: AcademyCourseComponent,
|
||||
resolve : {
|
||||
academy: AcademyCourseService
|
||||
}
|
||||
},
|
||||
{
|
||||
path : '**',
|
||||
redirectTo: 'courses'
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AcademyCoursesComponent,
|
||||
AcademyCourseComponent
|
||||
],
|
||||
imports : [
|
||||
RouterModule.forChild(routes),
|
||||
|
||||
MatButtonModule,
|
||||
MatFormFieldModule,
|
||||
MatIconModule,
|
||||
MatInputModule,
|
||||
MatSelectModule,
|
||||
|
||||
FuseSharedModule,
|
||||
FuseSidebarModule
|
||||
],
|
||||
providers : [
|
||||
AcademyCoursesService,
|
||||
AcademyCourseService
|
||||
]
|
||||
})
|
||||
export class AcademyModule
|
||||
{
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
|
||||
@Injectable()
|
||||
export class AcademyCourseService implements Resolve<any>
|
||||
{
|
||||
onCourseChanged: BehaviorSubject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {HttpClient} _httpClient
|
||||
*/
|
||||
constructor(
|
||||
private _httpClient: HttpClient
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.onCourseChanged = new BehaviorSubject({});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 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
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get course
|
||||
*
|
||||
* @param courseId
|
||||
* @param courseSlug
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
getCourse(courseId, courseSlug): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this._httpClient.get('api/academy-course/' + courseId + '/' + courseSlug)
|
||||
.subscribe((response: any) => {
|
||||
this.onCourseChanged.next(response);
|
||||
resolve(response);
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
<div id="academy-course" class="page-layout simple left-sidebar inner-scroll">
|
||||
|
||||
<!-- SIDEBAR -->
|
||||
<fuse-sidebar class="sidebar" name="academy-course-left-sidebar-1" position="left" lockedOpen="gt-md">
|
||||
|
||||
<!-- SIDEBAR CONTENT -->
|
||||
<div class="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>
|
||||
<!-- / SIDEBAR CONTENT -->
|
||||
|
||||
</fuse-sidebar>
|
||||
<!-- / SIDEBAR -->
|
||||
|
||||
<!-- CENTER -->
|
||||
<div class="center">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24" fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<button mat-icon-button class="sidebar-toggle mr-16" fxHide.gt-md
|
||||
(click)="toggleSidebar('academy-course-left-sidebar-1')">
|
||||
<mat-icon>menu</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-icon-button class="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 -->
|
||||
|
||||
</div>
|
||||
@@ -1,194 +0,0 @@
|
||||
@import "src/@fuse/scss/fuse";
|
||||
|
||||
#academy-course {
|
||||
|
||||
.sidebar {
|
||||
|
||||
.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;
|
||||
overflow: hidden;
|
||||
|
||||
.header {
|
||||
height: 72px;
|
||||
min-height: 72px;
|
||||
max-height: 72px;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
display: flex;
|
||||
background: mat-color($mat-grey, 200);
|
||||
|
||||
.course-step {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: 48px;
|
||||
overflow: auto;
|
||||
|
||||
&.ng-animating {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
import { AfterViewInit, ChangeDetectorRef, Component, OnDestroy, OnInit, QueryList, ViewChildren, ViewEncapsulation } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FusePerfectScrollbarDirective } from '@fuse/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive';
|
||||
import { FuseSidebarService } from '@fuse/components/sidebar/sidebar.service';
|
||||
|
||||
import { AcademyCourseService } from 'app/main/apps/academy/course.service';
|
||||
|
||||
@Component({
|
||||
selector : 'academy-course',
|
||||
templateUrl : './course.component.html',
|
||||
styleUrls : ['./course.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class AcademyCourseComponent implements OnInit, OnDestroy, AfterViewInit
|
||||
{
|
||||
animationDirection: 'left' | 'right' | 'none';
|
||||
course: any;
|
||||
courseStepContent: any;
|
||||
currentStep: number;
|
||||
|
||||
@ViewChildren(FusePerfectScrollbarDirective)
|
||||
fuseScrollbarDirectives: QueryList<FusePerfectScrollbarDirective>;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {AcademyCourseService} _academyCourseService
|
||||
* @param {ChangeDetectorRef} _changeDetectorRef
|
||||
* @param {FuseSidebarService} _fuseSidebarService
|
||||
*/
|
||||
constructor(
|
||||
private _academyCourseService: AcademyCourseService,
|
||||
private _changeDetectorRef: ChangeDetectorRef,
|
||||
private _fuseSidebarService: FuseSidebarService
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.animationDirection = 'none';
|
||||
this.currentStep = 0;
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to courses
|
||||
this._academyCourseService.onCourseChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(course => {
|
||||
this.course = course;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* After view init
|
||||
*/
|
||||
ngAfterViewInit(): void
|
||||
{
|
||||
this.courseStepContent = this.fuseScrollbarDirectives.find((fuseScrollbarDirective) => {
|
||||
return fuseScrollbarDirective.elementRef.nativeElement.id === 'course-step-content';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Go to step
|
||||
*
|
||||
* @param step
|
||||
*/
|
||||
gotoStep(step): void
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to next step
|
||||
*/
|
||||
gotoNextStep(): void
|
||||
{
|
||||
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++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to previous step
|
||||
*/
|
||||
gotoPreviousStep(): void
|
||||
{
|
||||
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--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the sidebar
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
toggleSidebar(name): void
|
||||
{
|
||||
this._fuseSidebarService.getSidebar(name).toggleOpen();
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
|
||||
@Injectable()
|
||||
export class AcademyCoursesService implements Resolve<any>
|
||||
{
|
||||
onCategoriesChanged: BehaviorSubject<any>;
|
||||
onCoursesChanged: BehaviorSubject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {HttpClient} _httpClient
|
||||
*/
|
||||
constructor(
|
||||
private _httpClient: HttpClient
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.onCategoriesChanged = new BehaviorSubject({});
|
||||
this.onCoursesChanged = new BehaviorSubject({});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 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
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get categories
|
||||
*
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
getCategories(): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this._httpClient.get('api/academy-categories')
|
||||
.subscribe((response: any) => {
|
||||
this.onCategoriesChanged.next(response);
|
||||
resolve(response);
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get courses
|
||||
*
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
getCourses(): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this._httpClient.get('api/academy-courses')
|
||||
.subscribe((response: any) => {
|
||||
this.onCoursesChanged.next(response);
|
||||
resolve(response);
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
<div id="academy-courses" class="page-layout simple">
|
||||
|
||||
<!-- 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 [@animate]="{value:'*',params:{delay:'100ms', y:'25px'}}">
|
||||
WELCOME TO ACADEMY
|
||||
</h1>
|
||||
<h3 [@animate]="{value:'*',params:{delay:'100ms', y:'25px'}}">
|
||||
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"
|
||||
(selectionChange)="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 wrap" fxLayoutAlign="center" [@animateStagger]="{value:'50'}">
|
||||
|
||||
<div class="course" *ngFor="let course of filteredCourses" fxFlex="100" fxFlex.gt-xs="50"
|
||||
fxFlex.gt-sm="33" [ngClass]="course.category" [@animate]="{value:'*',params:{y:'100%'}}">
|
||||
|
||||
<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>
|
||||
@@ -1,188 +0,0 @@
|
||||
@import "src/@fuse/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(3);
|
||||
|
||||
.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { AcademyCoursesService } from 'app/main/apps/academy/courses.service';
|
||||
|
||||
@Component({
|
||||
selector : 'academy-courses',
|
||||
templateUrl: './courses.component.html',
|
||||
styleUrls : ['./courses.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class AcademyCoursesComponent implements OnInit, OnDestroy
|
||||
{
|
||||
categories: any[];
|
||||
courses: any[];
|
||||
coursesFilteredByCategory: any[];
|
||||
filteredCourses: any[];
|
||||
currentCategory: string;
|
||||
searchTerm: string;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {AcademyCoursesService} _academyCoursesService
|
||||
*/
|
||||
constructor(
|
||||
private _academyCoursesService: AcademyCoursesService
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.currentCategory = 'all';
|
||||
this.searchTerm = '';
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to categories
|
||||
this._academyCoursesService.onCategoriesChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(categories => {
|
||||
this.categories = categories;
|
||||
});
|
||||
|
||||
// Subscribe to courses
|
||||
this._academyCoursesService.onCoursesChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(courses => {
|
||||
this.filteredCourses = this.coursesFilteredByCategory = this.courses = courses;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Filter courses by category
|
||||
*/
|
||||
filterCoursesByCategory(): void
|
||||
{
|
||||
// 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter courses by term
|
||||
*/
|
||||
filterCoursesByTerm(): void
|
||||
{
|
||||
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);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { FuseSharedModule } from '@fuse/shared.module';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path : 'dashboards/analytics',
|
||||
loadChildren: './dashboards/analytics/analytics.module#AnalyticsDashboardModule'
|
||||
},
|
||||
{
|
||||
path : 'dashboards/project',
|
||||
loadChildren: './dashboards/project/project.module#ProjectDashboardModule'
|
||||
},
|
||||
{
|
||||
path : 'mail',
|
||||
loadChildren: './mail/mail.module#MailModule'
|
||||
},
|
||||
{
|
||||
path : 'mail-ngrx',
|
||||
loadChildren: './mail-ngrx/mail.module#MailNgrxModule'
|
||||
},
|
||||
{
|
||||
path : 'chat',
|
||||
loadChildren: './chat/chat.module#ChatModule'
|
||||
},
|
||||
{
|
||||
path : 'calendar',
|
||||
loadChildren: './calendar/calendar.module#CalendarModule'
|
||||
},
|
||||
{
|
||||
path : 'e-commerce',
|
||||
loadChildren: './e-commerce/e-commerce.module#EcommerceModule'
|
||||
},
|
||||
{
|
||||
path : 'academy',
|
||||
loadChildren: './academy/academy.module#AcademyModule'
|
||||
},
|
||||
{
|
||||
path : 'todo',
|
||||
loadChildren: './todo/todo.module#TodoModule'
|
||||
},
|
||||
{
|
||||
path : 'file-manager',
|
||||
loadChildren: './file-manager/file-manager.module#FileManagerModule'
|
||||
},
|
||||
{
|
||||
path : 'contacts',
|
||||
loadChildren: './contacts/contacts.module#ContactsModule'
|
||||
},
|
||||
{
|
||||
path : 'scrumboard',
|
||||
loadChildren: './scrumboard/scrumboard.module#ScrumboardModule'
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports : [
|
||||
RouterModule.forChild(routes),
|
||||
FuseSharedModule
|
||||
]
|
||||
})
|
||||
export class AppsModule
|
||||
{
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
<div id="calendar" class="page-layout simple fullwidth">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header p-16 p-sm-24" [ngClass]="viewDate | date:'MMM'">
|
||||
|
||||
<div class="header-content" fxLayout="column" fxLayoutAlign="space-between">
|
||||
|
||||
<div class="header-top" fxLayout="row" fxLayoutAlign="space-between center" fxLayout.xs="column">
|
||||
|
||||
<div class="logo mb-16 mb-sm-0" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="logo-icon" [@animate]="{value:'*',params:{delay:'50ms',scale:'0.2'}}">
|
||||
today
|
||||
</mat-icon>
|
||||
<span class="logo-text" [@animate]="{value:'*',params:{delay:'100ms',x:'-25px'}}">
|
||||
Calendar
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- TOOLBAR -->
|
||||
<div class="toolbar" fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<button mat-icon-button aria-label="Search" matTooltip="Search">
|
||||
<mat-icon>search</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-icon-button
|
||||
mwlCalendarToday
|
||||
[(viewDate)]="viewDate"
|
||||
(viewDateChange)="selectedDay = {date:$event}"
|
||||
aria-label="Today" matTooltip="Today">
|
||||
<mat-icon>today</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-icon-button (click)="view='day'" aria-label="Day" matTooltip="Day">
|
||||
<mat-icon>view_day</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-icon-button (click)="view='week'" aria-label="Week" matTooltip="Week">
|
||||
<mat-icon>view_week</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-icon-button (click)="view='month'" aria-label="Month" matTooltip="Month">
|
||||
<mat-icon>view_module</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / TOOLBAR -->
|
||||
|
||||
<!-- HEADER BOTTOM -->
|
||||
<div class="header-bottom" fxLayout="row" fxLayoutAlign="center center"
|
||||
[@animate]="{value:'*',params:{delay:'150ms'}}">
|
||||
|
||||
<button mat-icon-button class="arrow"
|
||||
mwlCalendarPreviousView
|
||||
[view]="view"
|
||||
[(viewDate)]="viewDate"
|
||||
(viewDateChange)="selectedDay = {date:$event}"
|
||||
aria-label="Previous">
|
||||
<mat-icon>chevron_left</mat-icon>
|
||||
</button>
|
||||
|
||||
<div class="title">
|
||||
{{ viewDate | calendarDate:(view + 'ViewTitle'):'en' }}
|
||||
</div>
|
||||
|
||||
<button mat-icon-button class="arrow"
|
||||
mwlCalendarNextView
|
||||
[view]="view"
|
||||
[(viewDate)]="viewDate"
|
||||
(viewDateChange)="selectedDay = {date:$event}"
|
||||
aria-label="Next">
|
||||
<mat-icon>chevron_right</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<!-- / HEADER BOTTOM -->
|
||||
</div>
|
||||
|
||||
<!-- ADD EVENT BUTTON -->
|
||||
<button mat-fab class="add-event-button mat-warn" (click)="addEvent()" aria-label="Add event"
|
||||
[@animate]="{value:'*',params:{delay:'300ms',scale:'0.2'}}">
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
<!-- / ADD EVENT BUTTON -->
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content" fusePerfectScrollbar [@animate]="{value:'*',params:{delay:'200ms',y:'50px'}}">
|
||||
<div [ngSwitch]="view">
|
||||
<mwl-calendar-month-view
|
||||
*ngSwitchCase="'month'"
|
||||
[viewDate]="viewDate"
|
||||
[events]="events"
|
||||
[refresh]="refresh"
|
||||
[activeDayIsOpen]="activeDayIsOpen"
|
||||
(dayClicked)="dayClicked($event.day)"
|
||||
(eventClicked)="editEvent('edit', $event.event)"
|
||||
(eventTimesChanged)="eventTimesChanged($event)"
|
||||
(beforeViewRender)="beforeMonthViewRender($event)">
|
||||
</mwl-calendar-month-view>
|
||||
<mwl-calendar-week-view
|
||||
*ngSwitchCase="'week'"
|
||||
[viewDate]="viewDate"
|
||||
(viewDateChange)="selectedDay = {date:$event}"
|
||||
[events]="events"
|
||||
[refresh]="refresh"
|
||||
(dayClicked)="dayClicked($event.day)"
|
||||
(eventClicked)="editEvent('edit', $event.event)"
|
||||
(eventTimesChanged)="eventTimesChanged($event)">
|
||||
</mwl-calendar-week-view>
|
||||
<mwl-calendar-day-view
|
||||
*ngSwitchCase="'day'"
|
||||
[viewDate]="viewDate"
|
||||
(viewDateChange)="selectedDay = {date:$event}"
|
||||
[events]="events"
|
||||
[refresh]="refresh"
|
||||
(dayClicked)="dayClicked($event.day)"
|
||||
(eventClicked)="editEvent('edit', $event.event)"
|
||||
(eventTimesChanged)="eventTimesChanged($event)">
|
||||
</mwl-calendar-day-view>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / CONTENT -->
|
||||
</div>
|
||||
@@ -1,320 +0,0 @@
|
||||
@import "src/@fuse/scss/fuse";
|
||||
@import "node_modules/angular-calendar/scss/angular-calendar";
|
||||
|
||||
.cal-month-view {
|
||||
|
||||
.cal-header {
|
||||
|
||||
.cal-cell {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.cal-day-cell {
|
||||
|
||||
@include media-breakpoint(lg) {
|
||||
min-height: 150px;
|
||||
}
|
||||
|
||||
@include media-breakpoint(gt-lg) {
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
&.cal-open {
|
||||
@include mat-elevation(3);
|
||||
}
|
||||
}
|
||||
|
||||
.cal-open-day-events {
|
||||
background: #455A64;
|
||||
box-shadow: inset 0 0 12px 0 rgba(0, 0, 0, 0.54);
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
> div {
|
||||
padding: 0 16px;
|
||||
margin: 8px 16px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: start;
|
||||
background-color: white;
|
||||
@include mat-elevation(1);
|
||||
transition: box-shadow 300ms ease;
|
||||
|
||||
&:first-of-type {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@include mat-elevation(3);
|
||||
}
|
||||
|
||||
.cal-event {
|
||||
top: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
mwl-calendar-event-title {
|
||||
flex: 1;
|
||||
|
||||
.cal-event-title {
|
||||
display: block;
|
||||
padding: 21px 24px;
|
||||
line-height: 1;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
|
||||
mwl-calendar-event-actions {
|
||||
|
||||
.cal-event-actions {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.cal-event-action {
|
||||
display: block;
|
||||
line-height: 1;
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cal-week-view {
|
||||
|
||||
.cal-header > b {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.cal-event {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
mwl-calendar-event-title {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
flex: 1;
|
||||
order: 0;
|
||||
|
||||
.cal-event-title {
|
||||
display: block;
|
||||
//padding: 21px 24px;
|
||||
line-height: 1;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
|
||||
mwl-calendar-event-actions {
|
||||
order: 1;
|
||||
|
||||
.cal-event-actions {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.cal-event-action {
|
||||
display: block;
|
||||
line-height: 1;
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cal-day-view {
|
||||
|
||||
.cal-time {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.cal-event {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
mwl-calendar-event-title {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
flex: 1;
|
||||
order: 0;
|
||||
|
||||
.cal-event-title {
|
||||
display: block;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
|
||||
mwl-calendar-event-actions {
|
||||
order: 1;
|
||||
|
||||
.cal-event-actions {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.cal-event-action {
|
||||
display: block;
|
||||
line-height: 1;
|
||||
padding: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cal-hour-segment {
|
||||
|
||||
&:after,
|
||||
&::after {
|
||||
content: '' !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#calendar {
|
||||
background: #FFFFFF;
|
||||
|
||||
.header {
|
||||
height: 200px;
|
||||
min-height: 200px;
|
||||
max-height: 200px;
|
||||
position: relative;
|
||||
background-size: 100% auto;
|
||||
background-position: 0 50%;
|
||||
background-repeat: no-repeat;
|
||||
background-color: #FAFAFA;
|
||||
color: #FFFFFF;
|
||||
|
||||
@include media-breakpoint(xs) {
|
||||
height: 164px;
|
||||
min-height: 164px;
|
||||
max-height: 164px;
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
|
||||
&.Jan {
|
||||
background-image: url('/assets/images/backgrounds/winter.jpg');
|
||||
background-position: 0 85%;
|
||||
}
|
||||
&.Feb {
|
||||
background-image: url('/assets/images/backgrounds/winter.jpg');
|
||||
background-position: 0 85%;
|
||||
}
|
||||
&.Mar {
|
||||
background-image: url('/assets/images/backgrounds/spring.jpg');
|
||||
background-position: 0 40%;
|
||||
}
|
||||
&.Apr {
|
||||
background-image: url('/assets/images/backgrounds/spring.jpg');
|
||||
background-position: 0 40%;
|
||||
}
|
||||
&.May {
|
||||
background-image: url('/assets/images/backgrounds/spring.jpg');
|
||||
background-position: 0 40%;
|
||||
}
|
||||
&.Jun {
|
||||
background-image: url('/assets/images/backgrounds/summer.jpg');
|
||||
background-position: 0 80%;
|
||||
}
|
||||
&.Jul {
|
||||
background-image: url('/assets/images/backgrounds/summer.jpg');
|
||||
background-position: 0 80%;
|
||||
}
|
||||
&.Aug {
|
||||
background-image: url('/assets/images/backgrounds/summer.jpg');
|
||||
background-position: 0 80%;
|
||||
}
|
||||
&.Sep {
|
||||
background-image: url('/assets/images/backgrounds/autumn.jpg');
|
||||
background-position: 0 40%;
|
||||
}
|
||||
&.Oct {
|
||||
background-image: url('/assets/images/backgrounds/autumn.jpg');
|
||||
background-position: 0 40%;
|
||||
}
|
||||
&.Nov {
|
||||
background-image: url('/assets/images/backgrounds/autumn.jpg');
|
||||
background-position: 0 40%;
|
||||
}
|
||||
&.Dec {
|
||||
background-image: url('/assets/images/backgrounds/winter.jpg');
|
||||
background-position: 0 85%;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
height: 100%;
|
||||
|
||||
.header-top {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
.logo {
|
||||
|
||||
.logo-icon {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.header-bottom {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
.title {
|
||||
font-size: 20px;
|
||||
min-width: 160px;
|
||||
text-align: center;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.add-event-button {
|
||||
position: absolute;
|
||||
right: 18px;
|
||||
bottom: -26px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
mat-icon {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 24px;
|
||||
}
|
||||
}
|
||||
@@ -1,275 +0,0 @@
|
||||
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
import { MatDialog, MatDialogRef } from '@angular/material';
|
||||
import { Subject } from 'rxjs';
|
||||
import { startOfDay, isSameDay, isSameMonth } from 'date-fns';
|
||||
import { CalendarEvent, CalendarEventAction, CalendarEventTimesChangedEvent, CalendarMonthViewDay } from 'angular-calendar';
|
||||
|
||||
import { FuseConfirmDialogComponent } from '@fuse/components/confirm-dialog/confirm-dialog.component';
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { CalendarService } from 'app/main/apps/calendar/calendar.service';
|
||||
import { CalendarEventModel } from 'app/main/apps/calendar/event.model';
|
||||
import { CalendarEventFormDialogComponent } from 'app/main/apps/calendar/event-form/event-form.component';
|
||||
|
||||
@Component({
|
||||
selector : 'calendar',
|
||||
templateUrl : './calendar.component.html',
|
||||
styleUrls : ['./calendar.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class CalendarComponent implements OnInit
|
||||
{
|
||||
actions: CalendarEventAction[];
|
||||
activeDayIsOpen: boolean;
|
||||
confirmDialogRef: MatDialogRef<FuseConfirmDialogComponent>;
|
||||
dialogRef: any;
|
||||
events: CalendarEvent[];
|
||||
refresh: Subject<any> = new Subject();
|
||||
selectedDay: any;
|
||||
view: string;
|
||||
viewDate: Date;
|
||||
|
||||
constructor(
|
||||
private _matDialog: MatDialog,
|
||||
private _calendarService: CalendarService
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.view = 'month';
|
||||
this.viewDate = new Date();
|
||||
this.activeDayIsOpen = true;
|
||||
this.selectedDay = {date: startOfDay(new Date())};
|
||||
|
||||
this.actions = [
|
||||
{
|
||||
label : '<i class="material-icons s-16">edit</i>',
|
||||
onClick: ({event}: { event: CalendarEvent }): void => {
|
||||
this.editEvent('edit', event);
|
||||
}
|
||||
},
|
||||
{
|
||||
label : '<i class="material-icons s-16">delete</i>',
|
||||
onClick: ({event}: { event: CalendarEvent }): void => {
|
||||
this.deleteEvent(event);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
/**
|
||||
* Get events from service/server
|
||||
*/
|
||||
this.setEvents();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
/**
|
||||
* Watch re-render-refresh for updating db
|
||||
*/
|
||||
this.refresh.subscribe(updateDB => {
|
||||
if ( updateDB )
|
||||
{
|
||||
this._calendarService.updateEvents(this.events);
|
||||
}
|
||||
});
|
||||
|
||||
this._calendarService.onEventsUpdated.subscribe(events => {
|
||||
this.setEvents();
|
||||
this.refresh.next();
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set events
|
||||
*/
|
||||
setEvents(): void
|
||||
{
|
||||
this.events = this._calendarService.events.map(item => {
|
||||
item.actions = this.actions;
|
||||
return new CalendarEventModel(item);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Before View Renderer
|
||||
*
|
||||
* @param {any} header
|
||||
* @param {any} body
|
||||
*/
|
||||
beforeMonthViewRender({header, body}): void
|
||||
{
|
||||
// console.info('beforeMonthViewRender');
|
||||
/**
|
||||
* Get the selected day
|
||||
*/
|
||||
const _selectedDay = body.find((_day) => {
|
||||
return _day.date.getTime() === this.selectedDay.date.getTime();
|
||||
});
|
||||
|
||||
if ( _selectedDay )
|
||||
{
|
||||
/**
|
||||
* Set selectedday style
|
||||
* @type {string}
|
||||
*/
|
||||
_selectedDay.cssClass = 'mat-elevation-z3';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Day clicked
|
||||
*
|
||||
* @param {MonthViewDay} day
|
||||
*/
|
||||
dayClicked(day: CalendarMonthViewDay): void
|
||||
{
|
||||
const date: Date = day.date;
|
||||
const events: CalendarEvent[] = day.events;
|
||||
|
||||
if ( isSameMonth(date, this.viewDate) )
|
||||
{
|
||||
if ( (isSameDay(this.viewDate, date) && this.activeDayIsOpen === true) || events.length === 0 )
|
||||
{
|
||||
this.activeDayIsOpen = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.activeDayIsOpen = true;
|
||||
this.viewDate = date;
|
||||
}
|
||||
}
|
||||
this.selectedDay = day;
|
||||
this.refresh.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Event times changed
|
||||
* Event dropped or resized
|
||||
*
|
||||
* @param {CalendarEvent} event
|
||||
* @param {Date} newStart
|
||||
* @param {Date} newEnd
|
||||
*/
|
||||
eventTimesChanged({event, newStart, newEnd}: CalendarEventTimesChangedEvent): void
|
||||
{
|
||||
event.start = newStart;
|
||||
event.end = newEnd;
|
||||
// console.warn('Dropped or resized', event);
|
||||
this.refresh.next(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Event
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
deleteEvent(event): void
|
||||
{
|
||||
this.confirmDialogRef = this._matDialog.open(FuseConfirmDialogComponent, {
|
||||
disableClose: false
|
||||
});
|
||||
|
||||
this.confirmDialogRef.componentInstance.confirmMessage = 'Are you sure you want to delete?';
|
||||
|
||||
this.confirmDialogRef.afterClosed().subscribe(result => {
|
||||
if ( result )
|
||||
{
|
||||
const eventIndex = this.events.indexOf(event);
|
||||
this.events.splice(eventIndex, 1);
|
||||
this.refresh.next(true);
|
||||
}
|
||||
this.confirmDialogRef = null;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit Event
|
||||
*
|
||||
* @param {string} action
|
||||
* @param {CalendarEvent} event
|
||||
*/
|
||||
editEvent(action: string, event: CalendarEvent): void
|
||||
{
|
||||
const eventIndex = this.events.indexOf(event);
|
||||
|
||||
this.dialogRef = this._matDialog.open(CalendarEventFormDialogComponent, {
|
||||
panelClass: 'event-form-dialog',
|
||||
data : {
|
||||
event : event,
|
||||
action: action
|
||||
}
|
||||
});
|
||||
|
||||
this.dialogRef.afterClosed()
|
||||
.subscribe(response => {
|
||||
if ( !response )
|
||||
{
|
||||
return;
|
||||
}
|
||||
const actionType: string = response[0];
|
||||
const formData: FormGroup = response[1];
|
||||
switch ( actionType )
|
||||
{
|
||||
/**
|
||||
* Save
|
||||
*/
|
||||
case 'save':
|
||||
|
||||
this.events[eventIndex] = Object.assign(this.events[eventIndex], formData.getRawValue());
|
||||
this.refresh.next(true);
|
||||
|
||||
break;
|
||||
/**
|
||||
* Delete
|
||||
*/
|
||||
case 'delete':
|
||||
|
||||
this.deleteEvent(event);
|
||||
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Event
|
||||
*/
|
||||
addEvent(): void
|
||||
{
|
||||
this.dialogRef = this._matDialog.open(CalendarEventFormDialogComponent, {
|
||||
panelClass: 'event-form-dialog',
|
||||
data : {
|
||||
action: 'new',
|
||||
date : this.selectedDay.date
|
||||
}
|
||||
});
|
||||
this.dialogRef.afterClosed()
|
||||
.subscribe((response: FormGroup) => {
|
||||
if ( !response )
|
||||
{
|
||||
return;
|
||||
}
|
||||
const newEvent = response.getRawValue();
|
||||
newEvent.actions = this.actions;
|
||||
this.events.push(newEvent);
|
||||
this.refresh.next(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { MatButtonModule, MatDatepickerModule, MatDialogModule, MatFormFieldModule, MatIconModule, MatInputModule, MatSlideToggleModule, MatToolbarModule } from '@angular/material';
|
||||
import { ColorPickerModule } from 'ngx-color-picker';
|
||||
import { CalendarModule as AngularCalendarModule } from 'angular-calendar';
|
||||
|
||||
import { FuseSharedModule } from '@fuse/shared.module';
|
||||
import { FuseConfirmDialogModule } from '@fuse/components';
|
||||
|
||||
import { CalendarComponent } from 'app/main/apps/calendar/calendar.component';
|
||||
import { CalendarService } from 'app/main/apps/calendar/calendar.service';
|
||||
import { CalendarEventFormDialogComponent } from 'app/main/apps/calendar/event-form/event-form.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path : '**',
|
||||
component: CalendarComponent,
|
||||
children : [],
|
||||
resolve : {
|
||||
chat: CalendarService
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations : [
|
||||
CalendarComponent,
|
||||
CalendarEventFormDialogComponent
|
||||
],
|
||||
imports : [
|
||||
RouterModule.forChild(routes),
|
||||
|
||||
MatButtonModule,
|
||||
MatDatepickerModule,
|
||||
MatDialogModule,
|
||||
MatFormFieldModule,
|
||||
MatIconModule,
|
||||
MatInputModule,
|
||||
MatSlideToggleModule,
|
||||
MatToolbarModule,
|
||||
|
||||
AngularCalendarModule.forRoot(),
|
||||
ColorPickerModule,
|
||||
|
||||
FuseSharedModule,
|
||||
FuseConfirmDialogModule
|
||||
],
|
||||
providers : [
|
||||
CalendarService
|
||||
],
|
||||
entryComponents: [
|
||||
CalendarEventFormDialogComponent
|
||||
]
|
||||
})
|
||||
export class CalendarModule
|
||||
{
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
|
||||
@Injectable()
|
||||
export class CalendarService implements Resolve<any>
|
||||
{
|
||||
events: any;
|
||||
onEventsUpdated: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {HttpClient} _httpClient
|
||||
*/
|
||||
constructor(
|
||||
private _httpClient: HttpClient
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.onEventsUpdated = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 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.getEvents()
|
||||
]).then(
|
||||
([events]: [any]) => {
|
||||
resolve();
|
||||
},
|
||||
reject
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get events
|
||||
*
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
getEvents(): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
this._httpClient.get('api/calendar/events')
|
||||
.subscribe((response: any) => {
|
||||
this.events = response.data;
|
||||
this.onEventsUpdated.next(this.events);
|
||||
resolve(this.events);
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update events
|
||||
*
|
||||
* @param events
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
updateEvents(events): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this._httpClient.post('api/calendar/events', {
|
||||
id : 'events',
|
||||
data: [...events]
|
||||
})
|
||||
.subscribe((response: any) => {
|
||||
this.getEvents();
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
<div class="dialog-content-wrapper">
|
||||
<mat-toolbar class="mat-accent m-0">
|
||||
<mat-toolbar-row fxFlex fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<span class="title dialog-title">{{dialogTitle}}</span>
|
||||
<button mat-icon-button (click)="matDialogRef.close()" aria-label="Close dialog">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</mat-toolbar-row>
|
||||
</mat-toolbar>
|
||||
|
||||
<div mat-dialog-content class="p-24 m-0" fusePerfectScrollbar>
|
||||
|
||||
<form name="eventForm" [formGroup]="eventForm" class="event-form w-100-p" fxLayout="column" fxFlex>
|
||||
|
||||
<mat-form-field class="w-100-p">
|
||||
<input matInput
|
||||
name="title"
|
||||
formControlName="title"
|
||||
placeholder="Title"
|
||||
required>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="py-16" fxFlex="1 0 auto" fxLayout="row">
|
||||
<mat-slide-toggle
|
||||
name="allDay"
|
||||
formControlName="allDay"
|
||||
class="mr-24"
|
||||
aria-label="All day">
|
||||
All Day
|
||||
</mat-slide-toggle>
|
||||
</div>
|
||||
|
||||
<div class="py-16" fxFlex="1 0 auto" fxLayout="column" fxLayout.gt-xs="row" formGroupName="color">
|
||||
|
||||
<mat-form-field class="mr-sm-24" fxFlex>
|
||||
<input matInput
|
||||
class="primary-color-input"
|
||||
name="primary color"
|
||||
formControlName="primary"
|
||||
placeholder="Primary color"
|
||||
[(colorPicker)]="event.color.primary"
|
||||
cpWidth="290px"
|
||||
[cpPresetColors]="presetColors"
|
||||
[style.background]="event.color.primary"
|
||||
(colorPickerChange)="event.color.primary = $event; eventForm.patchValue({color:{primary:$event}})"/>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex>
|
||||
<input matInput
|
||||
class="secondary-color-input"
|
||||
name="secondary color"
|
||||
formControlName="secondary"
|
||||
placeholder="Secondary color"
|
||||
[(colorPicker)]="event.color.secondary"
|
||||
cpWidth="290px"
|
||||
[cpPresetColors]="presetColors"
|
||||
[style.background]="event.color.secondary"
|
||||
(colorPickerChange)="event.color.secondary = $event; eventForm.patchValue({color:{secondary:$event}})"/>
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
|
||||
<div fxFlex="1 0 auto" fxLayout="column" fxLayout.gt-xs="row">
|
||||
|
||||
<mat-form-field class="mr-sm-24" fxFlex>
|
||||
<input matInput [matDatepicker]="startDatePicker" placeholder="Start Date"
|
||||
name="start"
|
||||
formControlName="start">
|
||||
<mat-datepicker-toggle matSuffix [for]="startDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #startDatePicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="no-errors-spacer" fxFlex mat-no-float>
|
||||
<input matInput placeholder="Start Time">
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
|
||||
<div fxFlex="1 0 auto" fxLayout="column" fxLayout.gt-xs="row">
|
||||
|
||||
<mat-form-field class="mr-sm-24" fxFlex>
|
||||
<input matInput [matDatepicker]="endDatePicker" placeholder="End Date"
|
||||
name="end"
|
||||
formControlName="end">
|
||||
<mat-datepicker-toggle matSuffix [for]="endDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #endDatePicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="no-errors-spacer" fxFlex mat-no-float>
|
||||
<input matInput placeholder="End Time">
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
|
||||
<mat-form-field formGroupName="meta" class="w-100-p">
|
||||
<input matInput
|
||||
name="location"
|
||||
formControlName="location"
|
||||
placeholder="Location">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field formGroupName="meta" class="w-100-p">
|
||||
|
||||
<textarea matInput
|
||||
formControlName="notes"
|
||||
placeholder="Notes"
|
||||
mat-maxlength="250"
|
||||
max-rows="4">
|
||||
</textarea>
|
||||
</mat-form-field>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<div mat-dialog-actions class="m-0 p-16" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
|
||||
<button *ngIf="action !=='edit'"
|
||||
mat-raised-button
|
||||
(click)="_matDialogRef.close(eventForm)"
|
||||
class="save-button mat-accent"
|
||||
[disabled]="eventForm.invalid"
|
||||
aria-label="SAVE">
|
||||
SAVE
|
||||
</button>
|
||||
|
||||
<button *ngIf="action ==='edit'"
|
||||
mat-raised-button
|
||||
(click)="_matDialogRef.close(['save',eventForm])"
|
||||
class="save-button mat-accent"
|
||||
[disabled]="eventForm.invalid"
|
||||
aria-label="SAVE">
|
||||
SAVE
|
||||
</button>
|
||||
|
||||
<button *ngIf="action ==='edit'"
|
||||
mat-icon-button
|
||||
(click)="_matDialogRef.close(['delete',eventForm])"
|
||||
aria-label="Delete"
|
||||
matTooltip="Delete">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,27 +0,0 @@
|
||||
@import "src/@fuse/scss/fuse";
|
||||
|
||||
.event-form-dialog {
|
||||
|
||||
@include media-breakpoint('xs') {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up('xs') {
|
||||
width: 480px;
|
||||
}
|
||||
|
||||
.mat-dialog-container {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.dialog-content-wrapper {
|
||||
max-height: 85vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.primary-color-input,
|
||||
.secondary-color-input {
|
||||
padding: 6px 8px;
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
import { Component, Inject, ViewEncapsulation } from '@angular/core';
|
||||
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
|
||||
import { CalendarEvent } from 'angular-calendar';
|
||||
|
||||
import { MatColors } from '@fuse/mat-colors';
|
||||
|
||||
import { CalendarEventModel } from 'app/main/apps/calendar/event.model';
|
||||
|
||||
@Component({
|
||||
selector : 'calendar-event-form-dialog',
|
||||
templateUrl : './event-form.component.html',
|
||||
styleUrls : ['./event-form.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
|
||||
export class CalendarEventFormDialogComponent
|
||||
{
|
||||
action: string;
|
||||
event: CalendarEvent;
|
||||
eventForm: FormGroup;
|
||||
dialogTitle: string;
|
||||
presetColors = MatColors.presets;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {MatDialogRef<CalendarEventFormDialogComponent>} matDialogRef
|
||||
* @param _data
|
||||
* @param {FormBuilder} _formBuilder
|
||||
*/
|
||||
constructor(
|
||||
public matDialogRef: MatDialogRef<CalendarEventFormDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) private _data: any,
|
||||
private _formBuilder: FormBuilder
|
||||
)
|
||||
{
|
||||
this.event = _data.event;
|
||||
this.action = _data.action;
|
||||
|
||||
if ( this.action === 'edit' )
|
||||
{
|
||||
this.dialogTitle = this.event.title;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.dialogTitle = 'New Event';
|
||||
this.event = new CalendarEventModel({
|
||||
start: _data.date,
|
||||
end : _data.date
|
||||
});
|
||||
}
|
||||
|
||||
this.eventForm = this.createEventForm();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create the event form
|
||||
*
|
||||
* @returns {FormGroup}
|
||||
*/
|
||||
createEventForm(): FormGroup
|
||||
{
|
||||
return new FormGroup({
|
||||
title : new FormControl(this.event.title),
|
||||
start : new FormControl(this.event.start),
|
||||
end : new FormControl(this.event.end),
|
||||
allDay: new FormControl(this.event.allDay),
|
||||
color : this._formBuilder.group({
|
||||
primary : new FormControl(this.event.color.primary),
|
||||
secondary: new FormControl(this.event.color.secondary)
|
||||
}),
|
||||
meta :
|
||||
this._formBuilder.group({
|
||||
location: new FormControl(this.event.meta.location),
|
||||
notes : new FormControl(this.event.meta.notes)
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
import { CalendarEventAction } from 'angular-calendar';
|
||||
import { startOfDay, endOfDay } from 'date-fns';
|
||||
|
||||
export class CalendarEventModel
|
||||
{
|
||||
start: Date;
|
||||
end?: Date;
|
||||
title: string;
|
||||
color: {
|
||||
primary: string;
|
||||
secondary: string;
|
||||
};
|
||||
actions?: CalendarEventAction[];
|
||||
allDay?: boolean;
|
||||
cssClass?: string;
|
||||
resizable?: {
|
||||
beforeStart?: boolean;
|
||||
afterEnd?: boolean;
|
||||
};
|
||||
draggable?: boolean;
|
||||
meta?: {
|
||||
location: string,
|
||||
notes: string
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param data
|
||||
*/
|
||||
constructor(data?)
|
||||
{
|
||||
data = data || {};
|
||||
this.start = new Date(data.start) || startOfDay(new Date());
|
||||
this.end = new Date(data.end) || endOfDay(new Date());
|
||||
this.title = data.title || '';
|
||||
this.color = {
|
||||
primary : data.color && data.color.primary || '#1e90ff',
|
||||
secondary: data.color && data.color.secondary || '#D1E8FF'
|
||||
};
|
||||
this.draggable = data.draggable || true;
|
||||
this.resizable = {
|
||||
beforeStart: data.resizable && data.resizable.beforeStart || true,
|
||||
afterEnd : data.resizable && data.resizable.afterEnd || true
|
||||
};
|
||||
this.actions = data.actions || [];
|
||||
this.allDay = data.allDay || false;
|
||||
this.cssClass = data.cssClass || '';
|
||||
this.meta = {
|
||||
location: data.meta && data.meta.location || '',
|
||||
notes : data.meta && data.meta.notes || ''
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
<div fxFlex fxLayout="column" fxLayoutAlign="center center">
|
||||
|
||||
<div class="big-circle mat-elevation-z1 app-logo" fxLayout="column" fxLayoutAlign="center center"
|
||||
[@animate]="{value:'*',params:{delay:'50ms',scale:'0.2'}}">
|
||||
|
||||
<mat-icon class="s-64 s-mat-128 mat-accent">chat</mat-icon>
|
||||
|
||||
</div>
|
||||
|
||||
<span class="app-title my-24" [@animate]="{value:'*',params:{delay:'100ms',y:'25px'}}">Chat App</span>
|
||||
|
||||
<span fxHide fxShow.gt-md class="app-message" [@animate]="{value:'*',params:{delay:'200ms',y:'50px'}}">
|
||||
Select contact to start the chat!..
|
||||
</span>
|
||||
|
||||
<button mat-raised-button fxHide.gt-md fuseMatSidenavToggler="chat-left-sidenav">
|
||||
Select contact to start the chat!..
|
||||
</button>
|
||||
|
||||
</div>
|
||||
@@ -1,31 +0,0 @@
|
||||
@import "src/@fuse/scss/fuse";
|
||||
|
||||
:host {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
background: linear-gradient(to bottom, rgba(255, 255, 255, 0.8) 0%, rgba(255, 255, 255, 0.6) 20%, rgba(255, 255, 255, 0.8));
|
||||
|
||||
.big-circle {
|
||||
background: linear-gradient(to bottom, rgba(255, 255, 255, 0.8) 0%, rgba(255, 255, 255, 0.6) 20%, rgba(255, 255, 255, 0.8));
|
||||
border-radius: 50%;
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
line-height: 300px;
|
||||
text-align: center;
|
||||
|
||||
@include media-breakpoint-down('sm') {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
line-height: 160px;
|
||||
}
|
||||
}
|
||||
|
||||
.app-title {
|
||||
font-weight: 500;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.secondary-text {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
@Component({
|
||||
selector : 'chat-start',
|
||||
templateUrl: './chat-start.component.html',
|
||||
styleUrls : ['./chat-start.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class ChatStartComponent
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
<!-- CHAT -->
|
||||
<div class="chat" fxFlex fxLayout="column">
|
||||
|
||||
<!-- CHAT TOOLBAR -->
|
||||
<mat-toolbar class="chat-toolbar">
|
||||
|
||||
<div fxFlex fxLayout="row" fxLayoutAlign="space-between center">
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<!-- RESPONSIVE CHATS BUTTON-->
|
||||
<button mat-icon-button fxHide.gt-md class="responsive-chats-button mr-16"
|
||||
fuseMatSidenavToggler="chat-left-sidenav"
|
||||
aria-label="chats button">
|
||||
<mat-icon>chat</mat-icon>
|
||||
</button>
|
||||
<!-- / RESPONSIVE CHATS BUTTON-->
|
||||
|
||||
<!-- CHAT CONTACT-->
|
||||
<div class="chat-contact" fxLayout="row" fxLayoutAlign="start center"
|
||||
fuseMatSidenavToggler="chat-right-sidenav" (click)="selectContact()">
|
||||
|
||||
<div class="avatar-wrapper">
|
||||
|
||||
<img [src]="contact.avatar"
|
||||
class="avatar"
|
||||
alt="{{contact.name}}"/>
|
||||
|
||||
<mat-icon class="s-16 status"
|
||||
[ngClass]="contact.status">
|
||||
</mat-icon>
|
||||
</div>
|
||||
|
||||
<div class="chat-contact-name">
|
||||
{{contact.name}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / CHAT CONTACT-->
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button mat-icon-button [matMenuTriggerFor]="contactMenu" aria-label="more">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
|
||||
<mat-menu #contactMenu="matMenu">
|
||||
<button mat-menu-item fuseMatSidenavToggler="chat-right-sidenav" (click)="selectContact()">
|
||||
Contact Info
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</mat-toolbar>
|
||||
<!-- / CHAT TOOLBAR -->
|
||||
|
||||
<!-- CHAT CONTENT -->
|
||||
<div id="chat-content" fxFlex fusePerfectScrollbar>
|
||||
|
||||
<!-- CHAT MESSAGES -->
|
||||
<div class="chat-messages">
|
||||
|
||||
<!-- MESSAGE -->
|
||||
<div fxLayout="row" *ngFor="let message of dialog" class="message-row"
|
||||
[ngClass]="{'user' :message.who === user.id}">
|
||||
|
||||
<img *ngIf="message.who === contact.id"
|
||||
src="{{contact.avatar}}"
|
||||
class="avatar"
|
||||
alt="{{contact.name}}"/>
|
||||
|
||||
<img *ngIf="message.who ===user.id" class="avatar" src="{{user.avatar}}">
|
||||
|
||||
<div class="bubble">
|
||||
<div class="message">{{message.message}}</div>
|
||||
<div class="time secondary-text">{{message.time | date:'medium'}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / MESSAGE -->
|
||||
|
||||
</div>
|
||||
<!-- CHAT MESSAGES -->
|
||||
|
||||
</div>
|
||||
<!-- / CHAT CONTENT -->
|
||||
|
||||
<!-- CHAT FOOTER -->
|
||||
<div class="chat-footer" fxFlex="1 0 auto" fxLayout="row" fxLayoutAlign="center center">
|
||||
|
||||
<!-- REPLY FORM -->
|
||||
<form #replyForm="ngForm"
|
||||
(ngSubmit)="reply()"
|
||||
(keyup.enter)="reply()"
|
||||
fxFlex class="reply-form"
|
||||
fxLayout="row"
|
||||
fxLayoutAlign="start center">
|
||||
|
||||
<mat-form-field fxFlex floatLabel="never">
|
||||
<textarea matInput #replyInput placeholder="Type and hit enter to send message"
|
||||
ngModel name="message"></textarea>
|
||||
</mat-form-field>
|
||||
|
||||
<button mat-fab type="submit" aria-label="Send message">
|
||||
<mat-icon>send</mat-icon>
|
||||
</button>
|
||||
|
||||
</form>
|
||||
<!-- / REPLY FORM -->
|
||||
|
||||
</div>
|
||||
<!-- / CHAT FOOTER-->
|
||||
|
||||
</div>
|
||||
<!-- / CHAT -->
|
||||
@@ -1,136 +0,0 @@
|
||||
:host {
|
||||
display: flex;
|
||||
flex: 1 0 auto;
|
||||
background: linear-gradient(to bottom, rgba(255, 255, 255, 0.8) 0%, rgba(255, 255, 255, 0.6) 20%, rgba(255, 255, 255, 0.8));
|
||||
overflow: hidden;
|
||||
max-width: 100%;
|
||||
|
||||
.chat {
|
||||
|
||||
.chat-toolbar {
|
||||
min-height: 64px;
|
||||
background-color: #F3F4F5;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, .08);
|
||||
|
||||
.responsive-chats-button {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.chat-contact {
|
||||
cursor: pointer;
|
||||
|
||||
.avatar {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.chat-contact-name {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#chat-content {
|
||||
background: transparent;
|
||||
overflow: auto;
|
||||
|
||||
.message-row {
|
||||
padding: 16px;
|
||||
|
||||
.bubble {
|
||||
position: relative;
|
||||
padding: 6px 7px 8px 9px;
|
||||
background-color: #FFF;
|
||||
box-shadow: 0 1px .5px rgba(0, 0, 0, .13);
|
||||
border-radius: 6px;
|
||||
|
||||
&:before {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAmCAMAAADp2asXAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAADGUExURQAAAP////b29vn5+f///wAAAP///wAAAAAAAP///9ra2v////j4+PHx8fv7++Hh4fHx8f////////////////39/QAAAP////////z8/P////39/f39/fz8/P////////////z8/P////////////z8/P////////////v7+/Hx8f///9bW1vz8/K2trf////39/f39/WJiYgAAAExMTFtbWwAAAN3d3cjIyPr6+vX19QAAAO7u7vz8/NTU1Ofn5zMzM////zGPlXsAAABBdFJOUwAcm/kREh4CCDWL1SneR6TfAQffhMYK/A5nRrLWfRc5DW2ih5f+19Kn+9v4g/1LCJuXHwQUKgahcXS6DNnlDMMKKzPoTgAAAKBJREFUKM+V08USwmAQA+C/0NIWd3d3d8/7vxTMcIPkQK7f7CG7s8bQAOY/SCuwFYQU1P+eiCqIK2gpWCmoCrAgoKQgJ8CHgIqAMjg0MxxSQ3DogEMWFBZtUPAHYGB1CyDQWE6AH7BrfXzlAxGAQhECTGAmwN1Okz0Gb/LW4fEItIfrOfNELMh3tck7u+PhcT2zQ7l77/K8iY8yJwV3BeYFqpc/uSyPGdAAAAAASUVORK5CYII=);
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -11px;
|
||||
bottom: 3px;
|
||||
width: 12px;
|
||||
height: 19px;
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.message {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.time {
|
||||
font-size: 11px;
|
||||
margin-top: 8px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
&.contact {
|
||||
|
||||
.avatar {
|
||||
margin: 0 16px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.user {
|
||||
align-items: flex-end;
|
||||
|
||||
.avatar {
|
||||
order: 2;
|
||||
margin: 0 0 0 16px;
|
||||
}
|
||||
|
||||
.bubble {
|
||||
margin-left: auto;
|
||||
background-color: #E8F5E9;
|
||||
border: 1px solid #DFEBE0;
|
||||
order: 1;
|
||||
&:before {
|
||||
right: -11px;
|
||||
left: auto;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAmCAMAAADp2asXAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAD2UExURQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRsXAAAANzwzNPmxNrtyau5oIWRedDkwNntyczgwdfpyJ+/n97wzsLWtNjsytvwzczfvtPmxau6nNjqxtrtyio1KtzwzNjryAAAANzwzgAAANzwzK7Aor/Us9Lnw8vevAAAAMzevtbpxrvMrX+IdwAAAEROOi45Lr3MrZGjf9LoxX+MctnqydLkwhgYGMzfv9vuyQAAANzwzNvuy9zxy7vMu7XGqNvtzKKykwAAANruzKq6nLnMriQkGMXXuL3PsNjsySgzKAAAANLkw83fvd3vy9z4xtzwzRpFmIEAAABQdFJOUwAXChEGBAMBAgwhDvJ7k0YqMc0Zmwj6apf2kjU0+dkw/swh/CP9j2Wr2gndvaYeBRoxQg6gUPt/FaHJGdTj9A9k7XQLeE6iFcN12xkSt9r4NKizowAAAMFJREFUKM+V0sdywlAMBVDbMX7PQCihQ+iQ0HsJvfem/P/PwBIzugu0PXNnNNJVyPmhsIPhhoB2COwIGuLdhAcl3AhCBoBoHUC6BCBbA0C/EkBFB5D/FjxQwQYg1RI8UKINgDoSAPUlAPqUAMgfAEBfXsEDBV0+Hogi4Zhg4THj9YwHoqEBYOrgYTI3GVgMNn8r+Qq94k9yZNosW/3Hy9VuTjWfHkOX6367bGZUU7de66ieHZrO1OGg8Z1WTgYAFLgD5S1PCkzo1B0AAAAASUVORK5CYII=);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chat-footer {
|
||||
min-height: 72px;
|
||||
max-height: 96px;
|
||||
background-color: #F3F4F5;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
border-top: 1px solid rgba(0, 0, 0, .08);
|
||||
padding: 8px 8px 8px 16px;
|
||||
|
||||
.reply-form {
|
||||
|
||||
mat-form-field {
|
||||
margin: 0;
|
||||
padding-right: 16px;
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
max-height: 80px;
|
||||
transition: height 200ms ease;
|
||||
|
||||
&.grow {
|
||||
height: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-errors-spacer {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-button {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
import { AfterViewInit, Component, OnDestroy, OnInit, ViewChild, ViewChildren } from '@angular/core';
|
||||
import { NgForm } from '@angular/forms';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { FusePerfectScrollbarDirective } from '@fuse/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive';
|
||||
|
||||
import { ChatService } from 'app/main/apps/chat/chat.service';
|
||||
|
||||
@Component({
|
||||
selector : 'chat-view',
|
||||
templateUrl: './chat-view.component.html',
|
||||
styleUrls : ['./chat-view.component.scss']
|
||||
})
|
||||
export class ChatViewComponent implements OnInit, OnDestroy, AfterViewInit
|
||||
{
|
||||
user: any;
|
||||
chat: any;
|
||||
dialog: any;
|
||||
contact: any;
|
||||
replyInput: any;
|
||||
selectedChat: any;
|
||||
|
||||
@ViewChild(FusePerfectScrollbarDirective)
|
||||
directiveScroll: FusePerfectScrollbarDirective;
|
||||
|
||||
@ViewChildren('replyInput')
|
||||
replyInputField;
|
||||
|
||||
@ViewChild('replyForm')
|
||||
replyForm: NgForm;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ChatService} _chatService
|
||||
*/
|
||||
constructor(
|
||||
private _chatService: ChatService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.user = this._chatService.user;
|
||||
this._chatService.onChatSelected
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(chatData => {
|
||||
if ( chatData )
|
||||
{
|
||||
this.selectedChat = chatData;
|
||||
this.contact = chatData.contact;
|
||||
this.dialog = chatData.dialog;
|
||||
this.readyToReply();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* After view init
|
||||
*/
|
||||
ngAfterViewInit(): void
|
||||
{
|
||||
this.replyInput = this.replyInputField.first.nativeElement;
|
||||
this.readyToReply();
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Select contact
|
||||
*/
|
||||
selectContact(): void
|
||||
{
|
||||
this._chatService.selectContact(this.contact);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ready to reply
|
||||
*/
|
||||
readyToReply(): void
|
||||
{
|
||||
setTimeout(() => {
|
||||
this.replyForm.reset();
|
||||
this.focusReplyInput();
|
||||
this.scrollToBottom();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus to the reply input
|
||||
*/
|
||||
focusReplyInput(): void
|
||||
{
|
||||
setTimeout(() => {
|
||||
this.replyInput.focus();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Scroll to the bottom
|
||||
*
|
||||
* @param {number} speed
|
||||
*/
|
||||
scrollToBottom(speed?: number): void
|
||||
{
|
||||
speed = speed || 400;
|
||||
if ( this.directiveScroll )
|
||||
{
|
||||
this.directiveScroll.update();
|
||||
|
||||
setTimeout(() => {
|
||||
this.directiveScroll.scrollToBottom(0, speed);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reply
|
||||
*/
|
||||
reply(): void
|
||||
{
|
||||
// Message
|
||||
const message = {
|
||||
who : this.user.id,
|
||||
message: this.replyForm.form.value.message,
|
||||
time : new Date().toISOString()
|
||||
};
|
||||
|
||||
// Add the message to the chat
|
||||
this.dialog.push(message);
|
||||
|
||||
// Update the server
|
||||
this._chatService.updateDialog(this.selectedChat.chatId, this.dialog).then(response => {
|
||||
this.readyToReply();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
<div id="chat" class="page-layout carded fullwidth">
|
||||
|
||||
<!-- TOP BACKGROUND -->
|
||||
<div class="top-bg mat-accent-bg"></div>
|
||||
<!-- / TOP BACKGROUND -->
|
||||
|
||||
<!-- CENTER -->
|
||||
<div class="center">
|
||||
|
||||
<!-- CONTENT CARD -->
|
||||
<div class="content-card">
|
||||
|
||||
<mat-sidenav-container>
|
||||
|
||||
<!-- LEFT SIDENAV -->
|
||||
<mat-sidenav class="sidenav" position="start" opened="true" mode="side"
|
||||
fuseMatSidenavHelper="chat-left-sidenav" mat-is-locked-open="gt-md">
|
||||
<chat-left-sidenav></chat-left-sidenav>
|
||||
</mat-sidenav>
|
||||
<!-- / LEFT SIDENAV -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<chat-start *ngIf="!selectedChat"></chat-start>
|
||||
|
||||
<chat-view *ngIf="selectedChat"></chat-view>
|
||||
<!-- / CONTENT -->
|
||||
|
||||
<!-- RIGHT SIDENAV -->
|
||||
<mat-sidenav class="sidenav" position="end" opened="false" mode="over"
|
||||
fuseMatSidenavHelper="chat-right-sidenav">
|
||||
<chat-right-sidenav></chat-right-sidenav>
|
||||
</mat-sidenav>
|
||||
<!-- / RIGHT SIDENAV -->
|
||||
|
||||
</mat-sidenav-container>
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT CARD -->
|
||||
|
||||
</div>
|
||||
<!-- / CENTER -->
|
||||
|
||||
</div>
|
||||
@@ -1,51 +0,0 @@
|
||||
@import "src/@fuse/scss/fuse";
|
||||
|
||||
#chat {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
|
||||
.center {
|
||||
padding: 32px !important;
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.content-card {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
position: relative;
|
||||
background: url('/assets/images/patterns/rain-grey.png') repeat;
|
||||
|
||||
.mat-sidenav-container {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
background: transparent;
|
||||
|
||||
> .mat-sidenav-content,
|
||||
> .mat-drawer-content {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
min-height: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
> .mat-drawer-content {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
mat-sidenav {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 400px;
|
||||
max-width: 90%;
|
||||
box-shadow: 0 0 1px rgba(0, 0, 0, .37);
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { ChatService } from 'app/main/apps/chat/chat.service';
|
||||
|
||||
@Component({
|
||||
selector : 'chat',
|
||||
templateUrl : './chat.component.html',
|
||||
styleUrls : ['./chat.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class ChatComponent implements OnInit, OnDestroy
|
||||
{
|
||||
selectedChat: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ChatService} _chatService
|
||||
*/
|
||||
constructor(
|
||||
private _chatService: ChatService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._chatService.onChatSelected
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(chatData => {
|
||||
this.selectedChat = chatData;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { MatButtonModule, MatCardModule, MatFormFieldModule, MatIconModule, MatInputModule, MatListModule, MatMenuModule, MatRadioModule, MatSidenavModule, MatToolbarModule } from '@angular/material';
|
||||
|
||||
import { FuseSharedModule } from '@fuse/shared.module';
|
||||
|
||||
import { ChatService } from 'app/main/apps/chat/chat.service';
|
||||
import { ChatComponent } from 'app/main/apps/chat/chat.component';
|
||||
import { ChatStartComponent } from 'app/main/apps/chat/chat-start/chat-start.component';
|
||||
import { ChatViewComponent } from 'app/main/apps/chat/chat-view/chat-view.component';
|
||||
import { ChatChatsSidenavComponent } from 'app/main/apps/chat/sidenavs/left/chats/chats.component';
|
||||
import { ChatUserSidenavComponent } from 'app/main/apps/chat/sidenavs/left/user/user.component';
|
||||
import { ChatLeftSidenavComponent } from 'app/main/apps/chat/sidenavs/left/left.component';
|
||||
import { ChatRightSidenavComponent } from 'app/main/apps/chat/sidenavs/right/right.component';
|
||||
import { ChatContactSidenavComponent } from 'app/main/apps/chat/sidenavs/right/contact/contact.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path : '**',
|
||||
component: ChatComponent,
|
||||
children : [],
|
||||
resolve : {
|
||||
chat: ChatService
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
ChatComponent,
|
||||
ChatViewComponent,
|
||||
ChatStartComponent,
|
||||
ChatChatsSidenavComponent,
|
||||
ChatUserSidenavComponent,
|
||||
ChatLeftSidenavComponent,
|
||||
ChatRightSidenavComponent,
|
||||
ChatContactSidenavComponent
|
||||
],
|
||||
imports : [
|
||||
RouterModule.forChild(routes),
|
||||
|
||||
MatButtonModule,
|
||||
MatCardModule,
|
||||
MatFormFieldModule,
|
||||
MatIconModule,
|
||||
MatInputModule,
|
||||
MatListModule,
|
||||
MatMenuModule,
|
||||
MatRadioModule,
|
||||
MatSidenavModule,
|
||||
MatToolbarModule,
|
||||
|
||||
FuseSharedModule
|
||||
],
|
||||
providers : [
|
||||
ChatService
|
||||
]
|
||||
})
|
||||
export class ChatModule
|
||||
{
|
||||
}
|
||||
@@ -1,270 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||
import { BehaviorSubject, Observable, Subject } from 'rxjs';
|
||||
|
||||
import { FuseUtils } from '@fuse/utils';
|
||||
|
||||
@Injectable()
|
||||
export class ChatService implements Resolve<any>
|
||||
{
|
||||
contacts: any[];
|
||||
chats: any[];
|
||||
user: any;
|
||||
onChatSelected: BehaviorSubject<any>;
|
||||
onContactSelected: BehaviorSubject<any>;
|
||||
onChatsUpdated: Subject<any>;
|
||||
onUserUpdated: Subject<any>;
|
||||
onLeftSidenavViewChanged: Subject<any>;
|
||||
onRightSidenavViewChanged: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {HttpClient} _httpClient
|
||||
*/
|
||||
constructor(
|
||||
private _httpClient: HttpClient
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.onChatSelected = new BehaviorSubject(null);
|
||||
this.onContactSelected = new BehaviorSubject(null);
|
||||
this.onChatsUpdated = new Subject();
|
||||
this.onUserUpdated = new Subject();
|
||||
this.onLeftSidenavViewChanged = new Subject();
|
||||
this.onRightSidenavViewChanged = new Subject();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.getContacts(),
|
||||
this.getChats(),
|
||||
this.getUser()
|
||||
]).then(
|
||||
([contacts, chats, user]) => {
|
||||
this.contacts = contacts;
|
||||
this.chats = chats;
|
||||
this.user = user;
|
||||
resolve();
|
||||
},
|
||||
reject
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get chat
|
||||
*
|
||||
* @param contactId
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
getChat(contactId): Promise<any>
|
||||
{
|
||||
const chatItem = this.user.chatList.find((item) => {
|
||||
return item.contactId === contactId;
|
||||
});
|
||||
|
||||
/**
|
||||
* Create new chat, if it's not created yet.
|
||||
*/
|
||||
if ( !chatItem )
|
||||
{
|
||||
this.createNewChat(contactId).then((newChats) => {
|
||||
this.getChat(contactId);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this._httpClient.get('api/chat-chats/' + chatItem.id)
|
||||
.subscribe((response: any) => {
|
||||
const chat = response;
|
||||
|
||||
const chatContact = this.contacts.find((contact) => {
|
||||
return contact.id === contactId;
|
||||
});
|
||||
|
||||
const chatData = {
|
||||
chatId : chat.id,
|
||||
dialog : chat.dialog,
|
||||
contact: chatContact
|
||||
};
|
||||
|
||||
this.onChatSelected.next({...chatData});
|
||||
|
||||
}, reject);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new chat
|
||||
*
|
||||
* @param contactId
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
createNewChat(contactId): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
const contact = this.contacts.find((item) => {
|
||||
return item.id === contactId;
|
||||
});
|
||||
|
||||
const chatId = FuseUtils.generateGUID();
|
||||
|
||||
const chat = {
|
||||
id : chatId,
|
||||
dialog: []
|
||||
};
|
||||
|
||||
const chatListItem = {
|
||||
contactId : contactId,
|
||||
id : chatId,
|
||||
lastMessageTime: '2017-02-18T10:30:18.931Z',
|
||||
name : contact.name,
|
||||
unread : null
|
||||
};
|
||||
|
||||
/**
|
||||
* Add new chat list item to the user's chat list
|
||||
*/
|
||||
this.user.chatList.push(chatListItem);
|
||||
|
||||
/**
|
||||
* Post the created chat
|
||||
*/
|
||||
this._httpClient.post('api/chat-chats', {...chat})
|
||||
.subscribe((response: any) => {
|
||||
|
||||
/**
|
||||
* Post the new the user data
|
||||
*/
|
||||
this._httpClient.post('api/chat-user/' + this.user.id, this.user)
|
||||
.subscribe(newUserData => {
|
||||
|
||||
/**
|
||||
* Update the user data from server
|
||||
*/
|
||||
this.getUser().then(updatedUser => {
|
||||
this.onUserUpdated.next(updatedUser);
|
||||
resolve(updatedUser);
|
||||
});
|
||||
});
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Select contact
|
||||
*
|
||||
* @param contact
|
||||
*/
|
||||
selectContact(contact): void
|
||||
{
|
||||
this.onContactSelected.next(contact);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set user status
|
||||
*
|
||||
* @param status
|
||||
*/
|
||||
setUserStatus(status): void
|
||||
{
|
||||
this.user.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user data
|
||||
*
|
||||
* @param userData
|
||||
*/
|
||||
updateUserData(userData): void
|
||||
{
|
||||
this._httpClient.post('api/chat-user/' + this.user.id, userData)
|
||||
.subscribe((response: any) => {
|
||||
this.user = userData;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the chat dialog
|
||||
*
|
||||
* @param chatId
|
||||
* @param dialog
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
updateDialog(chatId, dialog): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
const newData = {
|
||||
id : chatId,
|
||||
dialog: dialog
|
||||
};
|
||||
|
||||
this._httpClient.post('api/chat-chats/' + chatId, newData)
|
||||
.subscribe(updatedChat => {
|
||||
resolve(updatedChat);
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get contacts
|
||||
*
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
getContacts(): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this._httpClient.get('api/chat-contacts')
|
||||
.subscribe((response: any) => {
|
||||
resolve(response);
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get chats
|
||||
*
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
getChats(): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this._httpClient.get('api/chat-chats')
|
||||
.subscribe((response: any) => {
|
||||
resolve(response);
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user
|
||||
*
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
getUser(): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this._httpClient.get('api/chat-user')
|
||||
.subscribe((response: any) => {
|
||||
resolve(response[0]);
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,185 +0,0 @@
|
||||
<!-- SIDENAV HEADER -->
|
||||
<div class="sidenav-header">
|
||||
<!-- CHATS TOOLBAR -->
|
||||
<mat-toolbar>
|
||||
|
||||
<!-- TOOLBAR TOP -->
|
||||
<mat-toolbar-row fxLayout="row" fxLayoutAlign="space-between center">
|
||||
|
||||
<!-- USER AVATAR WRAPPER -->
|
||||
<div class="avatar-wrapper">
|
||||
|
||||
<!-- USER AVATAR -->
|
||||
<img (click)="changeLeftSidenavView('user')"
|
||||
src="{{user.avatar}}"
|
||||
class="mat-avatar avatar"
|
||||
alt="{{user.name}}"/>
|
||||
<!-- / USER AVATAR -->
|
||||
|
||||
<mat-icon class="s-16 status" [ngClass]="user.status"
|
||||
[matMenuTriggerFor]="userStatusMenu"></mat-icon>
|
||||
|
||||
<!-- USER STATUS -->
|
||||
<mat-menu id="user-status-menu" #userStatusMenu="matMenu">
|
||||
|
||||
<button mat-menu-item (click)="setUserStatus('online')">
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="s-16 status online"></mat-icon>
|
||||
<span>Online</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button mat-menu-item (click)="setUserStatus('away')">
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="s-16 status away"></mat-icon>
|
||||
<span>Away</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button mat-menu-item (click)="setUserStatus('do-not-disturb')">
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="s-16 status do-not-disturb"></mat-icon>
|
||||
<span>Do not disturb</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button mat-menu-item (click)="setUserStatus('offline')">
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="s-16 status offline"></mat-icon>
|
||||
<span>Offline</span>
|
||||
</div>
|
||||
</button>
|
||||
</mat-menu>
|
||||
<!-- / USER STATUS -->
|
||||
|
||||
</div>
|
||||
<!-- / USER AVATAR -->
|
||||
|
||||
<div>
|
||||
<button mat-icon-button
|
||||
[matMenuTriggerFor]="userMenu"
|
||||
aria-label="more">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
<mat-menu #userMenu="matMenu">
|
||||
<button mat-menu-item (click)="changeLeftSidenavView('user')">
|
||||
Profile
|
||||
</button>
|
||||
<button mat-menu-item (click)="logout()">
|
||||
Logout
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
|
||||
</mat-toolbar-row>
|
||||
<!-- / TOOLBAR TOP -->
|
||||
|
||||
<!-- TOOLBAR BOTTOM -->
|
||||
<mat-toolbar-row>
|
||||
|
||||
<!-- SEARCH -->
|
||||
<div class="search-wrapper" fxFlex fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<div class="search" fxFlex fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<mat-icon>search</mat-icon>
|
||||
|
||||
<input [(ngModel)]="searchText" type="text" placeholder="Search or start new chat" fxFlex>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- / SEARCH -->
|
||||
|
||||
</mat-toolbar-row>
|
||||
<!-- / TOOLBAR BOTTOM -->
|
||||
|
||||
</mat-toolbar>
|
||||
<!-- / CHATS TOOLBAR -->
|
||||
|
||||
</div>
|
||||
<!-- / SIDENAV HEADER -->
|
||||
|
||||
<!-- SIDENAV CONTENT -->
|
||||
<div class="sidenav-content" fusePerfectScrollbar fxFlex>
|
||||
|
||||
<!-- CHATS CONTENT -->
|
||||
<div *fuseIfOnDom [@animateStagger]="{value:'50'}">
|
||||
|
||||
<!-- CHATS LIST-->
|
||||
<div class="chat-list" fxLayout="column">
|
||||
|
||||
<div matSubheader *ngIf="(user.chatList | filter: searchText).length > 0">
|
||||
Chats
|
||||
</div>
|
||||
|
||||
<button mat-button class="contact"
|
||||
*ngFor="let chat of user.chatList | filter: searchText"
|
||||
(click)="getChat(chat.contactId)" ngClass="{'unread':contact.unread}"
|
||||
[@animate]="{value:'*',params:{y:'100%'}}">
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<div class="avatar-wrapper" fxFlex="0 1 auto" fxLayoutAlign="center center">
|
||||
<img [src]="contacts |getById:chat.contactId:'avatar'"
|
||||
class="avatar"
|
||||
alt="{{contacts |getById:chat.contactId:'name'}}"/>
|
||||
<mat-icon class="s-16 status" [ngClass]="contacts |getById:chat.contactId:'status'"></mat-icon>
|
||||
</div>
|
||||
|
||||
<div fxLayout="row" fxFlex>
|
||||
|
||||
<div class="" fxFlex fxLayout="column" fxLayoutAlign="center start">
|
||||
<div class="contact-name">{{contacts |getById:chat.contactId:'name'}}</div>
|
||||
</div>
|
||||
|
||||
<div fxLayout="column" fxLayoutAlign="center end">
|
||||
<div class="contact-last-message-time">
|
||||
{{chat.lastMessageTime | date}}
|
||||
</div>
|
||||
<div *ngIf="chat.unread" class="unread-message-count mat-accent-bg">{{chat.unread}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<!-- / CHATS LIST-->
|
||||
|
||||
<!-- CONTACTS LIST-->
|
||||
<div class="contact-list" fxLayout="column">
|
||||
|
||||
<div matSubheader *ngIf="(contacts| filter: searchText).length > 0">
|
||||
Contacts
|
||||
</div>
|
||||
|
||||
<button mat-button class="contact"
|
||||
*ngFor="let contact of contacts| filter: searchText"
|
||||
(click)="getChat(contact.id)"
|
||||
[@animate]="{value:'*',params:{y:'100%'}}">
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<div class="avatar-wrapper" fxFlex="0 1 auto">
|
||||
<img src="{{contact.avatar}}" class="mat-avatar avatar" alt="{{contact.name}}"/>
|
||||
<mat-icon class="s-16 status" [ngClass]="contact.status"></mat-icon>
|
||||
</div>
|
||||
|
||||
<div class="" fxLayout="column" fxLayoutAlign="center start">
|
||||
<div class="contact-name">{{contact.name}}</div>
|
||||
<p class="contact-mood">{{contact.mood}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<!-- / CONTACTS LIST-->
|
||||
|
||||
<!-- NO RESULTS MESSAGE -->
|
||||
<div *ngIf="(contacts| filter: searchText).length === 0" class="no-results-message">
|
||||
No results..
|
||||
</div>
|
||||
<!-- NO RESULTS MESSAGE-->
|
||||
|
||||
</div>
|
||||
<!-- / CHATS CONTENT -->
|
||||
|
||||
</div>
|
||||
<!-- / SIDENAV CONTENT -->
|
||||
@@ -1,111 +0,0 @@
|
||||
@import "src/@fuse/scss/fuse";
|
||||
|
||||
:host {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
|
||||
.sidenav-header {
|
||||
|
||||
mat-toolbar {
|
||||
border-bottom: 1px solid rgba(0, 0, 0, .08);
|
||||
|
||||
.avatar-wrapper {
|
||||
|
||||
.avatar, .status {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.search {
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
padding: 8px;
|
||||
background: #FFFFFF;
|
||||
font-size: 13px;
|
||||
@include mat-elevation(1);
|
||||
|
||||
.icon {
|
||||
margin: 0;
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
}
|
||||
|
||||
input {
|
||||
padding-left: 12px;
|
||||
height: 36px;
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidenav-content {
|
||||
overflow: auto;
|
||||
|
||||
.contact-list, .chat-list {
|
||||
|
||||
.mat-subheader {
|
||||
padding-left: 16px;
|
||||
font-size: 20px;
|
||||
font-weight: 300;
|
||||
height: 88px;
|
||||
line-height: 88px;
|
||||
color: mat-color($accent);
|
||||
}
|
||||
|
||||
.contact {
|
||||
white-space: normal;
|
||||
text-align: left;
|
||||
letter-spacing: .010em;
|
||||
min-height: 88px;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
||||
padding: 16px;
|
||||
font-weight: 400;
|
||||
|
||||
.avatar-wrapper {
|
||||
|
||||
.avatar {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.contact-name {
|
||||
font-size: 16px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.contact-last-message {
|
||||
line-height: 1.6em;
|
||||
margin: 0;
|
||||
font-weight: 500;
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
}
|
||||
|
||||
.contact-mood {
|
||||
line-height: normal;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.unread-message-count {
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-results-message {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 88px;
|
||||
padding: 16px;
|
||||
background: #FFFFFF;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { ObservableMedia } from '@angular/flex-layout';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseMatSidenavHelperService } from '@fuse/directives/fuse-mat-sidenav/fuse-mat-sidenav.service';
|
||||
|
||||
import { ChatService } from 'app/main/apps/chat/chat.service';
|
||||
|
||||
@Component({
|
||||
selector : 'chat-chats-sidenav',
|
||||
templateUrl: './chats.component.html',
|
||||
styleUrls : ['./chats.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class ChatChatsSidenavComponent implements OnInit, OnDestroy
|
||||
{
|
||||
chats: any[];
|
||||
chatSearch: any;
|
||||
contacts: any[];
|
||||
searchText: string;
|
||||
user: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ChatService} _chatService
|
||||
* @param {FuseMatSidenavHelperService} _fuseMatSidenavHelperService
|
||||
* @param {ObservableMedia} _observableMedia
|
||||
*/
|
||||
constructor(
|
||||
private _chatService: ChatService,
|
||||
private _fuseMatSidenavHelperService: FuseMatSidenavHelperService,
|
||||
public _observableMedia: ObservableMedia
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.chatSearch = {
|
||||
name: ''
|
||||
};
|
||||
this.searchText = '';
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.user = this._chatService.user;
|
||||
this.chats = this._chatService.chats;
|
||||
this.contacts = this._chatService.contacts;
|
||||
|
||||
this._chatService.onChatsUpdated
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(updatedChats => {
|
||||
this.chats = updatedChats;
|
||||
});
|
||||
|
||||
this._chatService.onUserUpdated
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(updatedUser => {
|
||||
this.user = updatedUser;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get chat
|
||||
*
|
||||
* @param contact
|
||||
*/
|
||||
getChat(contact): void
|
||||
{
|
||||
this._chatService.getChat(contact);
|
||||
|
||||
if ( !this._observableMedia.isActive('gt-md') )
|
||||
{
|
||||
this._fuseMatSidenavHelperService.getSidenav('chat-left-sidenav').toggle();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set user status
|
||||
*
|
||||
* @param status
|
||||
*/
|
||||
setUserStatus(status): void
|
||||
{
|
||||
this._chatService.setUserStatus(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change left sidenav view
|
||||
*
|
||||
* @param view
|
||||
*/
|
||||
changeLeftSidenavView(view): void
|
||||
{
|
||||
this._chatService.onLeftSidenavViewChanged.next(view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout
|
||||
*/
|
||||
logout(): void
|
||||
{
|
||||
console.log('logout triggered');
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<div [ngSwitch]="view" class="views">
|
||||
<chat-chats-sidenav class="view"
|
||||
*ngSwitchCase="'chats'"
|
||||
[@slideInRight]>
|
||||
</chat-chats-sidenav>
|
||||
|
||||
<chat-user-sidenav class="view"
|
||||
*ngSwitchCase="'user'"
|
||||
[@slideInLeft]
|
||||
fusePerfectScrollbar>
|
||||
</chat-user-sidenav>
|
||||
</div>
|
||||
@@ -1,20 +0,0 @@
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
.views {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
.view {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { ChatService } from 'app/main/apps/chat/chat.service';
|
||||
|
||||
@Component({
|
||||
selector : 'chat-left-sidenav',
|
||||
templateUrl: './left.component.html',
|
||||
styleUrls : ['./left.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class ChatLeftSidenavComponent implements OnInit, OnDestroy
|
||||
{
|
||||
view: string;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ChatService} _chatService
|
||||
*/
|
||||
constructor(
|
||||
private _chatService: ChatService
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.view = 'chats';
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._chatService.onLeftSidenavViewChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(view => {
|
||||
this.view = view;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
<!-- SIDENAV HEADER -->
|
||||
<div class="sidenav-header">
|
||||
|
||||
<!-- USER TOOLBAR -->
|
||||
<mat-toolbar class="mat-accent-bg">
|
||||
|
||||
<!-- TOOLBAR TOP -->
|
||||
<mat-toolbar-row fxLayout="row" fxLayoutAlign="space-between center">
|
||||
|
||||
<button mat-icon-button (click)="changeLeftSidenavView('chats')" aria-label="back">
|
||||
<mat-icon>arrow_back</mat-icon>
|
||||
</button>
|
||||
|
||||
</mat-toolbar-row>
|
||||
<!-- / TOOLBAR TOP -->
|
||||
|
||||
<!-- TOOLBAR BOTTOM -->
|
||||
<mat-toolbar-row class="toolbar-bottom" fxLayout="column" fxLayoutAlign="center center">
|
||||
|
||||
<img [src]="user.avatar" class="avatar user-avatar huge" alt="{{user.name}}"/>
|
||||
<div class="user-name my-8">{{user.name}}</div>
|
||||
|
||||
</mat-toolbar-row>
|
||||
<!-- / TOOLBAR BOTTOM -->
|
||||
|
||||
</mat-toolbar>
|
||||
<!-- / USER TOOLBAR -->
|
||||
</div>
|
||||
|
||||
<!-- SIDENAV CONTENT -->
|
||||
<div class="sidenav-content p-16" fxFlex>
|
||||
|
||||
<!-- USER MOOD -->
|
||||
<mat-card>
|
||||
|
||||
<form [formGroup]="userForm" fxLayout="column">
|
||||
|
||||
<mat-form-field class="mb-24" fxFlex="0 1 auto">
|
||||
<textarea matInput placeholder="Mood" name="mood"
|
||||
formControlName="mood" rows="3"></textarea>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-radio-group formControlName="status" fxLayout="column">
|
||||
|
||||
<mat-radio-button value="online" class="py-8">
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="status online mr-8"></mat-icon>
|
||||
<span class="mat-h4 m-0">Online</span>
|
||||
</div>
|
||||
</mat-radio-button>
|
||||
|
||||
<mat-radio-button value="away" class="py-8">
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="status away mr-8"></mat-icon>
|
||||
<span class="mat-h4 m-0">Away</span>
|
||||
</div>
|
||||
</mat-radio-button>
|
||||
|
||||
<mat-radio-button value="do-not-disturb" class="py-8">
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="status do-not-disturb mr-8"></mat-icon>
|
||||
<span class="mat-h4 m-0">Do not disturb</span>
|
||||
</div>
|
||||
</mat-radio-button>
|
||||
|
||||
<mat-radio-button value="offline" class="py-8">
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="status offline mr-8"></mat-icon>
|
||||
<span class="mat-h4 m-0">Offline</span>
|
||||
</div>
|
||||
</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
</form>
|
||||
</mat-card>
|
||||
<!-- / USER MOOD -->
|
||||
</div>
|
||||
@@ -1,23 +0,0 @@
|
||||
@import "src/@fuse/scss/fuse";
|
||||
|
||||
:host {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
|
||||
mat-toolbar {
|
||||
|
||||
.toolbar-bottom {
|
||||
height: 240px;
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
height: 180px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidenav-content {
|
||||
background: whitesmoke;
|
||||
}
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { FormControl, FormGroup } from '@angular/forms';
|
||||
import { Subject } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { ChatService } from 'app/main/apps/chat/chat.service';
|
||||
|
||||
@Component({
|
||||
selector : 'chat-user-sidenav',
|
||||
templateUrl: './user.component.html',
|
||||
styleUrls : ['./user.component.scss']
|
||||
})
|
||||
export class ChatUserSidenavComponent implements OnInit, OnDestroy
|
||||
{
|
||||
user: any;
|
||||
userForm: FormGroup;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ChatService} _chatService
|
||||
*/
|
||||
constructor(
|
||||
private _chatService: ChatService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.user = this._chatService.user;
|
||||
|
||||
this.userForm = new FormGroup({
|
||||
mood : new FormControl(this.user.mood),
|
||||
status: new FormControl(this.user.status)
|
||||
});
|
||||
|
||||
this.userForm.valueChanges
|
||||
.pipe(
|
||||
takeUntil(this._unsubscribeAll),
|
||||
debounceTime(500),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
.subscribe(data => {
|
||||
this.user.mood = data.mood;
|
||||
this.user.status = data.status;
|
||||
this._chatService.updateUserData(this.user);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Change left sidenav view
|
||||
*
|
||||
* @param view
|
||||
*/
|
||||
changeLeftSidenavView(view): void
|
||||
{
|
||||
this._chatService.onLeftSidenavViewChanged.next(view);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
<!-- SIDENAV HEADER -->
|
||||
<div class="sidenav-header" *ngIf="contact">
|
||||
|
||||
<!-- CONTACT TOOLBAR -->
|
||||
<mat-toolbar class="mat-accent-bg">
|
||||
|
||||
<!-- TOOLBAR TOP -->
|
||||
<mat-toolbar-row fxLayout="row" fxLayoutAlign="space-between center">
|
||||
|
||||
<div>Contact Info</div>
|
||||
|
||||
<button mat-icon-button fuseMatSidenavToggler="chat-right-sidenav" aria-label="close">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
|
||||
</mat-toolbar-row>
|
||||
<!-- / TOOLBAR TOP -->
|
||||
|
||||
<!-- TOOLBAR BOTTOM -->
|
||||
<mat-toolbar-row class="toolbar-bottom" fxLayout="column" fxLayoutAlign="center center">
|
||||
<img [src]="contact.avatar" class="avatar contact-avatar huge" alt="{{contact.name}}"/>
|
||||
<div class="contact-name my-8">{{contact.name}}</div>
|
||||
</mat-toolbar-row>
|
||||
<!-- / TOOLBAR BOTTOM -->
|
||||
|
||||
</mat-toolbar>
|
||||
<!-- / CONTACT TOOLBAR -->
|
||||
</div>
|
||||
|
||||
<!-- SIDENAV CONTENT -->
|
||||
<div class="sidenav-content p-16" fxFlex *ngIf="contact">
|
||||
|
||||
<!-- CONTACT MOOD -->
|
||||
<mat-card>
|
||||
|
||||
<mat-form-field class="w-100-p">
|
||||
<textarea matInput placeholder="Mood" name="mood"
|
||||
[value]="contact.mood" rows="3" disabled>
|
||||
</textarea>
|
||||
</mat-form-field>
|
||||
|
||||
</mat-card>
|
||||
<!-- / CONTACT MOOD -->
|
||||
</div>
|
||||
@@ -1,23 +0,0 @@
|
||||
@import "src/@fuse/scss/fuse";
|
||||
|
||||
:host {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
|
||||
mat-toolbar {
|
||||
|
||||
.toolbar-bottom {
|
||||
height: 240px;
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
height: 180px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidenav-content {
|
||||
background: whitesmoke;
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { ChatService } from 'app/main/apps/chat/chat.service';
|
||||
|
||||
@Component({
|
||||
selector : 'chat-contact-sidenav',
|
||||
templateUrl: './contact.component.html',
|
||||
styleUrls : ['./contact.component.scss']
|
||||
})
|
||||
export class ChatContactSidenavComponent implements OnInit, OnDestroy
|
||||
{
|
||||
contact: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ChatService} _chatService
|
||||
*/
|
||||
constructor(
|
||||
private _chatService: ChatService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._chatService.onContactSelected
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(contact => {
|
||||
this.contact = contact;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
<div [ngSwitch]="view" class="views">
|
||||
|
||||
<chat-contact-sidenav class="view"
|
||||
*ngSwitchCase="'contact'"
|
||||
[@slideInRight]
|
||||
fusePerfectScrollbar>
|
||||
</chat-contact-sidenav>
|
||||
|
||||
</div>
|
||||
@@ -1,20 +0,0 @@
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
.views {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
.view {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { ChatService } from 'app/main/apps/chat/chat.service';
|
||||
|
||||
@Component({
|
||||
selector : 'chat-right-sidenav',
|
||||
templateUrl: './right.component.html',
|
||||
styleUrls : ['./right.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class ChatRightSidenavComponent implements OnInit, OnDestroy
|
||||
{
|
||||
view: string;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
constructor(
|
||||
private _chatService: ChatService
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.view = 'contact';
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._chatService.onRightSidenavViewChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(view => {
|
||||
this.view = view;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
<div class="dialog-content-wrapper">
|
||||
<mat-toolbar matDialogTitle class="mat-accent m-0">
|
||||
<mat-toolbar-row fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<span class="title dialog-title">{{dialogTitle}}</span>
|
||||
<button mat-icon-button (click)="matDialogRef.close()" aria-label="Close dialog">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</mat-toolbar-row>
|
||||
|
||||
<mat-toolbar-row class="toolbar-bottom py-16" fxLayout="column" fxLayoutAlign="center center">
|
||||
<img [src]="contact.avatar" class="avatar contact-avatar huge m-0"
|
||||
[alt]="contact.name"/>
|
||||
<div class="contact-name mt-8">{{contact.name}} {{contact.lastName}}</div>
|
||||
</mat-toolbar-row>
|
||||
</mat-toolbar>
|
||||
|
||||
<div mat-dialog-content class="p-24 m-0" fusePerfectScrollbar>
|
||||
|
||||
<form [formGroup]="contactForm">
|
||||
|
||||
<div class="mb-24" fxLayout="row" fxLayoutAlign="start start">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-icon matPrefix class="mr-12 s-20 secondary-text">account_circle</mat-icon>
|
||||
<input name="name" formControlName="name" placeholder="Name" matInput required>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="mb-24" fxLayout="row" fxLayoutAlign="start start">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-icon matPrefix class="mr-12 s-20 secondary-text">account_circle</mat-icon>
|
||||
<input name="lastName" formControlName="lastName" placeholder="Lastname" matInput>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="mb-24" fxLayout="row" fxLayoutAlign="start start">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-icon matPrefix class="mr-12 s-20 secondary-text">star</mat-icon>
|
||||
<input name="nickname" formControlName="nickname" matInput placeholder="Nickname">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="mb-24" fxLayout="row" fxLayoutAlign="start start">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-icon matPrefix class="mr-12 s-20 secondary-text">phone</mat-icon>
|
||||
<input formControlName="phone" matInput placeholder="Phone number">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="mb-24" fxLayout="row" fxLayoutAlign="start start">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-icon matPrefix class="mr-12 s-20 secondary-text">email</mat-icon>
|
||||
<input name="email" formControlName="email" matInput type="email" placeholder="Email">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="mb-24" fxLayout="row" fxLayoutAlign="start start">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-icon matPrefix class="mr-12 s-20 secondary-text">domain</mat-icon>
|
||||
<input name="company" formControlName="company" matInput placeholder="Company">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="mb-24" fxLayout="row" fxLayoutAlign="start start">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-icon matPrefix class="mr-12 s-20 secondary-text">work</mat-icon>
|
||||
<input name="jobTitle" formControlName="jobTitle" matInput placeholder="Job title">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="mb-24" fxLayout="row" fxLayoutAlign="start start">
|
||||
<mat-form-field class="mr-24" fxFlex>
|
||||
<mat-icon matPrefix class="mr-12 s-20 secondary-text">cake</mat-icon>
|
||||
<input matInput [matDatepicker]="birthdayDatePicker" placeholder="Birthday">
|
||||
<mat-datepicker-toggle matSuffix [for]="birthdayDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #birthdayDatePicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="mb-24" fxLayout="row" fxLayoutAlign="start start">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-icon matPrefix class="mr-12 s-20 secondary-text">home</mat-icon>
|
||||
<input name="address" formControlName="address" matInput placeholder="Address">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div fxLayout="row" class="textarea-wrapper" fxLayoutAlign="start start">
|
||||
<mat-form-field fxFlex>
|
||||
<textarea name="notes" formControlName="notes" placeholder="Notes" matInput type="text"
|
||||
max-rows="4"></textarea>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<div mat-dialog-actions class="m-0 p-16" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
|
||||
<button *ngIf="action !=='edit'"
|
||||
mat-raised-button
|
||||
(click)="_matDialogRef.close(contactForm)"
|
||||
class="save-button mat-accent"
|
||||
[disabled]="contactForm.invalid"
|
||||
aria-label="SAVE">
|
||||
SAVE
|
||||
</button>
|
||||
|
||||
<button *ngIf="action ==='edit'"
|
||||
mat-raised-button
|
||||
(click)="_matDialogRef.close(['save',contactForm])"
|
||||
class="save-button mat-accent"
|
||||
[disabled]="contactForm.invalid"
|
||||
aria-label="SAVE">
|
||||
SAVE
|
||||
</button>
|
||||
|
||||
<button *ngIf="action ==='edit'"
|
||||
mat-icon-button
|
||||
(click)="_matDialogRef.close(['delete',contactForm])"
|
||||
aria-label="Delete"
|
||||
matTooltip="Delete">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,31 +0,0 @@
|
||||
@import "src/@fuse/scss/fuse";
|
||||
|
||||
.contact-form-dialog {
|
||||
|
||||
@include media-breakpoint('xs') {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up('xs') {
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.mat-dialog-container {
|
||||
padding: 0;
|
||||
|
||||
.mat-toolbar {
|
||||
flex: 1 0 auto;
|
||||
min-height: initial;
|
||||
}
|
||||
|
||||
.toolbar-bottom {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-content-wrapper {
|
||||
max-height: 85vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
import { Component, Inject, ViewEncapsulation } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
|
||||
|
||||
import { Contact } from 'app/main/apps/contacts/contact.model';
|
||||
|
||||
@Component({
|
||||
selector : 'contacts-contact-form-dialog',
|
||||
templateUrl : './contact-form.component.html',
|
||||
styleUrls : ['./contact-form.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
|
||||
export class ContactsContactFormDialogComponent
|
||||
{
|
||||
action: string;
|
||||
contact: Contact;
|
||||
contactForm: FormGroup;
|
||||
dialogTitle: string;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {MatDialogRef<ContactsContactFormDialogComponent>} matDialogRef
|
||||
* @param _data
|
||||
* @param {FormBuilder} _formBuilder
|
||||
*/
|
||||
constructor(
|
||||
public matDialogRef: MatDialogRef<ContactsContactFormDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) private _data: any,
|
||||
private _formBuilder: FormBuilder
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.action = _data.action;
|
||||
|
||||
if ( this.action === 'edit' )
|
||||
{
|
||||
this.dialogTitle = 'Edit Contact';
|
||||
this.contact = _data.contact;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.dialogTitle = 'New Contact';
|
||||
this.contact = new Contact({});
|
||||
}
|
||||
|
||||
this.contactForm = this.createContactForm();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create contact form
|
||||
*
|
||||
* @returns {FormGroup}
|
||||
*/
|
||||
createContactForm(): FormGroup
|
||||
{
|
||||
return this._formBuilder.group({
|
||||
id : [this.contact.id],
|
||||
name : [this.contact.name],
|
||||
lastName: [this.contact.lastName],
|
||||
avatar : [this.contact.avatar],
|
||||
nickname: [this.contact.nickname],
|
||||
company : [this.contact.company],
|
||||
jobTitle: [this.contact.jobTitle],
|
||||
email : [this.contact.email],
|
||||
phone : [this.contact.phone],
|
||||
address : [this.contact.address],
|
||||
birthday: [this.contact.birthday],
|
||||
notes : [this.contact.notes]
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
<mat-table #table [dataSource]="dataSource"
|
||||
[@animateStagger]="{value:'50'}">
|
||||
<!-- Checkbox Column -->
|
||||
<ng-container cdkColumnDef="checkbox">
|
||||
<mat-header-cell *cdkHeaderCellDef></mat-header-cell>
|
||||
<mat-cell *cdkCellDef="let contact">
|
||||
<mat-checkbox [(ngModel)]="checkboxes[contact.id]" (ngModelChange)="onSelectedChange(contact.id)"
|
||||
(click)="$event.stopPropagation()">
|
||||
</mat-checkbox>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Avatar Column -->
|
||||
<ng-container cdkColumnDef="avatar">
|
||||
<mat-header-cell *cdkHeaderCellDef></mat-header-cell>
|
||||
<mat-cell *cdkCellDef="let contact">
|
||||
<img class="avatar" *ngIf="contact.avatar" [alt]="contact.name"
|
||||
[src]="contact.avatar"/>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Name Column -->
|
||||
<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>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Email Column -->
|
||||
<ng-container cdkColumnDef="email">
|
||||
<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}}
|
||||
</p>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Phone Column -->
|
||||
<ng-container cdkColumnDef="phone">
|
||||
<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}}
|
||||
</p>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Job Title Column -->
|
||||
<ng-container cdkColumnDef="jobTitle">
|
||||
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-lg>Job title</mat-header-cell>
|
||||
<mat-cell *cdkCellDef="let contact" fxHide fxShow.gt-lg>
|
||||
<p class="job-title text-truncate">
|
||||
{{contact.jobTitle}}
|
||||
</p>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Company Column -->
|
||||
<ng-container cdkColumnDef="company">
|
||||
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-lg>Company</mat-header-cell>
|
||||
<mat-cell *cdkCellDef="let contact" fxHide fxShow.gt-lg>
|
||||
<p class="company text-truncate">
|
||||
{{contact.company}}
|
||||
</p>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Buttons Column -->
|
||||
<ng-container cdkColumnDef="buttons">
|
||||
<mat-header-cell *cdkHeaderCellDef></mat-header-cell>
|
||||
<mat-cell *cdkCellDef="let contact">
|
||||
<div fxFlex="row" fxLayoutAlign="end center">
|
||||
<button mat-icon-button (click)="$event.stopPropagation();toggleStar(contact.id)" aria-label="Toggle star">
|
||||
<mat-icon class="amber-fg" *ngIf="user.starred.includes(contact.id)">star</mat-icon>
|
||||
<mat-icon class="secondary-text" *ngIf="!user.starred.includes(contact.id)">star_outline</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-icon-button [matMenuTriggerFor]="moreMenu" aria-label="More"
|
||||
(click)="$event.stopPropagation();">
|
||||
<mat-icon class="secondary-text">more_vert</mat-icon>
|
||||
</button>
|
||||
|
||||
<mat-menu #moreMenu="matMenu">
|
||||
<button mat-menu-item aria-label="remove" (click)="deleteContact(contact)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
<span>Remove</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<mat-header-row *cdkHeaderRowDef="displayedColumns"></mat-header-row>
|
||||
<mat-row *cdkRowDef="let contact; columns: displayedColumns;"
|
||||
class="contact"
|
||||
(click)="editContact(contact)"
|
||||
[ngClass]="{'mat-accent-50-bg':checkboxes[contact.id]}"
|
||||
matRipple
|
||||
[@animate]="{value:'*',params:{y:'100%'}}">
|
||||
</mat-row>
|
||||
</mat-table>
|
||||
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
@import "src/@fuse/scss/fuse";
|
||||
|
||||
contacts-contact-list {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
width: 100%;
|
||||
|
||||
.mat-table {
|
||||
width: 100%;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
|
||||
.mat-column-checkbox {
|
||||
flex: 0 1 64px;
|
||||
padding-left: 18px;
|
||||
}
|
||||
|
||||
.mat-column-avatar {
|
||||
flex: 0 1 64px;
|
||||
}
|
||||
|
||||
.mat-column-buttons {
|
||||
flex: 0 1 80px;
|
||||
}
|
||||
|
||||
.mat-row {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
padding: 8px;
|
||||
|
||||
.mat-cell {
|
||||
min-width: 0;
|
||||
|
||||
&.mat-column-detail-button {
|
||||
flex: 0 1 auto;
|
||||
padding: 0 24px 0 0;
|
||||
|
||||
@include media-breakpoint('gt-md') {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#add-contact-button {
|
||||
position: absolute;
|
||||
bottom: 12px;
|
||||
right: 12px;
|
||||
padding: 0;
|
||||
z-index: 99;
|
||||
}
|
||||
@@ -1,242 +0,0 @@
|
||||
import { Component, OnDestroy, OnInit, TemplateRef, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
import { MatDialog, MatDialogRef } from '@angular/material';
|
||||
import { DataSource } from '@angular/cdk/collections';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseConfirmDialogComponent } from '@fuse/components/confirm-dialog/confirm-dialog.component';
|
||||
|
||||
import { ContactsService } from 'app/main/apps/contacts/contacts.service';
|
||||
import { ContactsContactFormDialogComponent } from 'app/main/apps/contacts/contact-form/contact-form.component';
|
||||
|
||||
@Component({
|
||||
selector : 'contacts-contact-list',
|
||||
templateUrl : './contact-list.component.html',
|
||||
styleUrls : ['./contact-list.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class ContactsContactListComponent implements OnInit, OnDestroy
|
||||
{
|
||||
@ViewChild('dialogContent')
|
||||
dialogContent: TemplateRef<any>;
|
||||
|
||||
contacts: any;
|
||||
user: any;
|
||||
dataSource: FilesDataSource | null;
|
||||
displayedColumns = ['checkbox', 'avatar', 'name', 'email', 'phone', 'jobTitle', 'buttons'];
|
||||
selectedContacts: any[];
|
||||
checkboxes: {};
|
||||
dialogRef: any;
|
||||
confirmDialogRef: MatDialogRef<FuseConfirmDialogComponent>;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ContactsService} _contactsService
|
||||
* @param {MatDialog} _matDialog
|
||||
*/
|
||||
constructor(
|
||||
private _contactsService: ContactsService,
|
||||
public _matDialog: MatDialog
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.dataSource = new FilesDataSource(this._contactsService);
|
||||
|
||||
this._contactsService.onContactsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(contacts => {
|
||||
this.contacts = contacts;
|
||||
|
||||
this.checkboxes = {};
|
||||
contacts.map(contact => {
|
||||
this.checkboxes[contact.id] = false;
|
||||
});
|
||||
});
|
||||
|
||||
this._contactsService.onSelectedContactsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(selectedContacts => {
|
||||
for ( const id in this.checkboxes )
|
||||
{
|
||||
if ( !this.checkboxes.hasOwnProperty(id) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
this.checkboxes[id] = selectedContacts.includes(id);
|
||||
}
|
||||
this.selectedContacts = selectedContacts;
|
||||
});
|
||||
|
||||
this._contactsService.onUserDataChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(user => {
|
||||
this.user = user;
|
||||
});
|
||||
|
||||
this._contactsService.onFilterChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(() => {
|
||||
this._contactsService.deselectContacts();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Edit contact
|
||||
*
|
||||
* @param contact
|
||||
*/
|
||||
editContact(contact): void
|
||||
{
|
||||
this.dialogRef = this._matDialog.open(ContactsContactFormDialogComponent, {
|
||||
panelClass: 'contact-form-dialog',
|
||||
data : {
|
||||
contact: contact,
|
||||
action : 'edit'
|
||||
}
|
||||
});
|
||||
|
||||
this.dialogRef.afterClosed()
|
||||
.subscribe(response => {
|
||||
if ( !response )
|
||||
{
|
||||
return;
|
||||
}
|
||||
const actionType: string = response[0];
|
||||
const formData: FormGroup = response[1];
|
||||
switch ( actionType )
|
||||
{
|
||||
/**
|
||||
* Save
|
||||
*/
|
||||
case 'save':
|
||||
|
||||
this._contactsService.updateContact(formData.getRawValue());
|
||||
|
||||
break;
|
||||
/**
|
||||
* Delete
|
||||
*/
|
||||
case 'delete':
|
||||
|
||||
this.deleteContact(contact);
|
||||
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Contact
|
||||
*/
|
||||
deleteContact(contact): void
|
||||
{
|
||||
this.confirmDialogRef = this._matDialog.open(FuseConfirmDialogComponent, {
|
||||
disableClose: false
|
||||
});
|
||||
|
||||
this.confirmDialogRef.componentInstance.confirmMessage = 'Are you sure you want to delete?';
|
||||
|
||||
this.confirmDialogRef.afterClosed().subscribe(result => {
|
||||
if ( result )
|
||||
{
|
||||
this._contactsService.deleteContact(contact);
|
||||
}
|
||||
this.confirmDialogRef = null;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* On selected change
|
||||
*
|
||||
* @param contactId
|
||||
*/
|
||||
onSelectedChange(contactId): void
|
||||
{
|
||||
this._contactsService.toggleSelectedContact(contactId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle star
|
||||
*
|
||||
* @param contactId
|
||||
*/
|
||||
toggleStar(contactId): void
|
||||
{
|
||||
if ( this.user.starred.includes(contactId) )
|
||||
{
|
||||
this.user.starred.splice(this.user.starred.indexOf(contactId), 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.user.starred.push(contactId);
|
||||
}
|
||||
|
||||
this._contactsService.updateUserData(this.user);
|
||||
}
|
||||
}
|
||||
|
||||
export class FilesDataSource extends DataSource<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ContactsService} _contactsService
|
||||
*/
|
||||
constructor(
|
||||
private _contactsService: ContactsService
|
||||
)
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect function called by the table to retrieve one stream containing the data to render.
|
||||
* @returns {Observable<any[]>}
|
||||
*/
|
||||
connect(): Observable<any[]>
|
||||
{
|
||||
return this._contactsService.onContactsChanged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect
|
||||
*/
|
||||
disconnect(): void
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
import { FuseUtils } from '@fuse/utils';
|
||||
|
||||
export class Contact
|
||||
{
|
||||
id: string;
|
||||
name: string;
|
||||
lastName: string;
|
||||
avatar: string;
|
||||
nickname: string;
|
||||
company: string;
|
||||
jobTitle: string;
|
||||
email: string;
|
||||
phone: string;
|
||||
address: string;
|
||||
birthday: string;
|
||||
notes: string;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param contact
|
||||
*/
|
||||
constructor(contact)
|
||||
{
|
||||
{
|
||||
this.id = contact.id || FuseUtils.generateGUID();
|
||||
this.name = contact.name || '';
|
||||
this.lastName = contact.lastName || '';
|
||||
this.avatar = contact.avatar || 'assets/images/avatars/profile.jpg';
|
||||
this.nickname = contact.nickname || '';
|
||||
this.company = contact.company || '';
|
||||
this.jobTitle = contact.jobTitle || '';
|
||||
this.email = contact.email || '';
|
||||
this.phone = contact.phone || '';
|
||||
this.address = contact.address || '';
|
||||
this.birthday = contact.birhday || '';
|
||||
this.notes = contact.notes || '';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
<div id="contacts" class="page-layout simple left-sidebar inner-sidebar inner-scroll">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-16 p-sm-24" fxLayout="column" fxLayoutAlign="start start"
|
||||
fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="space-between center">
|
||||
|
||||
<!-- APP TITLE -->
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<button mat-icon-button class="sidebar-toggle mr-12" fxHide.gt-md
|
||||
(click)="toggleSidebar('contacts-main-sidebar')">
|
||||
<mat-icon>menu</mat-icon>
|
||||
</button>
|
||||
|
||||
<div class="logo" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="logo-icon mr-16"
|
||||
[@animate]="{value:'*',params:{delay:'50ms',scale:'0.2'}}">account_box
|
||||
</mat-icon>
|
||||
<span class="logo-text h1" [@animate]="{value:'*',params:{delay:'100ms',x:'-25px'}}">
|
||||
Contacts
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / APP TITLE -->
|
||||
|
||||
<!-- SEARCH -->
|
||||
<div class="search-input-wrapper mt-16 ml-8 m-sm-0" fxLayout="row" fxLayoutAlign="start center">
|
||||
<label for="search" class="mr-8">
|
||||
<mat-icon>search</mat-icon>
|
||||
</label>
|
||||
<mat-form-field mat-no-float class="m-0" floatLabel="never">
|
||||
<input matInput [formControl]="searchInput" id="search" placeholder="Search for anything">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<!-- / SEARCH -->
|
||||
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- SELECTED BAR -->
|
||||
<selected-bar class="mat-accent-600-bg" *ngIf="hasSelectedContacts" [@slideInTop]></selected-bar>
|
||||
<!-- / SELECTED BAR -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content">
|
||||
|
||||
<!-- SIDEBAR -->
|
||||
<fuse-sidebar class="sidebar" name="contacts-main-sidebar" position="left" lockedOpen="gt-sm">
|
||||
|
||||
<!-- SIDEBAR CONTENT -->
|
||||
<div class="content" fusePerfectScrollbar>
|
||||
<contacts-main-sidebar [@animate]="{value:'*'}"></contacts-main-sidebar>
|
||||
</div>
|
||||
<!-- / SIDEBAR CONTENT -->
|
||||
|
||||
</fuse-sidebar>
|
||||
<!-- / SIDEBAR -->
|
||||
|
||||
<!-- CENTER -->
|
||||
<div class="center p-24 pb-56 pr-sm-92" fusePerfectScrollbar>
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content mat-white-bg mat-elevation-z4">
|
||||
<contacts-contact-list></contacts-contact-list>
|
||||
</div>
|
||||
<!-- / CONTENT -->
|
||||
|
||||
</div>
|
||||
<!-- / CENTER -->
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT-->
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ADD CONTACT BUTTON -->
|
||||
<button mat-fab class="mat-accent-bg" id="add-contact-button" (click)="newContact()" aria-label="add contact"
|
||||
[@animate]="{value:'*', params:{delay:'300ms',scale:'.2'}}">
|
||||
<mat-icon>person_add</mat-icon>
|
||||
</button>
|
||||
<!-- / ADD CONTACT BUTTON -->
|
||||
@@ -1,13 +0,0 @@
|
||||
#contacts {
|
||||
|
||||
.content {
|
||||
overflow: hidden;
|
||||
|
||||
.sidebar {
|
||||
|
||||
&:not(.locked-open) {
|
||||
background: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { FormControl, FormGroup } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material';
|
||||
import { Subject } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseSidebarService } from '@fuse/components/sidebar/sidebar.service';
|
||||
|
||||
import { ContactsService } from 'app/main/apps/contacts/contacts.service';
|
||||
import { ContactsContactFormDialogComponent } from 'app/main/apps/contacts/contact-form/contact-form.component';
|
||||
|
||||
@Component({
|
||||
selector : 'contacts',
|
||||
templateUrl : './contacts.component.html',
|
||||
styleUrls : ['./contacts.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class ContactsComponent implements OnInit, OnDestroy
|
||||
{
|
||||
dialogRef: any;
|
||||
hasSelectedContacts: boolean;
|
||||
searchInput: FormControl;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ContactsService} _contactsService
|
||||
* @param {FuseSidebarService} _fuseSidebarService
|
||||
* @param {MatDialog} _matDialog
|
||||
*/
|
||||
constructor(
|
||||
private _contactsService: ContactsService,
|
||||
private _fuseSidebarService: FuseSidebarService,
|
||||
private _matDialog: MatDialog
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.searchInput = new FormControl('');
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._contactsService.onSelectedContactsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(selectedContacts => {
|
||||
this.hasSelectedContacts = selectedContacts.length > 0;
|
||||
});
|
||||
|
||||
this.searchInput.valueChanges
|
||||
.pipe(
|
||||
takeUntil(this._unsubscribeAll),
|
||||
debounceTime(300),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
.subscribe(searchText => {
|
||||
this._contactsService.onSearchTextChanged.next(searchText);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* New contact
|
||||
*/
|
||||
newContact(): void
|
||||
{
|
||||
this.dialogRef = this._matDialog.open(ContactsContactFormDialogComponent, {
|
||||
panelClass: 'contact-form-dialog',
|
||||
data : {
|
||||
action: 'new'
|
||||
}
|
||||
});
|
||||
|
||||
this.dialogRef.afterClosed()
|
||||
.subscribe((response: FormGroup) => {
|
||||
if ( !response )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this._contactsService.updateContact(response.getRawValue());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the sidebar
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
toggleSidebar(name): void
|
||||
{
|
||||
this._fuseSidebarService.getSidebar(name).toggleOpen();
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { CdkTableModule } from '@angular/cdk/table';
|
||||
|
||||
import { MatButtonModule, MatCheckboxModule, MatDatepickerModule, MatFormFieldModule, MatIconModule, MatInputModule, MatMenuModule, MatRippleModule, MatTableModule, MatToolbarModule } from '@angular/material';
|
||||
|
||||
import { FuseSharedModule } from '@fuse/shared.module';
|
||||
import { FuseConfirmDialogModule, FuseSidebarModule } from '@fuse/components';
|
||||
|
||||
import { ContactsComponent } from 'app/main/apps/contacts/contacts.component';
|
||||
import { ContactsService } from 'app/main/apps/contacts/contacts.service';
|
||||
import { ContactsContactListComponent } from 'app/main/apps/contacts/contact-list/contact-list.component';
|
||||
import { ContactsSelectedBarComponent } from 'app/main/apps/contacts/selected-bar/selected-bar.component';
|
||||
import { ContactsMainSidebarComponent } from 'app/main/apps/contacts/sidebars/main/main.component';
|
||||
import { ContactsContactFormDialogComponent } from 'app/main/apps/contacts/contact-form/contact-form.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path : '**',
|
||||
component: ContactsComponent,
|
||||
resolve : {
|
||||
contacts: ContactsService
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations : [
|
||||
ContactsComponent,
|
||||
ContactsContactListComponent,
|
||||
ContactsSelectedBarComponent,
|
||||
ContactsMainSidebarComponent,
|
||||
ContactsContactFormDialogComponent
|
||||
],
|
||||
imports : [
|
||||
RouterModule.forChild(routes),
|
||||
CdkTableModule,
|
||||
|
||||
MatButtonModule,
|
||||
MatCheckboxModule,
|
||||
MatDatepickerModule,
|
||||
MatFormFieldModule,
|
||||
MatIconModule,
|
||||
MatInputModule,
|
||||
MatMenuModule,
|
||||
MatRippleModule,
|
||||
MatTableModule,
|
||||
MatToolbarModule,
|
||||
|
||||
FuseSharedModule,
|
||||
FuseConfirmDialogModule,
|
||||
FuseSidebarModule
|
||||
],
|
||||
providers : [
|
||||
ContactsService
|
||||
],
|
||||
entryComponents: [
|
||||
ContactsContactFormDialogComponent
|
||||
]
|
||||
})
|
||||
export class ContactsModule
|
||||
{
|
||||
}
|
||||
@@ -1,288 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||
import { BehaviorSubject, Observable, Subject } from 'rxjs';
|
||||
|
||||
import { FuseUtils } from '@fuse/utils';
|
||||
|
||||
import { Contact } from 'app/main/apps/contacts/contact.model';
|
||||
|
||||
@Injectable()
|
||||
export class ContactsService implements Resolve<any>
|
||||
{
|
||||
onContactsChanged: BehaviorSubject<any>;
|
||||
onSelectedContactsChanged: BehaviorSubject<any>;
|
||||
onUserDataChanged: BehaviorSubject<any>;
|
||||
onSearchTextChanged: Subject<any>;
|
||||
onFilterChanged: Subject<any>;
|
||||
|
||||
contacts: Contact[];
|
||||
user: any;
|
||||
selectedContacts: string[] = [];
|
||||
|
||||
searchText: string;
|
||||
filterBy: string;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {HttpClient} _httpClient
|
||||
*/
|
||||
constructor(
|
||||
private _httpClient: HttpClient
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.onContactsChanged = new BehaviorSubject([]);
|
||||
this.onSelectedContactsChanged = new BehaviorSubject([]);
|
||||
this.onUserDataChanged = new BehaviorSubject([]);
|
||||
this.onSearchTextChanged = new Subject();
|
||||
this.onFilterChanged = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 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.getContacts(),
|
||||
this.getUserData()
|
||||
]).then(
|
||||
([files]) => {
|
||||
|
||||
this.onSearchTextChanged.subscribe(searchText => {
|
||||
this.searchText = searchText;
|
||||
this.getContacts();
|
||||
});
|
||||
|
||||
this.onFilterChanged.subscribe(filter => {
|
||||
this.filterBy = filter;
|
||||
this.getContacts();
|
||||
});
|
||||
|
||||
resolve();
|
||||
|
||||
},
|
||||
reject
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get contacts
|
||||
*
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
getContacts(): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this._httpClient.get('api/contacts-contacts')
|
||||
.subscribe((response: any) => {
|
||||
|
||||
this.contacts = response;
|
||||
|
||||
if ( this.filterBy === 'starred' )
|
||||
{
|
||||
this.contacts = this.contacts.filter(_contact => {
|
||||
return this.user.starred.includes(_contact.id);
|
||||
});
|
||||
}
|
||||
|
||||
if ( this.filterBy === 'frequent' )
|
||||
{
|
||||
this.contacts = this.contacts.filter(_contact => {
|
||||
return this.user.frequentContacts.includes(_contact.id);
|
||||
});
|
||||
}
|
||||
|
||||
if ( this.searchText && this.searchText !== '' )
|
||||
{
|
||||
this.contacts = FuseUtils.filterArrayByString(this.contacts, this.searchText);
|
||||
}
|
||||
|
||||
this.contacts = this.contacts.map(contact => {
|
||||
return new Contact(contact);
|
||||
});
|
||||
|
||||
this.onContactsChanged.next(this.contacts);
|
||||
resolve(this.contacts);
|
||||
}, reject);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user data
|
||||
*
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
getUserData(): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this._httpClient.get('api/contacts-user/5725a6802d10e277a0f35724')
|
||||
.subscribe((response: any) => {
|
||||
this.user = response;
|
||||
this.onUserDataChanged.next(this.user);
|
||||
resolve(this.user);
|
||||
}, reject);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle selected contact by id
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
toggleSelectedContact(id): void
|
||||
{
|
||||
// First, check if we already have that contact as selected...
|
||||
if ( this.selectedContacts.length > 0 )
|
||||
{
|
||||
const index = this.selectedContacts.indexOf(id);
|
||||
|
||||
if ( index !== -1 )
|
||||
{
|
||||
this.selectedContacts.splice(index, 1);
|
||||
|
||||
// Trigger the next event
|
||||
this.onSelectedContactsChanged.next(this.selectedContacts);
|
||||
|
||||
// Return
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If we don't have it, push as selected
|
||||
this.selectedContacts.push(id);
|
||||
|
||||
// Trigger the next event
|
||||
this.onSelectedContactsChanged.next(this.selectedContacts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle select all
|
||||
*/
|
||||
toggleSelectAll(): void
|
||||
{
|
||||
if ( this.selectedContacts.length > 0 )
|
||||
{
|
||||
this.deselectContacts();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.selectContacts();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select contacts
|
||||
*
|
||||
* @param filterParameter
|
||||
* @param filterValue
|
||||
*/
|
||||
selectContacts(filterParameter?, filterValue?): void
|
||||
{
|
||||
this.selectedContacts = [];
|
||||
|
||||
// If there is no filter, select all contacts
|
||||
if ( filterParameter === undefined || filterValue === undefined )
|
||||
{
|
||||
this.selectedContacts = [];
|
||||
this.contacts.map(contact => {
|
||||
this.selectedContacts.push(contact.id);
|
||||
});
|
||||
}
|
||||
|
||||
// Trigger the next event
|
||||
this.onSelectedContactsChanged.next(this.selectedContacts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update contact
|
||||
*
|
||||
* @param contact
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
updateContact(contact): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
this._httpClient.post('api/contacts-contacts/' + contact.id, {...contact})
|
||||
.subscribe(response => {
|
||||
this.getContacts();
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user data
|
||||
*
|
||||
* @param userData
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
updateUserData(userData): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this._httpClient.post('api/contacts-user/' + this.user.id, {...userData})
|
||||
.subscribe(response => {
|
||||
this.getUserData();
|
||||
this.getContacts();
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Deselect contacts
|
||||
*/
|
||||
deselectContacts(): void
|
||||
{
|
||||
this.selectedContacts = [];
|
||||
|
||||
// Trigger the next event
|
||||
this.onSelectedContactsChanged.next(this.selectedContacts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete contact
|
||||
*
|
||||
* @param contact
|
||||
*/
|
||||
deleteContact(contact): void
|
||||
{
|
||||
const contactIndex = this.contacts.indexOf(contact);
|
||||
this.contacts.splice(contactIndex, 1);
|
||||
this.onContactsChanged.next(this.contacts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete selected contacts
|
||||
*/
|
||||
deleteSelectedContacts(): void
|
||||
{
|
||||
for ( const contactId of this.selectedContacts )
|
||||
{
|
||||
const contact = this.contacts.find(_contact => {
|
||||
return _contact.id === contactId;
|
||||
});
|
||||
const contactIndex = this.contacts.indexOf(contact);
|
||||
this.contacts.splice(contactIndex, 1);
|
||||
}
|
||||
this.onContactsChanged.next(this.contacts);
|
||||
this.deselectContacts();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
<div fxFlex fxLayout="row" fxLayoutAlign="start center" class="p-24">
|
||||
|
||||
<div class="close-button-wrapper" fxFlex="0 1 auto" fxFlex.gt-sm="220px" (click)="deselectAll()">
|
||||
<button class="p-8" mat-button fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="mr-8">arrow_back</mat-icon>
|
||||
<span class="text-uppercase">Back</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div fxFlex fxLayout="row" fxLayoutAlign="end center" fxLayoutAlign.gt-sm="space-between center">
|
||||
|
||||
<div>
|
||||
<span class="selected-contacts-count">
|
||||
<span class="mr-4">{{selectedContacts.length}}</span>
|
||||
<span>selected</span>
|
||||
</span>
|
||||
|
||||
<button mat-icon-button [matMenuTriggerFor]="selectMenu">
|
||||
<mat-icon>arrow_drop_down</mat-icon>
|
||||
</button>
|
||||
<mat-menu #selectMenu="matMenu">
|
||||
<button mat-menu-item (click)="selectAll()">Select all</button>
|
||||
<button mat-menu-item (click)="deselectAll()">Deselect all</button>
|
||||
</mat-menu>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="multi-select-actions">
|
||||
<button mat-icon-button (click)="deleteSelectedContacts()" aria-label="delete selected">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -1,11 +0,0 @@
|
||||
@import "src/@fuse/scss/fuse";
|
||||
|
||||
:host {
|
||||
flex: 1;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
height: 120px;
|
||||
z-index: 99;
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { MatDialog, MatDialogRef } from '@angular/material';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { FuseConfirmDialogComponent } from '@fuse/components/confirm-dialog/confirm-dialog.component';
|
||||
|
||||
import { ContactsService } from 'app/main/apps/contacts/contacts.service';
|
||||
|
||||
@Component({
|
||||
selector : 'selected-bar',
|
||||
templateUrl: './selected-bar.component.html',
|
||||
styleUrls : ['./selected-bar.component.scss']
|
||||
})
|
||||
export class ContactsSelectedBarComponent implements OnInit, OnDestroy
|
||||
{
|
||||
confirmDialogRef: MatDialogRef<FuseConfirmDialogComponent>;
|
||||
hasSelectedContacts: boolean;
|
||||
isIndeterminate: boolean;
|
||||
selectedContacts: string[];
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ContactsService} _contactsService
|
||||
* @param {MatDialog} _matDialog
|
||||
*/
|
||||
constructor(
|
||||
private _contactsService: ContactsService,
|
||||
public _matDialog: MatDialog
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._contactsService.onSelectedContactsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(selectedContacts => {
|
||||
this.selectedContacts = selectedContacts;
|
||||
setTimeout(() => {
|
||||
this.hasSelectedContacts = selectedContacts.length > 0;
|
||||
this.isIndeterminate = (selectedContacts.length !== this._contactsService.contacts.length && selectedContacts.length > 0);
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Select all
|
||||
*/
|
||||
selectAll(): void
|
||||
{
|
||||
this._contactsService.selectContacts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deselect all
|
||||
*/
|
||||
deselectAll(): void
|
||||
{
|
||||
this._contactsService.deselectContacts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete selected contacts
|
||||
*/
|
||||
deleteSelectedContacts(): void
|
||||
{
|
||||
this.confirmDialogRef = this._matDialog.open(FuseConfirmDialogComponent, {
|
||||
disableClose: false
|
||||
});
|
||||
|
||||
this.confirmDialogRef.componentInstance.confirmMessage = 'Are you sure you want to delete all selected contacts?';
|
||||
|
||||
this.confirmDialogRef.afterClosed()
|
||||
.subscribe(result => {
|
||||
if ( result )
|
||||
{
|
||||
this._contactsService.deleteSelectedContacts();
|
||||
}
|
||||
this.confirmDialogRef = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
<div class="sidebar-content">
|
||||
|
||||
<div class="card mat-white-bg">
|
||||
|
||||
<!-- SIDEBAR HEADER -->
|
||||
<div class="header p-24" fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<!-- USER -->
|
||||
<img [src]="user.avatar" class="avatar mr-16" [alt]="user.name"/>
|
||||
<span class="h5">{{user.name}}</span>
|
||||
<!-- / USER -->
|
||||
|
||||
</div>
|
||||
<!-- / SIDEBAR HEADER -->
|
||||
|
||||
<!-- SIDEBAR CONTENT -->
|
||||
<div class="content py-16" fusePerfectScrollbar>
|
||||
|
||||
<div class="nav">
|
||||
|
||||
<div class="nav-item" aria-label="inbox">
|
||||
<a class="nav-link" matRipple (click)="changeFilter('all')"
|
||||
[ngClass]="{'active mat-accent-bg':filterBy ==='all'}">
|
||||
<span class="title">All Contacts</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="nav-item" aria-label="frequently contacted" (click)="changeFilter('frequent')">
|
||||
<a class="nav-link" matRipple [ngClass]="{'active mat-accent-bg':filterBy ==='frequent'}">
|
||||
<div class="title">Freequently contacted</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="nav-item" aria-label="starred" (click)="changeFilter('starred')">
|
||||
<a class="nav-link" matRipple [ngClass]="{'active mat-accent-bg':filterBy ==='starred'}">
|
||||
<div class="title">Starred Contacts</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / SIDEBAR CONTENT -->
|
||||
@@ -1,39 +0,0 @@
|
||||
@import "src/@fuse/scss/fuse";
|
||||
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 0 auto;
|
||||
height: 100%;
|
||||
|
||||
.sidebar-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0;
|
||||
|
||||
@include media-breakpoint(gt-sm) {
|
||||
padding: 24px 4px 24px 24px;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 0 1 auto;
|
||||
padding: 0;
|
||||
|
||||
@include media-breakpoint(gt-sm) {
|
||||
@include mat-elevation(4);
|
||||
}
|
||||
|
||||
> .header {
|
||||
flex: 0 1 auto;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
> .content {
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { ContactsService } from 'app/main/apps/contacts/contacts.service';
|
||||
|
||||
@Component({
|
||||
selector : 'contacts-main-sidebar',
|
||||
templateUrl: './main.component.html',
|
||||
styleUrls : ['./main.component.scss']
|
||||
})
|
||||
export class ContactsMainSidebarComponent implements OnInit, OnDestroy
|
||||
{
|
||||
user: any;
|
||||
filterBy: string;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ContactsService} _contactsService
|
||||
*/
|
||||
constructor(
|
||||
private _contactsService: ContactsService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.filterBy = this._contactsService.filterBy || 'all';
|
||||
|
||||
this._contactsService.onUserDataChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(user => {
|
||||
this.user = user;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy()
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Change the filter
|
||||
*
|
||||
* @param filter
|
||||
*/
|
||||
changeFilter(filter): void
|
||||
{
|
||||
this.filterBy = filter;
|
||||
this._contactsService.onFilterChanged.next(this.filterBy);
|
||||
}
|
||||
}
|
||||
@@ -1,509 +0,0 @@
|
||||
<div id="dashboard-analytics" class="page-layout blank grey-100-bg">
|
||||
|
||||
<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-lg-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 wrap" fxLayoutAlign="start end">
|
||||
|
||||
<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 wrap" fxLayoutAlign="start end">
|
||||
|
||||
<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 wrap" fxLayoutAlign="start end">
|
||||
|
||||
<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 wrap" fxLayout.gt-md="column">
|
||||
|
||||
<!-- Widget 7 -->
|
||||
<div class="mb-48" [ngClass.lt-lg]="'mr-32'" [ngClass.xs]="'mr-0'">
|
||||
|
||||
<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'" [ngClass.xs]="'mr-0'">
|
||||
|
||||
<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'" [ngClass.xs]="'mr-0'">
|
||||
|
||||
<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>
|
||||
@@ -1,58 +0,0 @@
|
||||
@import "src/@fuse/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;
|
||||
}
|
||||
|
||||
.fuse-card {
|
||||
|
||||
@include media-breakpoint-down('md') {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { AnalyticsDashboardService } from 'app/main/apps/dashboards/analytics/analytics.service';
|
||||
|
||||
@Component({
|
||||
selector : 'analytics-dashboard',
|
||||
templateUrl : './analytics.component.html',
|
||||
styleUrls : ['./analytics.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class AnalyticsDashboardComponent implements OnInit
|
||||
{
|
||||
widgets: any;
|
||||
widget1SelectedYear = '2016';
|
||||
widget5SelectedDay = 'today';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {AnalyticsDashboardService} _analyticsDashboardService
|
||||
*/
|
||||
constructor(
|
||||
private _analyticsDashboardService: AnalyticsDashboardService
|
||||
)
|
||||
{
|
||||
// Register the custom chart.js plugin
|
||||
this._registerCustomChartJSPlugin();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Get the widgets from the service
|
||||
this.widgets = this._analyticsDashboardService.widgets;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Private methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Register a custom plugin
|
||||
*/
|
||||
private _registerCustomChartJSPlugin(): void
|
||||
{
|
||||
(<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();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { MatButtonModule, MatFormFieldModule, MatIconModule, MatMenuModule, MatSelectModule, MatTabsModule } from '@angular/material';
|
||||
import { AgmCoreModule } from '@agm/core';
|
||||
import { ChartsModule } from 'ng2-charts';
|
||||
import { NgxChartsModule } from '@swimlane/ngx-charts';
|
||||
|
||||
import { FuseSharedModule } from '@fuse/shared.module';
|
||||
import { FuseWidgetModule } from '@fuse/components/widget/widget.module';
|
||||
|
||||
import { AnalyticsDashboardComponent } from 'app/main/apps/dashboards/analytics/analytics.component';
|
||||
import { AnalyticsDashboardService } from 'app/main/apps/dashboards/analytics/analytics.service';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path : '**',
|
||||
component: AnalyticsDashboardComponent,
|
||||
resolve : {
|
||||
data: AnalyticsDashboardService
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AnalyticsDashboardComponent
|
||||
],
|
||||
imports : [
|
||||
RouterModule.forChild(routes),
|
||||
|
||||
MatButtonModule,
|
||||
MatFormFieldModule,
|
||||
MatIconModule,
|
||||
MatMenuModule,
|
||||
MatSelectModule,
|
||||
MatTabsModule,
|
||||
|
||||
AgmCoreModule.forRoot({
|
||||
apiKey: 'AIzaSyD81ecsCj4yYpcXSLFcYU97PvRsE_X8Bx8'
|
||||
}),
|
||||
ChartsModule,
|
||||
NgxChartsModule,
|
||||
|
||||
FuseSharedModule,
|
||||
FuseWidgetModule
|
||||
],
|
||||
providers : [
|
||||
AnalyticsDashboardService
|
||||
]
|
||||
})
|
||||
export class AnalyticsDashboardModule
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Injectable()
|
||||
export class AnalyticsDashboardService implements Resolve<any>
|
||||
{
|
||||
widgets: any[];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {HttpClient} _httpClient
|
||||
*/
|
||||
constructor(
|
||||
private _httpClient: HttpClient
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.getWidgets()
|
||||
]).then(
|
||||
() => {
|
||||
resolve();
|
||||
},
|
||||
reject
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get widgets
|
||||
*
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
getWidgets(): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this._httpClient.get('api/analytics-dashboard-widgets')
|
||||
.subscribe((response: any) => {
|
||||
this.widgets = response;
|
||||
resolve(response);
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user