Database, eventbus, pluginloader fixes
This commit is contained in:
+1
-1
@@ -43,7 +43,7 @@
|
||||
"sqlite3": "^4.1.0",
|
||||
"trash": "^6.0.0",
|
||||
"upgiter": "^1.0.4",
|
||||
"uuid": "^3.3.2"
|
||||
"uuid": "^3.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.0",
|
||||
|
||||
+7
-10
@@ -5,15 +5,13 @@ import { promises as fs, mkdirSync } from "fs"
|
||||
import { RPCServer } from 'rpclibrary/js/src/Backend'
|
||||
import { AdminConf, TableDefiniton } from './Types';
|
||||
import { RPCConfigLoader } from './RPCConfigLoader';
|
||||
|
||||
import { RPCPluginLoader } from './PluginLoader';
|
||||
import * as Path from 'path'
|
||||
|
||||
import Knex = require('knex');
|
||||
import http = require('http');
|
||||
import express = require('express');
|
||||
import { TableDefinitionExporter } from './Interfaces';
|
||||
import { FrontworkEventBus } from './Eventbus';
|
||||
import { Plugin } from './Plugin';
|
||||
|
||||
const logger = getLogger("admin", 'debug')
|
||||
|
||||
@@ -22,14 +20,12 @@ implements TableDefinitionExporter {
|
||||
|
||||
private express
|
||||
private httpServer
|
||||
private pluginLoader:RPCPluginLoader = new RPCPluginLoader(this)
|
||||
private eventBus:FrontworkEventBus = new FrontworkEventBus(this)
|
||||
private plugins: Plugin[] = []
|
||||
config: RPCConfigLoader<AdminConf>
|
||||
knex:Knex
|
||||
|
||||
constructor(){
|
||||
this.eventBus = new FrontworkEventBus(this)
|
||||
}
|
||||
constructor(){}
|
||||
|
||||
async start(){
|
||||
this.initConfig()
|
||||
@@ -74,7 +70,8 @@ implements TableDefinitionExporter {
|
||||
private startWebsocket(){
|
||||
new RPCServer(20000, [
|
||||
this.config,
|
||||
...this.plugins
|
||||
this.pluginLoader,
|
||||
this.eventBus
|
||||
])
|
||||
}
|
||||
|
||||
@@ -134,7 +131,7 @@ implements TableDefinitionExporter {
|
||||
logger.info("Webserver stopped")
|
||||
}
|
||||
|
||||
public async makeKnex():Promise<Knex>{
|
||||
async makeKnex():Promise<Knex>{
|
||||
const conf:Knex.Config = this.config.getConfigKey("dbConf")
|
||||
|
||||
logger.debug("Making new knex:", conf)
|
||||
@@ -157,7 +154,7 @@ implements TableDefinitionExporter {
|
||||
getTableDefinitions(): TableDefiniton[]{
|
||||
return [
|
||||
this.eventBus,
|
||||
...this.plugins
|
||||
...this.pluginLoader.getPlugins()
|
||||
].flatMap(exporter => exporter.getTableDefinitions())
|
||||
}
|
||||
}
|
||||
|
||||
+46
-6
@@ -1,8 +1,10 @@
|
||||
import { RPCExporter } from "rpclibrary/js/src/Interfaces";
|
||||
import { SubscriptionResponse, ErrorResponse } from "rpclibrary/js/src/Types";
|
||||
import { makeSubResponse } from "rpclibrary/js/src/Utils";
|
||||
import { SubscriptionResponse, ErrorResponse, SuccessResponse } from "rpclibrary/js/src/Types";
|
||||
import { FrontworkAdmin } from "./Admin";
|
||||
import { TableDefinitionExporter } from "./Interfaces";
|
||||
import { getLogger } from 'frontblock-generic/Types';
|
||||
|
||||
import * as uuid from 'uuid/v4'
|
||||
|
||||
export type NotificationSeverity = 'Info' | 'Important' | 'Error'
|
||||
|
||||
@@ -22,25 +24,63 @@ export type EventbusIfc = {
|
||||
}
|
||||
}
|
||||
|
||||
const logger = getLogger("Eventbus", 'debug')
|
||||
|
||||
export class FrontworkEventBus
|
||||
implements RPCExporter<EventbusIfc, "Eventbus">, TableDefinitionExporter {
|
||||
name = "Eventbus" as "Eventbus"
|
||||
private subscriptions : { [uid in string]:Function } = {}
|
||||
|
||||
constructor(private admin: FrontworkAdmin){
|
||||
this.admin
|
||||
}
|
||||
|
||||
async subscribeNotifications(callback) : Promise<SubscriptionResponse>{
|
||||
const uid = uuid()
|
||||
this.subscriptions[uid] = callback
|
||||
return { result: 'Success', uuid: uid }
|
||||
}
|
||||
|
||||
async getNotificationLog() : Promise<Notification[]>{
|
||||
try{
|
||||
return await this.admin.knex.select('*').from('notifications')
|
||||
}catch(e){
|
||||
logger.error(e)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
async unsubscribeNotifications(uid:string) : Promise<SuccessResponse | ErrorResponse>{
|
||||
if(!this.subscriptions[uid]) return { result: 'Error', message: "Unknown subscription" }
|
||||
delete this.subscriptions[uid]
|
||||
return { result: 'Success' }
|
||||
}
|
||||
|
||||
async pushNotification(notification: Notification){
|
||||
if(!notification.time) notification.time = Date.now()
|
||||
logger.debug("inserting into notifications", notification)
|
||||
try{
|
||||
await this.admin.knex('notifications').insert(notification)
|
||||
}catch(e){
|
||||
logger.error(e)
|
||||
throw e
|
||||
}
|
||||
|
||||
Object.values(this.subscriptions).forEach(callback => {
|
||||
callback(notification)
|
||||
})
|
||||
}
|
||||
|
||||
exportRPCs(){
|
||||
return [{
|
||||
name: 'getNotificationLog' as 'getNotificationLog',
|
||||
call: async () => []
|
||||
call: async () => await this.getNotificationLog()
|
||||
},{
|
||||
name: 'pushNotification' as 'pushNotification',
|
||||
call: async () => {}
|
||||
call: async (notification: Notification) => { return await this.pushNotification(notification) }
|
||||
},{
|
||||
name: 'subscribeNotificaitons' as 'subscribeNotifications',
|
||||
hook: async (callback: Function) => {
|
||||
return makeSubResponse({})
|
||||
return await this.subscribeNotifications(callback)
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Plugin } from "./Plugin";
|
||||
import { FrontworkAdmin } from "./Admin";
|
||||
|
||||
class PluginLoader {
|
||||
private runningPlugins: Plugin[]
|
||||
private runningPlugins: Plugin[] = []
|
||||
private pluginUpdaters:{[name in string]:Git.Updater} = {}
|
||||
|
||||
constructor(private admin:FrontworkAdmin){}
|
||||
@@ -33,9 +33,9 @@ class PluginLoader {
|
||||
//logger.warn("Cloning fb-dist/"+name+".git into ./plugins/"+name+" ..."+(force?" USING FORCE!":""))
|
||||
this.pluginUpdaters[name] = new Git.Updater({
|
||||
schema: 'https',
|
||||
localPath: './dist',
|
||||
localPath: './plugins/'+name,
|
||||
remoteHost: 'www.versioncontrol.me',
|
||||
remotePath: 'frontwork-distribution',
|
||||
remotePath: 'frontblock-distribution',
|
||||
repoName: name
|
||||
})
|
||||
const status = await this.pluginUpdaters[name].cloneRepo(force)
|
||||
@@ -63,7 +63,7 @@ class PluginLoader {
|
||||
|
||||
let evalstr = "../plugins/"+name+"/Plugin"
|
||||
const pluginClass = await eval('require')(evalstr)
|
||||
const pluginObj = new pluginClass.default(this)
|
||||
const pluginObj = new pluginClass.default(this.admin)
|
||||
try{
|
||||
if(pluginObj.start)
|
||||
await pluginObj.start()
|
||||
@@ -137,7 +137,7 @@ export type PluginLoaderIfc = {
|
||||
}
|
||||
}
|
||||
|
||||
class RPCPluginLoader
|
||||
export class RPCPluginLoader
|
||||
extends PluginLoader
|
||||
implements RPCExporter<PluginLoaderIfc, "PluginLoader">{
|
||||
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
kind: pipeline
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: restore cache
|
||||
image: drillster/drone-volume-cache
|
||||
settings:
|
||||
restore: true
|
||||
mount:
|
||||
- ./node_modules
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /cache
|
||||
|
||||
- name: npm install
|
||||
image: node:12
|
||||
commands:
|
||||
- npm install
|
||||
|
||||
- name: npm run build
|
||||
image: node:12
|
||||
commands:
|
||||
- npm run build
|
||||
|
||||
- name: rebuild cache
|
||||
image: drillster/drone-volume-cache
|
||||
settings:
|
||||
rebuild: true
|
||||
mount:
|
||||
- ./node_modules
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /cache
|
||||
|
||||
- name: deploy static files
|
||||
image: node:12
|
||||
commands:
|
||||
- git config --global user.email "${DRONE_COMMIT_AUTHOR_EMAIL}"
|
||||
- git config --global user.name "${DRONE_COMMIT_AUTHOR}"
|
||||
- git clone https://gitea.frontblock.me/fb-dist/${DRONE_REPO_NAME}.git
|
||||
- cp -r ./dist/* ./${DRONE_REPO_NAME}
|
||||
- cd ./${DRONE_REPO_NAME}
|
||||
- git add -A
|
||||
- git commit --allow-empty -m "drone taged as version ${DRONE_TAG}"
|
||||
- git tag ${DRONE_TAG}
|
||||
- git push https://$GIT_USER:$GIT_PASSWORD@gitea.frontblock.me/fb-dist/${DRONE_REPO_NAME}.git master ${DRONE_TAG}
|
||||
environment:
|
||||
GIT_USER:
|
||||
from_secret: git_user
|
||||
GIT_PASSWORD:
|
||||
from_secret: git_password
|
||||
when:
|
||||
event:
|
||||
- tag
|
||||
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
host:
|
||||
path: /tmp
|
||||
@@ -1,4 +1,4 @@
|
||||
# Editor configuration, see https://editorconfig.org
|
||||
# Editor configuration, see http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
|
||||
+5
-12
@@ -1,19 +1,11 @@
|
||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# compiled output
|
||||
/dist
|
||||
/tmp
|
||||
/out-tsc
|
||||
# Only exists if Bazel was run
|
||||
/bazel-out
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# profiling files
|
||||
chrome-profiler-events.json
|
||||
speed-measure-plugin.json
|
||||
|
||||
# IDEs and editors
|
||||
/.idea
|
||||
.project
|
||||
@@ -29,7 +21,6 @@ speed-measure-plugin.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
.history/*
|
||||
|
||||
# misc
|
||||
/.sass-cache
|
||||
@@ -37,12 +28,14 @@ speed-measure-plugin.json
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
testem.log
|
||||
/typings
|
||||
/docs
|
||||
|
||||
# e2e
|
||||
/e2e/*.js
|
||||
/e2e/*.map
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
src/assets/*.js
|
||||
@@ -1,6 +0,0 @@
|
||||
[submodule "src/app/paymentmanager"]
|
||||
path = src/app/paymentmanager
|
||||
url = ssh://git@gitea.frontblock.me:2222/fb-plugin/paymentmanager.git
|
||||
[submodule "src/app/wallet"]
|
||||
path = src/app/wallet
|
||||
url = ssh://git@gitea.frontblock.me:2222/fb-plugin/wallet.git
|
||||
+63
-14
@@ -1,27 +1,76 @@
|
||||
# Dashboard
|
||||
# ngx-admin [<img src="https://i.imgur.com/oMcxwZ0.png" alt="Eva Design System" height="20px" />](https://eva.design) [](https://travis-ci.org/akveo/ngx-admin) [](https://david-dm.org/akveo/ng2-admin)
|
||||
|
||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.1.0.
|
||||
[Who uses ngx-admin?](https://github.com/akveo/ngx-admin/issues/1645)| [Documentation](https://akveo.github.io/ngx-admin/?utm_source=github&utm_medium=ngx_admin_readme&utm_campaign=themes) | [Installation Guidelines](https://akveo.github.io/ngx-admin/docs/getting-started/what-is-ngxadmin?utm_source=github&utm_medium=ngx_admin_readme&utm_campaign=themes)
|
||||
|
||||
## Development server
|
||||
# Admin template based on Angular 8+ and <a href="https://github.com/akveo/nebular">Nebular</a>
|
||||
<a target="_blank" href="http://akveo.com/ngx-admin/pages/dashboard?theme=corporate&utm_source=github&utm_medium=ngx_admin_readme&utm_campaign=main_pic"><img src="https://i.imgur.com/mFdqvgG.png"/></a>
|
||||
|
||||
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
||||
### Backend Integration Bundles
|
||||
Easy way to integrate ngx-admin with backend (.NET, Node.js, Java etc.).
|
||||
|
||||
## Code scaffolding
|
||||
<a target="_blank" href="https://store.akveo.com/collections/all/?utm_source=github&utm_medium=ngx_admin_readme">
|
||||
<img src="https://i.imgur.com/oiQHhop.png"/>
|
||||
</a>
|
||||
|
||||
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
|
||||
[Checkout our Store](https://store.akveo.com/collections/all/?utm_source=github&utm_medium=ngx_admin_readme) for ready to use Backend Bundles.
|
||||
|
||||
## Build
|
||||
### With 4 stunning visual themes
|
||||
|
||||
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
#### Default
|
||||
<a target="_blank" href="http://akveo.com/ngx-admin/pages/dashboard?theme=default&utm_source=github&utm_medium=ngx_admin_readme&utm_campaign=themes"><img src="https://i.imgur.com/Kn3xDKQ.png"/></a>
|
||||
|
||||
## Running end-to-end tests
|
||||
#### Dark
|
||||
<a target="_blank" href="http://akveo.com/ngx-admin/pages/dashboard?theme=dark&utm_source=github&utm_medium=ngx_admin_readme&utm_campaign=themes"><img src="https://i.imgur.com/FAn5iXY.png"/></a>
|
||||
|
||||
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
|
||||
#### Cosmic
|
||||
<a target="_blank" href="http://akveo.com/ngx-admin/pages/dashboard?theme=cosmic&utm_source=github&utm_medium=ngx_admin_readme&utm_campaign=themes"><img src="https://i.imgur.com/iJu2YDF.png"/></a>
|
||||
|
||||
## Further help
|
||||
#### Corporate
|
||||
<a target="_blank" href="http://akveo.com/ngx-admin/pages/dashboard?theme=corporate&utm_source=github&utm_medium=ngx_admin_readme&utm_campaign=themes"><img src="https://i.imgur.com/GpUt6NW.png"/></a>
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
||||
### What's included:
|
||||
|
||||
- Angular 8+ & Typescript
|
||||
- Bootstrap 4+ & SCSS
|
||||
- Responsive layout
|
||||
- RTL support
|
||||
- High resolution
|
||||
- Flexibly configurable themes with **hot-reload** (3 themes included)
|
||||
- Authentication module with multiple providers
|
||||
- 40+ Angular Components
|
||||
- 60+ Usage Examples
|
||||
|
||||
### Demo
|
||||
|
||||
<a target="_blank" href="http://akveo.com/ngx-admin/">Live Demo</a>
|
||||
|
||||
## Documentation
|
||||
This template is using [Nebular](https://github.com/akveo/nebular) modules set, [here you can find documentation and other useful articles](https://akveo.github.io/nebular/docs/guides/install-based-on-starter-kit).
|
||||
|
||||
### Empty starter kit
|
||||
Don't need all the pages and modules and just looking for an empty starter kit for your next project? Check out our [starter-kit branch](https://github.com/akveo/ngx-admin/tree/starter-kit).
|
||||
|
||||
## BrowserStack
|
||||
This project runs its tests on multiple desktop and mobile browsers using [BrowserStack](http://www.browserstack.com).
|
||||
|
||||
<img src="https://cloud.githubusercontent.com/assets/131406/22254249/534d889e-e254-11e6-8427-a759fb23b7bd.png" height="40" />
|
||||
|
||||
## More from Akveo
|
||||
|
||||
- [Eva Icons](https://github.com/akveo/eva-icons) - 480+ beautiful Open Source icons
|
||||
- [Nebular](https://github.com/akveo/nebular) - Angular Components, Auth and Security
|
||||
|
||||
### How can I support developers?
|
||||
- Star our GitHub repo :star:
|
||||
- Create pull requests, submit bugs, suggest new features or documentation updates :wrench:
|
||||
- Follow us on [Twitter](https://twitter.com/akveo_inc) :feet:
|
||||
- Like our page on [Facebook](https://www.facebook.com/akveo/) :thumbsup:
|
||||
|
||||
### Looking for engineering services?
|
||||
Visit [our homepage](http://akveo.com/) or simply leave us a message to [contact@akveo.com](mailto:contact@akveo.com). We will be happy to work with you!
|
||||
|
||||
### From Developers
|
||||
Made with :heart: by [Akveo team](http://akveo.com/). Follow us on [Twitter](https://twitter.com/akveo_inc) to get the latest news first!
|
||||
We're always happy to receive your feedback!
|
||||
|
||||
+111
-78
@@ -3,147 +3,180 @@
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"dashboard": {
|
||||
"projectType": "application",
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"style": "scss"
|
||||
}
|
||||
},
|
||||
"ngx-admin-demo": {
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"prefix": "app",
|
||||
"projectType": "application",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-builders/custom-webpack:browser",
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"customWebpackConfig": {"path": "./custom-webpack.config.js"},
|
||||
|
||||
"preserveSymlinks": true,
|
||||
"rebaseRootRelativeCssUrls": true,
|
||||
"outputPath": "dist",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"tsConfig": "src/tsconfig.app.json",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
|
||||
"aot": false,
|
||||
"assets": [
|
||||
"src/assets",
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
"src/favicon.png",
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "node_modules/leaflet/dist/images",
|
||||
"output": "/assets/img/markers"
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.scss",
|
||||
"node_modules/@clr/icons/clr-icons.min.css",
|
||||
"node_modules/@clr/ui/clr-ui-dark.min.css"
|
||||
"node_modules/bootstrap/dist/css/bootstrap.css",
|
||||
"node_modules/typeface-exo/index.css",
|
||||
"node_modules/roboto-fontface/css/roboto/roboto-fontface.css",
|
||||
"node_modules/ionicons/scss/ionicons.scss",
|
||||
"node_modules/@fortawesome/fontawesome-free/css/all.css",
|
||||
"node_modules/socicon/css/socicon.css",
|
||||
"node_modules/nebular-icons/scss/nebular-icons.scss",
|
||||
"node_modules/angular-tree-component/dist/angular-tree-component.css",
|
||||
"node_modules/pace-js/templates/pace-theme-flash.tmpl.css",
|
||||
"node_modules/leaflet/dist/leaflet.css",
|
||||
"src/app/@theme/styles/styles.scss"
|
||||
],
|
||||
"scripts": [
|
||||
"node_modules/systemjs/dist/system.js",
|
||||
"node_modules/@webcomponents/custom-elements/custom-elements.min.js",
|
||||
"node_modules/@clr/icons/clr-icons.min.js"
|
||||
"node_modules/pace-js/pace.min.js",
|
||||
"node_modules/tinymce/tinymce.min.js",
|
||||
"node_modules/tinymce/themes/modern/theme.min.js",
|
||||
"node_modules/tinymce/plugins/link/plugin.min.js",
|
||||
"node_modules/tinymce/plugins/paste/plugin.min.js",
|
||||
"node_modules/tinymce/plugins/table/plugin.min.js",
|
||||
"node_modules/echarts/dist/echarts.min.js",
|
||||
"node_modules/echarts/dist/extension/bmap.min.js",
|
||||
"node_modules/chart.js/dist/Chart.min.js",
|
||||
"node_modules/rpclibrary/js/browser/rpclibrary.browser.js"
|
||||
]
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"tsConfig": "tsconfig.prod.json",
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"extractCss": true,
|
||||
"namedChunks": false,
|
||||
"aot": false,
|
||||
"aot": true,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "2mb",
|
||||
"maximumError": "5mb"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"prodlike": {
|
||||
"tsConfig": "tsconfig.prod.json",
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prodlike.ts"
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-builders/custom-webpack:dev-server",
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "dashboard:build"
|
||||
"browserTarget": "ngx-admin-demo:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "dashboard:build:production"
|
||||
},
|
||||
"prodlike": {
|
||||
"browserTarget": "dashboard:build:prodlike"
|
||||
"browserTarget": "ngx-admin-demo:build:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"browserTarget": "dashboard:build"
|
||||
"browserTarget": "ngx-admin-demo:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-builders/custom-webpack:karma",
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"karmaConfig": "./karma.conf.js",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
"tsConfig": "src/tsconfig.spec.json",
|
||||
"scripts": [
|
||||
"node_modules/pace-js/pace.min.js",
|
||||
"node_modules/tinymce/tinymce.min.js",
|
||||
"node_modules/tinymce/themes/modern/theme.min.js",
|
||||
"node_modules/tinymce/plugins/link/plugin.min.js",
|
||||
"node_modules/tinymce/plugins/paste/plugin.min.js",
|
||||
"node_modules/tinymce/plugins/table/plugin.min.js",
|
||||
"node_modules/echarts/dist/echarts.min.js",
|
||||
"node_modules/echarts/dist/extension/bmap.min.js",
|
||||
"node_modules/chart.js/dist/Chart.min.js"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.scss"
|
||||
"node_modules/bootstrap/dist/css/bootstrap.css",
|
||||
"node_modules/typeface-exo/index.css",
|
||||
"node_modules/roboto-fontface/css/roboto/roboto-fontface.css",
|
||||
"node_modules/ionicons/scss/ionicons.scss",
|
||||
"node_modules/font-awesome/scss/font-awesome.scss",
|
||||
"node_modules/socicon/css/socicon.css",
|
||||
"node_modules/nebular-icons/scss/nebular-icons.scss",
|
||||
"node_modules/pace-js/templates/pace-theme-flash.tmpl.css",
|
||||
"src/app/@theme/styles/styles.scss"
|
||||
],
|
||||
"scripts": []
|
||||
"assets": [
|
||||
"src/assets",
|
||||
"src/favicon.ico",
|
||||
"src/favicon.png",
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "node_modules/leaflet/dist/images",
|
||||
"output": "/assets/img/markers"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-builders/custom-webpack:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"tsconfig.app.json",
|
||||
"tsconfig.spec.json",
|
||||
"e2e/tsconfig.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**",
|
||||
"**/backend/**"
|
||||
]
|
||||
}
|
||||
},
|
||||
"e2e": {
|
||||
"builder": "@angular-builders/custom-webpack:protractor",
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"protractorConfig": "e2e/protractor.conf.js",
|
||||
"devServerTarget": "dashboard:serve"
|
||||
"tsConfig": [
|
||||
"src/tsconfig.app.json",
|
||||
"src/tsconfig.spec.json"
|
||||
],
|
||||
"typeCheck": true,
|
||||
"exclude": []
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"devServerTarget": "dashboard:serve:production"
|
||||
"ngx-admin-demo-e2e": {
|
||||
"root": "",
|
||||
"sourceRoot": "",
|
||||
"projectType": "application",
|
||||
"architect": {
|
||||
"e2e": {
|
||||
"builder": "@angular-devkit/build-angular:protractor",
|
||||
"options": {
|
||||
"protractorConfig": "./protractor.conf.js",
|
||||
"devServerTarget": "ngx-admin-demo:serve"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"e2e/tsconfig.e2e.json"
|
||||
],
|
||||
"exclude": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}},
|
||||
"defaultProject": "dashboard"
|
||||
},
|
||||
"defaultProject": "ngx-admin-demo",
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"prefix": "ngx",
|
||||
"styleext": "scss"
|
||||
},
|
||||
"@schematics/angular:directive": {
|
||||
"prefix": "ngx"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,4 +9,4 @@
|
||||
last 2 versions
|
||||
Firefox ESR
|
||||
not dead
|
||||
not IE 9-11 # For IE 9-11 support, remove 'not'.
|
||||
IE 11
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
externals: ['log4js']
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
import { AppPage } from './app.po';
|
||||
import { browser, logging } from 'protractor';
|
||||
|
||||
describe('workspace-project App', () => {
|
||||
let page: AppPage;
|
||||
|
||||
beforeEach(() => {
|
||||
page = new AppPage();
|
||||
});
|
||||
|
||||
it('should display welcome message', () => {
|
||||
page.navigateTo();
|
||||
expect(page.getTitleText()).toEqual('Welcome to dashboard!');
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
// Assert that there are no errors emitted from the browser
|
||||
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
|
||||
expect(logs).not.toContain(jasmine.objectContaining({
|
||||
level: logging.Level.SEVERE,
|
||||
} as logging.Entry));
|
||||
});
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
import { browser, by, element } from 'protractor';
|
||||
|
||||
export class AppPage {
|
||||
navigateTo() {
|
||||
return browser.get(browser.baseUrl) as Promise<any>;
|
||||
}
|
||||
|
||||
getTitleText() {
|
||||
return element(by.css('app-root h1')).getText() as Promise<string>;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/e2e",
|
||||
"baseUrl": "./",
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"types": [
|
||||
@@ -2,7 +2,7 @@
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
const configuration = {
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
@@ -16,17 +16,30 @@ module.exports = function (config) {
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: require('path').join(__dirname, './coverage/dashboard'),
|
||||
reports: ['html', 'lcovonly', 'text-summary'],
|
||||
dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ],
|
||||
fixWebpackSourcePaths: true
|
||||
},
|
||||
angularCli: {
|
||||
environment: 'dev'
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true
|
||||
});
|
||||
customLaunchers: {
|
||||
Chrome_travis_ci: {
|
||||
base: 'Chrome',
|
||||
flags: ['--no-sandbox']
|
||||
}
|
||||
},
|
||||
singleRun: false
|
||||
};
|
||||
|
||||
if (process.env.TRAVIS) {
|
||||
configuration.browsers = ['Chrome_travis_ci'];
|
||||
}
|
||||
|
||||
config.set(configuration);
|
||||
};
|
||||
|
||||
Generated
+12283
-3635
File diff suppressed because it is too large
Load Diff
+100
-57
@@ -1,70 +1,113 @@
|
||||
{
|
||||
"name": "dashboard",
|
||||
"version": "0.0.0",
|
||||
"name": "ngx-admin",
|
||||
"version": "4.0.1",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/akveo/ngx-admin.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/akveo/ngx-admin/issues"
|
||||
},
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve --aot=false --optimization=false --proxy-config proxy.conf.json ",
|
||||
"start-prodlike": "npm run build-assets && ng serve --aot=false --optimization=false --proxy-config proxy.conf.json --configuration=prodlike",
|
||||
"build": "rm -f src/assets/*.js; ng build --prod --aot=false --optimization=false --build-optimizer=false",
|
||||
"build-assets": "npm run copy-frontends; npm run deep-clean-plugins",
|
||||
"get-submodules": "git submodule update --init && git submodule foreach git checkout master",
|
||||
"copy-frontends": "for module in $(git config --file .gitmodules --get-regexp path | awk '{ print $2 }'); do npm i --prefix $module && npm run --prefix $module build && cp $module/dist/FrontendPlugin.js ./src/assets/$(basename $module).js; done",
|
||||
"deep-clean-plugins": "for module in $(git config --file .gitmodules --get-regexp path | awk '{ print $2 }'); do rm -rf $module/node_modules; done",
|
||||
"conventional-changelog": "conventional-changelog",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"build:prod": "npm run build -- --prod --aot",
|
||||
"test": "ng test",
|
||||
"test:coverage": "rimraf coverage && npm run test -- --code-coverage",
|
||||
"lint": "ng lint",
|
||||
"lint:fix": "ng lint ngx-admin-demo --fix",
|
||||
"lint:styles": "stylelint ./src/**/*.scss",
|
||||
"lint:ci": "npm run lint && npm run lint:styles",
|
||||
"pree2e": "webdriver-manager update --standalone false --gecko false",
|
||||
"e2e": "ng e2e",
|
||||
"update-frontblock": "npm remove frontblock frontblock-generic; npm install frontblock-generic@latest frontblock@latest"
|
||||
"docs": "compodoc -p src/tsconfig.app.json -d docs",
|
||||
"docs:serve": "compodoc -p src/tsconfig.app.json -d docs -s",
|
||||
"prepush": "npm run lint:ci",
|
||||
"release:changelog": "npm run conventional-changelog -- -p angular -i CHANGELOG.md -s"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~8.2.1",
|
||||
"@angular/common": "~8.2.1",
|
||||
"@angular/compiler": "~8.2.1",
|
||||
"@angular/core": "~8.2.1",
|
||||
"@angular/forms": "~8.2.1",
|
||||
"@angular/platform-browser": "~8.2.1",
|
||||
"@angular/platform-browser-dynamic": "~8.2.1",
|
||||
"@angular/router": "~8.2.1",
|
||||
"@clr/angular": "^2.1.1",
|
||||
"@clr/icons": "^2.1.1",
|
||||
"@clr/ui": "^2.1.1",
|
||||
"@types/knex": "^0.16.1",
|
||||
"@webcomponents/custom-elements": "^1.0.0",
|
||||
"btc-hdkey": "0.0.17",
|
||||
"coinselect": "^3.1.11",
|
||||
"frontblock": "^0.15.1",
|
||||
"frontblock-generic": "^0.34.1",
|
||||
"key-file-storage": "^2.2.4",
|
||||
"node-fetch": "^2.6.0",
|
||||
"rxjs": "~6.5.2",
|
||||
"stream": "0.0.2",
|
||||
"systemjs": "^0.21.3",
|
||||
"@agm/core": "^1.0.0-beta.5",
|
||||
"@angular/animations": "^8.0.0",
|
||||
"@angular/cdk": "^8.0.0",
|
||||
"@angular/common": "^8.0.0",
|
||||
"@angular/compiler": "^8.0.0",
|
||||
"@angular/core": "^8.0.0",
|
||||
"@angular/forms": "^8.0.0",
|
||||
"@angular/platform-browser": "^8.0.0",
|
||||
"@angular/platform-browser-dynamic": "^8.0.0",
|
||||
"@angular/router": "^8.0.0",
|
||||
"@asymmetrik/ngx-leaflet": "3.0.1",
|
||||
"@nebular/auth": "4.4.0",
|
||||
"@nebular/eva-icons": "4.4.0",
|
||||
"@nebular/security": "4.4.0",
|
||||
"@nebular/theme": "4.4.0",
|
||||
"@swimlane/ngx-charts": "^10.0.0",
|
||||
"angular-tree-component": "7.2.0",
|
||||
"angular2-chartjs": "0.4.1",
|
||||
"angular2-toaster": "^7.0.0",
|
||||
"bootstrap": "4.3.1",
|
||||
"chart.js": "2.7.1",
|
||||
"ckeditor": "4.7.3",
|
||||
"classlist.js": "1.1.20150312",
|
||||
"core-js": "2.5.1",
|
||||
"echarts": "^4.0.2",
|
||||
"eva-icons": "^1.1.0",
|
||||
"intl": "1.2.5",
|
||||
"ionicons": "2.0.1",
|
||||
"leaflet": "1.2.0",
|
||||
"nebular-icons": "1.1.0",
|
||||
"ng2-ckeditor": "^1.2.2",
|
||||
"ng2-completer": "2.0.8",
|
||||
"ng2-smart-table": "1.3.5",
|
||||
"ngx-echarts": "^4.0.1",
|
||||
"node-sass": "^4.12.0",
|
||||
"normalize.css": "6.0.0",
|
||||
"pace-js": "1.0.2",
|
||||
"roboto-fontface": "0.8.0",
|
||||
"rpclibrary": "^1.3.17",
|
||||
"rxjs": "6.5.2",
|
||||
"rxjs-compat": "6.3.0",
|
||||
"socicon": "3.0.5",
|
||||
"tinymce": "4.5.7",
|
||||
"tslib": "^1.9.0",
|
||||
"uuid": "^3.3.2",
|
||||
"zone.js": "~0.10.1"
|
||||
"typeface-exo": "0.0.22",
|
||||
"web-animations-js": "github:angular/web-animations-js#release_pr208",
|
||||
"zone.js": "~0.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-builders/custom-webpack": "^8.2.0",
|
||||
"@angular-builders/dev-server": "^7.3.1",
|
||||
"@angular-devkit/build-angular": "^0.802.2",
|
||||
"@angular/cli": "^8.2.2",
|
||||
"@angular/compiler-cli": "~8.2.1",
|
||||
"@angular/language-service": "~8.2.1",
|
||||
"@types/jasmine": "~3.4.0",
|
||||
"@types/jasminewd2": "~2.0.3",
|
||||
"@types/node": "^12.7.1",
|
||||
"@types/systemjs": "^0.20.6",
|
||||
"codelyzer": "^5.0.0",
|
||||
"jasmine-core": "~3.4.0",
|
||||
"jasmine-spec-reporter": "~4.2.1",
|
||||
"karma": "~4.2.0",
|
||||
"karma-chrome-launcher": "~3.0.0",
|
||||
"karma-coverage-istanbul-reporter": "~2.1.0",
|
||||
"karma-jasmine": "~2.0.1",
|
||||
"karma-jasmine-html-reporter": "^1.4.0",
|
||||
"protractor": "~5.4.0",
|
||||
"ts-node": "~8.3.0",
|
||||
"tslint": "~5.18.0",
|
||||
"typescript": "~3.5.3"
|
||||
"@angular-devkit/build-angular": "~0.800.2",
|
||||
"@angular/cli": "^8.0.2",
|
||||
"@angular/compiler-cli": "^8.0.0",
|
||||
"@angular/language-service": "8.0.0",
|
||||
"@compodoc/compodoc": "1.0.1",
|
||||
"@fortawesome/fontawesome-free": "^5.2.0",
|
||||
"@types/d3-color": "1.0.5",
|
||||
"@types/googlemaps": "^3.30.4",
|
||||
"@types/jasmine": "2.5.54",
|
||||
"@types/jasminewd2": "2.0.3",
|
||||
"@types/leaflet": "1.2.3",
|
||||
"@types/node": "6.0.90",
|
||||
"codelyzer": "^5.0.1",
|
||||
"conventional-changelog-cli": "1.3.4",
|
||||
"husky": "0.13.3",
|
||||
"jasmine-core": "2.6.4",
|
||||
"jasmine-spec-reporter": "4.1.1",
|
||||
"karma": "1.7.1",
|
||||
"karma-chrome-launcher": "2.1.1",
|
||||
"karma-cli": "1.0.1",
|
||||
"karma-coverage-istanbul-reporter": "1.3.0",
|
||||
"karma-jasmine": "1.1.0",
|
||||
"karma-jasmine-html-reporter": "0.2.2",
|
||||
"npm-run-all": "4.0.2",
|
||||
"protractor": "5.1.2",
|
||||
"rimraf": "2.6.1",
|
||||
"stylelint": "7.13.0",
|
||||
"ts-node": "3.2.2",
|
||||
"tslint": "^5.7.0",
|
||||
"tslint-language-service": "^0.9.9",
|
||||
"typescript": "3.4.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
// @ts-check
|
||||
// Protractor configuration file, see link for more information
|
||||
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
||||
|
||||
const { SpecReporter } = require('jasmine-spec-reporter');
|
||||
|
||||
/**
|
||||
* @type { import("protractor").Config }
|
||||
*/
|
||||
exports.config = {
|
||||
allScriptsTimeout: 11000,
|
||||
specs: [
|
||||
'./src/**/*.e2e-spec.ts'
|
||||
'./e2e/**/*.e2e-spec.ts'
|
||||
],
|
||||
capabilities: {
|
||||
'browserName': 'chrome'
|
||||
'browserName': 'chrome',
|
||||
'chromeOptions': {
|
||||
'args': ['show-fps-counter=true', '--no-sandbox']
|
||||
}
|
||||
},
|
||||
directConnect: true,
|
||||
baseUrl: 'http://localhost:4200/',
|
||||
@@ -25,8 +24,9 @@ exports.config = {
|
||||
},
|
||||
onPrepare() {
|
||||
require('ts-node').register({
|
||||
project: require('path').join(__dirname, './tsconfig.json')
|
||||
project: 'e2e/tsconfig.e2e.json'
|
||||
});
|
||||
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
||||
|
||||
jasmine.getEnv().addReporter(new SpecReporter({ acspec: { displayStacktrace: true } }));
|
||||
}
|
||||
};
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"/widgets-repo/*": {
|
||||
"target": "http://localhost:4201",
|
||||
"secure": false,
|
||||
"pathRewrite": {
|
||||
"^/widgets-repo": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NbAuthModule, NbDummyAuthStrategy } from '@nebular/auth';
|
||||
import { NbSecurityModule, NbRoleProvider } from '@nebular/security';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
|
||||
import { throwIfAlreadyLoaded } from './module-import-guard';
|
||||
import {
|
||||
AnalyticsService,
|
||||
LayoutService,
|
||||
PlayerService,
|
||||
StateService,
|
||||
} from './utils';
|
||||
import { UserData } from './data/users';
|
||||
import { ElectricityData } from './data/electricity';
|
||||
import { SmartTableData } from './data/smart-table';
|
||||
import { UserActivityData } from './data/user-activity';
|
||||
import { OrdersChartData } from './data/orders-chart';
|
||||
import { ProfitChartData } from './data/profit-chart';
|
||||
import { TrafficListData } from './data/traffic-list';
|
||||
import { EarningData } from './data/earning';
|
||||
import { OrdersProfitChartData } from './data/orders-profit-chart';
|
||||
import { TrafficBarData } from './data/traffic-bar';
|
||||
import { ProfitBarAnimationChartData } from './data/profit-bar-animation-chart';
|
||||
import { TemperatureHumidityData } from './data/temperature-humidity';
|
||||
import { SolarData } from './data/solar';
|
||||
import { TrafficChartData } from './data/traffic-chart';
|
||||
import { StatsBarData } from './data/stats-bar';
|
||||
import { CountryOrderData } from './data/country-order';
|
||||
import { StatsProgressBarData } from './data/stats-progress-bar';
|
||||
import { VisitorsAnalyticsData } from './data/visitors-analytics';
|
||||
import { SecurityCamerasData } from './data/security-cameras';
|
||||
|
||||
import { UserService } from './mock/users.service';
|
||||
import { ElectricityService } from './mock/electricity.service';
|
||||
import { SmartTableService } from './mock/smart-table.service';
|
||||
import { UserActivityService } from './mock/user-activity.service';
|
||||
import { OrdersChartService } from './mock/orders-chart.service';
|
||||
import { ProfitChartService } from './mock/profit-chart.service';
|
||||
import { TrafficListService } from './mock/traffic-list.service';
|
||||
import { EarningService } from './mock/earning.service';
|
||||
import { OrdersProfitChartService } from './mock/orders-profit-chart.service';
|
||||
import { TrafficBarService } from './mock/traffic-bar.service';
|
||||
import { ProfitBarAnimationChartService } from './mock/profit-bar-animation-chart.service';
|
||||
import { TemperatureHumidityService } from './mock/temperature-humidity.service';
|
||||
import { SolarService } from './mock/solar.service';
|
||||
import { TrafficChartService } from './mock/traffic-chart.service';
|
||||
import { StatsBarService } from './mock/stats-bar.service';
|
||||
import { CountryOrderService } from './mock/country-order.service';
|
||||
import { StatsProgressBarService } from './mock/stats-progress-bar.service';
|
||||
import { VisitorsAnalyticsService } from './mock/visitors-analytics.service';
|
||||
import { SecurityCamerasService } from './mock/security-cameras.service';
|
||||
import { MockDataModule } from './mock/mock-data.module';
|
||||
|
||||
const socialLinks = [
|
||||
{
|
||||
url: 'https://github.com/akveo/nebular',
|
||||
target: '_blank',
|
||||
icon: 'github',
|
||||
},
|
||||
{
|
||||
url: 'https://www.facebook.com/akveo/',
|
||||
target: '_blank',
|
||||
icon: 'facebook',
|
||||
},
|
||||
{
|
||||
url: 'https://twitter.com/akveo_inc',
|
||||
target: '_blank',
|
||||
icon: 'twitter',
|
||||
},
|
||||
];
|
||||
|
||||
const DATA_SERVICES = [
|
||||
{ provide: UserData, useClass: UserService },
|
||||
{ provide: ElectricityData, useClass: ElectricityService },
|
||||
{ provide: SmartTableData, useClass: SmartTableService },
|
||||
{ provide: UserActivityData, useClass: UserActivityService },
|
||||
{ provide: OrdersChartData, useClass: OrdersChartService },
|
||||
{ provide: ProfitChartData, useClass: ProfitChartService },
|
||||
{ provide: TrafficListData, useClass: TrafficListService },
|
||||
{ provide: EarningData, useClass: EarningService },
|
||||
{ provide: OrdersProfitChartData, useClass: OrdersProfitChartService },
|
||||
{ provide: TrafficBarData, useClass: TrafficBarService },
|
||||
{ provide: ProfitBarAnimationChartData, useClass: ProfitBarAnimationChartService },
|
||||
{ provide: TemperatureHumidityData, useClass: TemperatureHumidityService },
|
||||
{ provide: SolarData, useClass: SolarService },
|
||||
{ provide: TrafficChartData, useClass: TrafficChartService },
|
||||
{ provide: StatsBarData, useClass: StatsBarService },
|
||||
{ provide: CountryOrderData, useClass: CountryOrderService },
|
||||
{ provide: StatsProgressBarData, useClass: StatsProgressBarService },
|
||||
{ provide: VisitorsAnalyticsData, useClass: VisitorsAnalyticsService },
|
||||
{ provide: SecurityCamerasData, useClass: SecurityCamerasService },
|
||||
];
|
||||
|
||||
export class NbSimpleRoleProvider extends NbRoleProvider {
|
||||
getRole() {
|
||||
// here you could provide any role based on any auth flow
|
||||
return observableOf('guest');
|
||||
}
|
||||
}
|
||||
|
||||
export const NB_CORE_PROVIDERS = [
|
||||
...MockDataModule.forRoot().providers,
|
||||
...DATA_SERVICES,
|
||||
...NbAuthModule.forRoot({
|
||||
|
||||
strategies: [
|
||||
NbDummyAuthStrategy.setup({
|
||||
name: 'email',
|
||||
delay: 3000,
|
||||
}),
|
||||
],
|
||||
forms: {
|
||||
login: {
|
||||
socialLinks: socialLinks,
|
||||
},
|
||||
register: {
|
||||
socialLinks: socialLinks,
|
||||
},
|
||||
},
|
||||
}).providers,
|
||||
|
||||
NbSecurityModule.forRoot({
|
||||
accessControl: {
|
||||
guest: {
|
||||
view: '*',
|
||||
},
|
||||
user: {
|
||||
parent: 'guest',
|
||||
create: '*',
|
||||
edit: '*',
|
||||
remove: '*',
|
||||
},
|
||||
},
|
||||
}).providers,
|
||||
|
||||
{
|
||||
provide: NbRoleProvider, useClass: NbSimpleRoleProvider,
|
||||
},
|
||||
AnalyticsService,
|
||||
LayoutService,
|
||||
PlayerService,
|
||||
StateService,
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
],
|
||||
exports: [
|
||||
NbAuthModule,
|
||||
],
|
||||
declarations: [],
|
||||
})
|
||||
export class CoreModule {
|
||||
constructor(@Optional() @SkipSelf() parentModule: CoreModule) {
|
||||
throwIfAlreadyLoaded(parentModule, 'CoreModule');
|
||||
}
|
||||
|
||||
static forRoot(): ModuleWithProviders {
|
||||
return <ModuleWithProviders>{
|
||||
ngModule: CoreModule,
|
||||
providers: [
|
||||
...NB_CORE_PROVIDERS,
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Application-wise data providers.
|
||||
@@ -0,0 +1,6 @@
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export abstract class CountryOrderData {
|
||||
abstract getCountriesCategories(): Observable<string[]>;
|
||||
abstract getCountriesCategoriesData(country: string): Observable<number[]>;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface LiveUpdateChart {
|
||||
liveChart: { value: [string, number] }[];
|
||||
delta: {
|
||||
up: boolean;
|
||||
value: number;
|
||||
};
|
||||
dailyIncome: number;
|
||||
}
|
||||
|
||||
export interface PieChart {
|
||||
value: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export abstract class EarningData {
|
||||
abstract getEarningLiveUpdateCardData(currency: string): Observable<any[]>;
|
||||
abstract getEarningCardData(currency: string): Observable<LiveUpdateChart>;
|
||||
abstract getEarningPieChartData(): Observable<PieChart[]>;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface Month {
|
||||
month: string;
|
||||
delta: string;
|
||||
down: boolean;
|
||||
kWatts: string;
|
||||
cost: string;
|
||||
}
|
||||
|
||||
export interface Electricity {
|
||||
title: string;
|
||||
active?: boolean;
|
||||
months: Month[];
|
||||
}
|
||||
|
||||
export interface ElectricityChart {
|
||||
label: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
export abstract class ElectricityData {
|
||||
abstract getListData(): Observable<Electricity[]>;
|
||||
abstract getChartData(): Observable<ElectricityChart[]>;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export interface OrdersChart {
|
||||
chartLabel: string[];
|
||||
linesData: number[][];
|
||||
}
|
||||
|
||||
export abstract class OrdersChartData {
|
||||
abstract getOrdersChartData(period: string): OrdersChart;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Observable } from 'rxjs';
|
||||
import { OrdersChart } from './orders-chart';
|
||||
import { ProfitChart } from './profit-chart';
|
||||
|
||||
export interface OrderProfitChartSummary {
|
||||
title: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
export abstract class OrdersProfitChartData {
|
||||
abstract getOrderProfitChartSummary(): Observable<OrderProfitChartSummary[]>;
|
||||
abstract getOrdersChartData(period: string): Observable<OrdersChart>;
|
||||
abstract getProfitChartData(period: string): Observable<ProfitChart>;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export abstract class ProfitBarAnimationChartData {
|
||||
abstract getChartData(): Observable<{ firstLine: number[]; secondLine: number[]; }>;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export interface ProfitChart {
|
||||
chartLabel: string[];
|
||||
data: number[][];
|
||||
}
|
||||
|
||||
export abstract class ProfitChartData {
|
||||
abstract getProfitChartData(period: string): ProfitChart;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface Camera {
|
||||
title: string;
|
||||
source: string;
|
||||
}
|
||||
|
||||
export abstract class SecurityCamerasData {
|
||||
abstract getCamerasData(): Observable<Camera[]>;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
export abstract class SmartTableData {
|
||||
abstract getData(): any[];
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export abstract class SolarData {
|
||||
abstract getSolarData(): Observable<number>;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export abstract class StatsBarData {
|
||||
abstract getStatsBarData(): Observable<number[]>;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface ProgressInfo {
|
||||
title: string;
|
||||
value: number;
|
||||
activeProgress: number;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export abstract class StatsProgressBarData {
|
||||
abstract getProgressInfoData(): Observable<ProgressInfo[]>;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface Temperature {
|
||||
value: number;
|
||||
min: number;
|
||||
max: number;
|
||||
}
|
||||
|
||||
export abstract class TemperatureHumidityData {
|
||||
abstract getTemperatureData(): Observable<Temperature>;
|
||||
abstract getHumidityData(): Observable<Temperature>;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface TrafficBar {
|
||||
data: number[];
|
||||
labels: string[];
|
||||
formatter: string;
|
||||
}
|
||||
|
||||
export abstract class TrafficBarData {
|
||||
abstract getTrafficBarData(period: string): Observable<TrafficBar>;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export abstract class TrafficChartData {
|
||||
abstract getTrafficChartData(): Observable<number[]>;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface TrafficList {
|
||||
date: string;
|
||||
value: number;
|
||||
delta: {
|
||||
up: boolean;
|
||||
value: number;
|
||||
};
|
||||
comparison: {
|
||||
prevDate: string;
|
||||
prevValue: number;
|
||||
nextDate: string;
|
||||
nextValue: number;
|
||||
};
|
||||
}
|
||||
|
||||
export abstract class TrafficListData {
|
||||
abstract getTrafficListData(period: string): Observable<TrafficList>;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface UserActive {
|
||||
date: string;
|
||||
pagesVisitCount: number;
|
||||
deltaUp: boolean;
|
||||
newVisits: number;
|
||||
}
|
||||
|
||||
export abstract class UserActivityData {
|
||||
abstract getUserActivityData(period: string): Observable<UserActive[]>;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface User {
|
||||
name: string;
|
||||
picture: string;
|
||||
}
|
||||
|
||||
export interface Contacts {
|
||||
user: User;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface RecentUsers extends Contacts {
|
||||
time: number;
|
||||
}
|
||||
|
||||
export abstract class UserData {
|
||||
abstract getUsers(): Observable<User[]>;
|
||||
abstract getContacts(): Observable<Contacts[]>;
|
||||
abstract getRecentUsers(): Observable<RecentUsers[]>;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface OutlineData {
|
||||
label: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
export abstract class VisitorsAnalyticsData {
|
||||
abstract getInnerLineChartData(): Observable<number[]>;
|
||||
abstract getOutlineLineChartData(): Observable<OutlineData[]>;
|
||||
abstract getPieChartData(): Observable<number>;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Application-wise data providers.
|
||||
@@ -0,0 +1,29 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { of as observableOf, Observable } from 'rxjs';
|
||||
import { CountryOrderData } from '../data/country-order';
|
||||
|
||||
@Injectable()
|
||||
export class CountryOrderService extends CountryOrderData {
|
||||
|
||||
private countriesCategories = [
|
||||
'Sofas',
|
||||
'Furniture',
|
||||
'Lighting',
|
||||
'Tables',
|
||||
'Textiles',
|
||||
];
|
||||
private countriesCategoriesLength = this.countriesCategories.length;
|
||||
private generateRandomData(nPoints: number): number[] {
|
||||
return Array.from(Array(nPoints)).map(() => {
|
||||
return Math.round(Math.random() * 20);
|
||||
});
|
||||
}
|
||||
|
||||
getCountriesCategories(): Observable<string[]> {
|
||||
return observableOf(this.countriesCategories);
|
||||
}
|
||||
|
||||
getCountriesCategoriesData(country: string): Observable<number[]> {
|
||||
return observableOf(this.generateRandomData(this.countriesCategoriesLength));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { of as observableOf, Observable } from 'rxjs';
|
||||
import { LiveUpdateChart, PieChart, EarningData } from '../data/earning';
|
||||
|
||||
@Injectable()
|
||||
export class EarningService extends EarningData {
|
||||
|
||||
private currentDate: Date = new Date();
|
||||
private currentValue = Math.random() * 1000;
|
||||
private ONE_DAY = 24 * 3600 * 1000;
|
||||
|
||||
private pieChartData = [
|
||||
{
|
||||
value: 50,
|
||||
name: 'Bitcoin',
|
||||
},
|
||||
{
|
||||
value: 25,
|
||||
name: 'Tether',
|
||||
},
|
||||
{
|
||||
value: 25,
|
||||
name: 'Ethereum',
|
||||
},
|
||||
];
|
||||
|
||||
private liveUpdateChartData = {
|
||||
bitcoin: {
|
||||
liveChart: [],
|
||||
delta: {
|
||||
up: true,
|
||||
value: 4,
|
||||
},
|
||||
dailyIncome: 45895,
|
||||
},
|
||||
tether: {
|
||||
liveChart: [],
|
||||
delta: {
|
||||
up: false,
|
||||
value: 9,
|
||||
},
|
||||
dailyIncome: 5862,
|
||||
},
|
||||
ethereum: {
|
||||
liveChart: [],
|
||||
delta: {
|
||||
up: false,
|
||||
value: 21,
|
||||
},
|
||||
dailyIncome: 584,
|
||||
},
|
||||
};
|
||||
|
||||
getDefaultLiveChartData(elementsNumber: number) {
|
||||
this.currentDate = new Date();
|
||||
this.currentValue = Math.random() * 1000;
|
||||
|
||||
return Array.from(Array(elementsNumber))
|
||||
.map(item => this.generateRandomLiveChartData());
|
||||
}
|
||||
|
||||
generateRandomLiveChartData() {
|
||||
this.currentDate = new Date(+this.currentDate + this.ONE_DAY);
|
||||
this.currentValue = this.currentValue + Math.random() * 20 - 11;
|
||||
|
||||
if (this.currentValue < 0) {
|
||||
this.currentValue = Math.random() * 100;
|
||||
}
|
||||
|
||||
return {
|
||||
value: [
|
||||
[
|
||||
this.currentDate.getFullYear(),
|
||||
this.currentDate.getMonth(),
|
||||
this.currentDate.getDate(),
|
||||
].join('/'),
|
||||
Math.round(this.currentValue),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
getEarningLiveUpdateCardData(currency): Observable<any[]> {
|
||||
const data = this.liveUpdateChartData[currency.toLowerCase()];
|
||||
const newValue = this.generateRandomLiveChartData();
|
||||
|
||||
data.liveChart.shift();
|
||||
data.liveChart.push(newValue);
|
||||
|
||||
return observableOf(data.liveChart);
|
||||
}
|
||||
|
||||
getEarningCardData(currency: string): Observable<LiveUpdateChart> {
|
||||
const data = this.liveUpdateChartData[currency.toLowerCase()];
|
||||
|
||||
data.liveChart = this.getDefaultLiveChartData(150);
|
||||
|
||||
return observableOf(data);
|
||||
}
|
||||
|
||||
getEarningPieChartData(): Observable<PieChart[]> {
|
||||
return observableOf(this.pieChartData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { of as observableOf, Observable } from 'rxjs';
|
||||
import { Electricity, ElectricityChart, ElectricityData } from '../data/electricity';
|
||||
|
||||
@Injectable()
|
||||
export class ElectricityService extends ElectricityData {
|
||||
|
||||
private listData: Electricity[] = [
|
||||
{
|
||||
title: '2015',
|
||||
months: [
|
||||
{ month: 'Jan', delta: '0.97', down: true, kWatts: '816', cost: '97' },
|
||||
{ month: 'Feb', delta: '1.83', down: true, kWatts: '806', cost: '95' },
|
||||
{ month: 'Mar', delta: '0.64', down: true, kWatts: '803', cost: '94' },
|
||||
{ month: 'Apr', delta: '2.17', down: false, kWatts: '818', cost: '98' },
|
||||
{ month: 'May', delta: '1.32', down: true, kWatts: '809', cost: '96' },
|
||||
{ month: 'Jun', delta: '0.05', down: true, kWatts: '808', cost: '96' },
|
||||
{ month: 'Jul', delta: '1.39', down: false, kWatts: '815', cost: '97' },
|
||||
{ month: 'Aug', delta: '0.73', down: true, kWatts: '807', cost: '95' },
|
||||
{ month: 'Sept', delta: '2.61', down: true, kWatts: '792', cost: '92' },
|
||||
{ month: 'Oct', delta: '0.16', down: true, kWatts: '791', cost: '92' },
|
||||
{ month: 'Nov', delta: '1.71', down: true, kWatts: '786', cost: '89' },
|
||||
{ month: 'Dec', delta: '0.37', down: false, kWatts: '789', cost: '91' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '2016',
|
||||
active: true,
|
||||
months: [
|
||||
{ month: 'Jan', delta: '1.56', down: true, kWatts: '789', cost: '91' },
|
||||
{ month: 'Feb', delta: '0.33', down: false, kWatts: '791', cost: '92' },
|
||||
{ month: 'Mar', delta: '0.62', down: true, kWatts: '790', cost: '92' },
|
||||
{ month: 'Apr', delta: '1.93', down: true, kWatts: '783', cost: '87' },
|
||||
{ month: 'May', delta: '2.52', down: true, kWatts: '771', cost: '83' },
|
||||
{ month: 'Jun', delta: '0.39', down: false, kWatts: '774', cost: '85' },
|
||||
{ month: 'Jul', delta: '1.61', down: true, kWatts: '767', cost: '81' },
|
||||
{ month: 'Aug', delta: '1.41', down: true, kWatts: '759', cost: '76' },
|
||||
{ month: 'Sept', delta: '1.03', down: true, kWatts: '752', cost: '74' },
|
||||
{ month: 'Oct', delta: '2.94', down: false, kWatts: '769', cost: '82' },
|
||||
{ month: 'Nov', delta: '0.26', down: true, kWatts: '767', cost: '81' },
|
||||
{ month: 'Dec', delta: '1.62', down: true, kWatts: '760', cost: '76' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '2017',
|
||||
months: [
|
||||
{ month: 'Jan', delta: '1.34', down: false, kWatts: '789', cost: '91' },
|
||||
{ month: 'Feb', delta: '0.95', down: false, kWatts: '793', cost: '93' },
|
||||
{ month: 'Mar', delta: '0.25', down: true, kWatts: '791', cost: '92' },
|
||||
{ month: 'Apr', delta: '1.72', down: false, kWatts: '797', cost: '95' },
|
||||
{ month: 'May', delta: '2.62', down: true, kWatts: '786', cost: '90' },
|
||||
{ month: 'Jun', delta: '0.72', down: false, kWatts: '789', cost: '91' },
|
||||
{ month: 'Jul', delta: '0.78', down: true, kWatts: '784', cost: '89' },
|
||||
{ month: 'Aug', delta: '0.36', down: true, kWatts: '782', cost: '88' },
|
||||
{ month: 'Sept', delta: '0.55', down: false, kWatts: '787', cost: '90' },
|
||||
{ month: 'Oct', delta: '1.81', down: true, kWatts: '779', cost: '86' },
|
||||
{ month: 'Nov', delta: '1.12', down: true, kWatts: '774', cost: '84' },
|
||||
{ month: 'Dec', delta: '0.52', down: false, kWatts: '776', cost: '95' },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
private chartPoints = [
|
||||
490, 490, 495, 500,
|
||||
505, 510, 520, 530,
|
||||
550, 580, 630, 720,
|
||||
800, 840, 860, 870,
|
||||
870, 860, 840, 800,
|
||||
720, 200, 145, 130,
|
||||
130, 145, 200, 570,
|
||||
635, 660, 670, 670,
|
||||
660, 630, 580, 460,
|
||||
380, 350, 340, 340,
|
||||
340, 340, 340, 340,
|
||||
340, 340, 340,
|
||||
];
|
||||
|
||||
chartData: ElectricityChart[];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.chartData = this.chartPoints.map((p, index) => ({
|
||||
label: (index % 5 === 3) ? `${Math.round(index / 5)}` : '',
|
||||
value: p,
|
||||
}));
|
||||
}
|
||||
|
||||
getListData(): Observable<Electricity[]> {
|
||||
return observableOf(this.listData);
|
||||
}
|
||||
|
||||
getChartData(): Observable<ElectricityChart[]> {
|
||||
return observableOf(this.chartData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
import { NgModule, ModuleWithProviders } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { UserService } from './users.service';
|
||||
import { ElectricityService } from './electricity.service';
|
||||
import { SmartTableService } from './smart-table.service';
|
||||
import { UserActivityService } from './user-activity.service';
|
||||
import { OrdersChartService } from './orders-chart.service';
|
||||
import { ProfitChartService } from './profit-chart.service';
|
||||
import { TrafficListService } from './traffic-list.service';
|
||||
import { PeriodsService } from './periods.service';
|
||||
import { EarningService } from './earning.service';
|
||||
import { OrdersProfitChartService } from './orders-profit-chart.service';
|
||||
import { TrafficBarService } from './traffic-bar.service';
|
||||
import { ProfitBarAnimationChartService } from './profit-bar-animation-chart.service';
|
||||
import { TemperatureHumidityService } from './temperature-humidity.service';
|
||||
import { SolarService } from './solar.service';
|
||||
import { TrafficChartService } from './traffic-chart.service';
|
||||
import { StatsBarService } from './stats-bar.service';
|
||||
import { CountryOrderService } from './country-order.service';
|
||||
import { StatsProgressBarService } from './stats-progress-bar.service';
|
||||
import { VisitorsAnalyticsService } from './visitors-analytics.service';
|
||||
import { SecurityCamerasService } from './security-cameras.service';
|
||||
|
||||
const SERVICES = [
|
||||
UserService,
|
||||
ElectricityService,
|
||||
SmartTableService,
|
||||
UserActivityService,
|
||||
OrdersChartService,
|
||||
ProfitChartService,
|
||||
TrafficListService,
|
||||
PeriodsService,
|
||||
EarningService,
|
||||
OrdersProfitChartService,
|
||||
TrafficBarService,
|
||||
ProfitBarAnimationChartService,
|
||||
TemperatureHumidityService,
|
||||
SolarService,
|
||||
TrafficChartService,
|
||||
StatsBarService,
|
||||
CountryOrderService,
|
||||
StatsProgressBarService,
|
||||
VisitorsAnalyticsService,
|
||||
SecurityCamerasService,
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
],
|
||||
providers: [
|
||||
...SERVICES,
|
||||
],
|
||||
})
|
||||
export class MockDataModule {
|
||||
static forRoot(): ModuleWithProviders {
|
||||
return <ModuleWithProviders>{
|
||||
ngModule: MockDataModule,
|
||||
providers: [
|
||||
...SERVICES,
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { PeriodsService } from './periods.service';
|
||||
import { OrdersChart, OrdersChartData } from '../data/orders-chart';
|
||||
|
||||
@Injectable()
|
||||
export class OrdersChartService extends OrdersChartData {
|
||||
|
||||
private year = [
|
||||
'2012',
|
||||
'2013',
|
||||
'2014',
|
||||
'2015',
|
||||
'2016',
|
||||
'2017',
|
||||
'2018',
|
||||
];
|
||||
|
||||
private data = { };
|
||||
|
||||
constructor(private period: PeriodsService) {
|
||||
super();
|
||||
this.data = {
|
||||
week: this.getDataForWeekPeriod(),
|
||||
month: this.getDataForMonthPeriod(),
|
||||
year: this.getDataForYearPeriod(),
|
||||
};
|
||||
}
|
||||
|
||||
private getDataForWeekPeriod(): OrdersChart {
|
||||
return {
|
||||
chartLabel: this.getDataLabels(42, this.period.getWeeks()),
|
||||
linesData: [
|
||||
[
|
||||
184, 267, 326, 366, 389, 399,
|
||||
392, 371, 340, 304, 265, 227,
|
||||
191, 158, 130, 108, 95, 91, 97,
|
||||
109, 125, 144, 166, 189, 212,
|
||||
236, 259, 280, 300, 316, 329,
|
||||
338, 342, 339, 329, 312, 288,
|
||||
258, 221, 178, 128, 71,
|
||||
],
|
||||
[
|
||||
158, 178, 193, 205, 212, 213,
|
||||
204, 190, 180, 173, 168, 164,
|
||||
162, 160, 159, 158, 159, 166,
|
||||
179, 195, 215, 236, 257, 276,
|
||||
292, 301, 304, 303, 300, 293,
|
||||
284, 273, 262, 251, 241, 234,
|
||||
232, 232, 232, 232, 232, 232,
|
||||
],
|
||||
[
|
||||
58, 137, 202, 251, 288, 312,
|
||||
323, 324, 311, 288, 257, 222,
|
||||
187, 154, 124, 100, 81, 68, 61,
|
||||
58, 61, 69, 80, 96, 115, 137,
|
||||
161, 186, 210, 233, 254, 271,
|
||||
284, 293, 297, 297, 297, 297,
|
||||
297, 297, 297, 297, 297,
|
||||
],
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
private getDataForMonthPeriod(): OrdersChart {
|
||||
return {
|
||||
chartLabel: this.getDataLabels(47, this.period.getMonths()),
|
||||
linesData: [
|
||||
[
|
||||
5, 63, 113, 156, 194, 225,
|
||||
250, 270, 283, 289, 290,
|
||||
286, 277, 264, 244, 220,
|
||||
194, 171, 157, 151, 150,
|
||||
152, 155, 160, 166, 170,
|
||||
167, 153, 135, 115, 97,
|
||||
82, 71, 64, 63, 62, 61,
|
||||
62, 65, 73, 84, 102,
|
||||
127, 159, 203, 259, 333,
|
||||
],
|
||||
[
|
||||
6, 83, 148, 200, 240,
|
||||
265, 273, 259, 211,
|
||||
122, 55, 30, 28, 36,
|
||||
50, 68, 88, 109, 129,
|
||||
146, 158, 163, 165,
|
||||
173, 187, 208, 236,
|
||||
271, 310, 346, 375,
|
||||
393, 400, 398, 387,
|
||||
368, 341, 309, 275,
|
||||
243, 220, 206, 202,
|
||||
207, 222, 247, 286, 348,
|
||||
],
|
||||
[
|
||||
398, 348, 315, 292, 274,
|
||||
261, 251, 243, 237, 231,
|
||||
222, 209, 192, 172, 152,
|
||||
132, 116, 102, 90, 80, 71,
|
||||
64, 58, 53, 49, 48, 54, 66,
|
||||
84, 104, 125, 142, 156, 166,
|
||||
172, 174, 172, 167, 159, 149,
|
||||
136, 121, 105, 86, 67, 45, 22,
|
||||
],
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
private getDataForYearPeriod(): OrdersChart {
|
||||
return {
|
||||
chartLabel: this.getDataLabels(42, this.year),
|
||||
linesData: [
|
||||
[
|
||||
190, 269, 327, 366, 389, 398,
|
||||
396, 387, 375, 359, 343, 327,
|
||||
312, 298, 286, 276, 270, 268,
|
||||
265, 258, 247, 234, 220, 204,
|
||||
188, 172, 157, 142, 128, 116,
|
||||
106, 99, 95, 94, 92, 89, 84,
|
||||
77, 69, 60, 49, 36, 22,
|
||||
],
|
||||
[
|
||||
265, 307, 337, 359, 375, 386,
|
||||
393, 397, 399, 397, 390, 379,
|
||||
365, 347, 326, 305, 282, 261,
|
||||
241, 223, 208, 197, 190, 187,
|
||||
185, 181, 172, 160, 145, 126,
|
||||
105, 82, 60, 40, 26, 19, 22,
|
||||
43, 82, 141, 220, 321,
|
||||
],
|
||||
[
|
||||
9, 165, 236, 258, 244, 206,
|
||||
186, 189, 209, 239, 273, 307,
|
||||
339, 365, 385, 396, 398, 385,
|
||||
351, 300, 255, 221, 197, 181,
|
||||
170, 164, 162, 161, 159, 154,
|
||||
146, 135, 122, 108, 96, 87,
|
||||
83, 82, 82, 82, 82, 82, 82,
|
||||
],
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
getDataLabels(nPoints: number, labelsArray: string[]): string[] {
|
||||
const labelsArrayLength = labelsArray.length;
|
||||
const step = Math.round(nPoints / labelsArrayLength);
|
||||
|
||||
return Array.from(Array(nPoints)).map((item, index) => {
|
||||
const dataIndex = Math.round(index / step);
|
||||
|
||||
return index % step === 0 ? labelsArray[dataIndex] : '';
|
||||
});
|
||||
}
|
||||
|
||||
getOrdersChartData(period: string): OrdersChart {
|
||||
return this.data[period];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import { of as observableOf, Observable } from 'rxjs';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { OrdersChart, OrdersChartData } from '../data/orders-chart';
|
||||
import { OrderProfitChartSummary, OrdersProfitChartData } from '../data/orders-profit-chart';
|
||||
import { ProfitChart, ProfitChartData } from '../data/profit-chart';
|
||||
|
||||
@Injectable()
|
||||
export class OrdersProfitChartService extends OrdersProfitChartData {
|
||||
|
||||
private summary = [
|
||||
{
|
||||
title: 'Marketplace',
|
||||
value: 3654,
|
||||
},
|
||||
{
|
||||
title: 'Last Month',
|
||||
value: 946,
|
||||
},
|
||||
{
|
||||
title: 'Last Week',
|
||||
value: 654,
|
||||
},
|
||||
{
|
||||
title: 'Today',
|
||||
value: 230,
|
||||
},
|
||||
];
|
||||
|
||||
constructor(private ordersChartService: OrdersChartData,
|
||||
private profitChartService: ProfitChartData) {
|
||||
super();
|
||||
}
|
||||
|
||||
getOrderProfitChartSummary(): Observable<OrderProfitChartSummary[]> {
|
||||
return observableOf(this.summary);
|
||||
}
|
||||
|
||||
getOrdersChartData(period: string): Observable<OrdersChart> {
|
||||
return observableOf(this.ordersChartService.getOrdersChartData(period));
|
||||
}
|
||||
|
||||
getProfitChartData(period: string): Observable<ProfitChart> {
|
||||
return observableOf(this.profitChartService.getProfitChartData(period));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class PeriodsService {
|
||||
getYears() {
|
||||
return [
|
||||
'2010', '2011', '2012',
|
||||
'2013', '2014', '2015',
|
||||
'2016', '2017', '2018',
|
||||
];
|
||||
}
|
||||
|
||||
getMonths() {
|
||||
return [
|
||||
'Jan', 'Feb', 'Mar',
|
||||
'Apr', 'May', 'Jun',
|
||||
'Jul', 'Aug', 'Sep',
|
||||
'Oct', 'Nov', 'Dec',
|
||||
];
|
||||
}
|
||||
|
||||
getWeeks() {
|
||||
return [
|
||||
'Mon',
|
||||
'Tue',
|
||||
'Wed',
|
||||
'Thu',
|
||||
'Fri',
|
||||
'Sat',
|
||||
'Sun',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { of as observableOf, Observable } from 'rxjs';
|
||||
import { ProfitBarAnimationChartData } from '../data/profit-bar-animation-chart';
|
||||
|
||||
@Injectable()
|
||||
export class ProfitBarAnimationChartService extends ProfitBarAnimationChartData {
|
||||
|
||||
private data: any;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.data = {
|
||||
firstLine: this.getDataForFirstLine(),
|
||||
secondLine: this.getDataForSecondLine(),
|
||||
};
|
||||
}
|
||||
|
||||
getDataForFirstLine(): number[] {
|
||||
return this.createEmptyArray(100)
|
||||
.map((_, index) => {
|
||||
const oneFifth = index / 5;
|
||||
|
||||
return (Math.sin(oneFifth) * (oneFifth - 10) + index / 6) * 5;
|
||||
});
|
||||
}
|
||||
|
||||
getDataForSecondLine(): number[] {
|
||||
return this.createEmptyArray(100)
|
||||
.map((_, index) => {
|
||||
const oneFifth = index / 5;
|
||||
|
||||
return (Math.cos(oneFifth) * (oneFifth - 10) + index / 6) * 5;
|
||||
});
|
||||
}
|
||||
|
||||
createEmptyArray(nPoints: number) {
|
||||
return Array.from(Array(nPoints));
|
||||
}
|
||||
|
||||
getChartData(): Observable<{ firstLine: number[]; secondLine: number[]; }> {
|
||||
return observableOf(this.data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { PeriodsService } from './periods.service';
|
||||
import { ProfitChart, ProfitChartData } from '../data/profit-chart';
|
||||
|
||||
@Injectable()
|
||||
export class ProfitChartService extends ProfitChartData {
|
||||
|
||||
private year = [
|
||||
'2012',
|
||||
'2013',
|
||||
'2014',
|
||||
'2015',
|
||||
'2016',
|
||||
'2017',
|
||||
'2018',
|
||||
];
|
||||
|
||||
private data = { };
|
||||
|
||||
constructor(private period: PeriodsService) {
|
||||
super();
|
||||
this.data = {
|
||||
week: this.getDataForWeekPeriod(),
|
||||
month: this.getDataForMonthPeriod(),
|
||||
year: this.getDataForYearPeriod(),
|
||||
};
|
||||
}
|
||||
|
||||
private getDataForWeekPeriod(): ProfitChart {
|
||||
const nPoint = this.period.getWeeks().length;
|
||||
|
||||
return {
|
||||
chartLabel: this.period.getWeeks(),
|
||||
data: [
|
||||
this.getRandomData(nPoint),
|
||||
this.getRandomData(nPoint),
|
||||
this.getRandomData(nPoint),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
private getDataForMonthPeriod(): ProfitChart {
|
||||
const nPoint = this.period.getMonths().length;
|
||||
|
||||
return {
|
||||
chartLabel: this.period.getMonths(),
|
||||
data: [
|
||||
this.getRandomData(nPoint),
|
||||
this.getRandomData(nPoint),
|
||||
this.getRandomData(nPoint),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
private getDataForYearPeriod(): ProfitChart {
|
||||
const nPoint = this.year.length;
|
||||
|
||||
return {
|
||||
chartLabel: this.year,
|
||||
data: [
|
||||
this.getRandomData(nPoint),
|
||||
this.getRandomData(nPoint),
|
||||
this.getRandomData(nPoint),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
private getRandomData(nPoints: number): number[] {
|
||||
return Array.from(Array(nPoints)).map(() => {
|
||||
return Math.round(Math.random() * 500);
|
||||
});
|
||||
}
|
||||
|
||||
getProfitChartData(period: string): ProfitChart {
|
||||
return this.data[period];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { of as observableOf, Observable } from 'rxjs';
|
||||
import { Camera, SecurityCamerasData } from '../data/security-cameras';
|
||||
|
||||
@Injectable()
|
||||
export class SecurityCamerasService extends SecurityCamerasData {
|
||||
|
||||
private cameras: Camera[] = [
|
||||
{
|
||||
title: 'Camera #1',
|
||||
source: 'assets/images/camera1.jpg',
|
||||
},
|
||||
{
|
||||
title: 'Camera #2',
|
||||
source: 'assets/images/camera2.jpg',
|
||||
},
|
||||
{
|
||||
title: 'Camera #3',
|
||||
source: 'assets/images/camera3.jpg',
|
||||
},
|
||||
{
|
||||
title: 'Camera #4',
|
||||
source: 'assets/images/camera4.jpg',
|
||||
},
|
||||
];
|
||||
|
||||
getCamerasData(): Observable<Camera[]> {
|
||||
return observableOf(this.cameras);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,432 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { SmartTableData } from '../data/smart-table';
|
||||
|
||||
@Injectable()
|
||||
export class SmartTableService extends SmartTableData {
|
||||
|
||||
data = [{
|
||||
id: 1,
|
||||
firstName: 'Mark',
|
||||
lastName: 'Otto',
|
||||
username: '@mdo',
|
||||
email: 'mdo@gmail.com',
|
||||
age: '28',
|
||||
}, {
|
||||
id: 2,
|
||||
firstName: 'Jacob',
|
||||
lastName: 'Thornton',
|
||||
username: '@fat',
|
||||
email: 'fat@yandex.ru',
|
||||
age: '45',
|
||||
}, {
|
||||
id: 3,
|
||||
firstName: 'Larry',
|
||||
lastName: 'Bird',
|
||||
username: '@twitter',
|
||||
email: 'twitter@outlook.com',
|
||||
age: '18',
|
||||
}, {
|
||||
id: 4,
|
||||
firstName: 'John',
|
||||
lastName: 'Snow',
|
||||
username: '@snow',
|
||||
email: 'snow@gmail.com',
|
||||
age: '20',
|
||||
}, {
|
||||
id: 5,
|
||||
firstName: 'Jack',
|
||||
lastName: 'Sparrow',
|
||||
username: '@jack',
|
||||
email: 'jack@yandex.ru',
|
||||
age: '30',
|
||||
}, {
|
||||
id: 6,
|
||||
firstName: 'Ann',
|
||||
lastName: 'Smith',
|
||||
username: '@ann',
|
||||
email: 'ann@gmail.com',
|
||||
age: '21',
|
||||
}, {
|
||||
id: 7,
|
||||
firstName: 'Barbara',
|
||||
lastName: 'Black',
|
||||
username: '@barbara',
|
||||
email: 'barbara@yandex.ru',
|
||||
age: '43',
|
||||
}, {
|
||||
id: 8,
|
||||
firstName: 'Sevan',
|
||||
lastName: 'Bagrat',
|
||||
username: '@sevan',
|
||||
email: 'sevan@outlook.com',
|
||||
age: '13',
|
||||
}, {
|
||||
id: 9,
|
||||
firstName: 'Ruben',
|
||||
lastName: 'Vardan',
|
||||
username: '@ruben',
|
||||
email: 'ruben@gmail.com',
|
||||
age: '22',
|
||||
}, {
|
||||
id: 10,
|
||||
firstName: 'Karen',
|
||||
lastName: 'Sevan',
|
||||
username: '@karen',
|
||||
email: 'karen@yandex.ru',
|
||||
age: '33',
|
||||
}, {
|
||||
id: 11,
|
||||
firstName: 'Mark',
|
||||
lastName: 'Otto',
|
||||
username: '@mark',
|
||||
email: 'mark@gmail.com',
|
||||
age: '38',
|
||||
}, {
|
||||
id: 12,
|
||||
firstName: 'Jacob',
|
||||
lastName: 'Thornton',
|
||||
username: '@jacob',
|
||||
email: 'jacob@yandex.ru',
|
||||
age: '48',
|
||||
}, {
|
||||
id: 13,
|
||||
firstName: 'Haik',
|
||||
lastName: 'Hakob',
|
||||
username: '@haik',
|
||||
email: 'haik@outlook.com',
|
||||
age: '48',
|
||||
}, {
|
||||
id: 14,
|
||||
firstName: 'Garegin',
|
||||
lastName: 'Jirair',
|
||||
username: '@garegin',
|
||||
email: 'garegin@gmail.com',
|
||||
age: '40',
|
||||
}, {
|
||||
id: 15,
|
||||
firstName: 'Krikor',
|
||||
lastName: 'Bedros',
|
||||
username: '@krikor',
|
||||
email: 'krikor@yandex.ru',
|
||||
age: '32',
|
||||
}, {
|
||||
'id': 16,
|
||||
'firstName': 'Francisca',
|
||||
'lastName': 'Brady',
|
||||
'username': '@Gibson',
|
||||
'email': 'franciscagibson@comtours.com',
|
||||
'age': 11,
|
||||
}, {
|
||||
'id': 17,
|
||||
'firstName': 'Tillman',
|
||||
'lastName': 'Figueroa',
|
||||
'username': '@Snow',
|
||||
'email': 'tillmansnow@comtours.com',
|
||||
'age': 34,
|
||||
}, {
|
||||
'id': 18,
|
||||
'firstName': 'Jimenez',
|
||||
'lastName': 'Morris',
|
||||
'username': '@Bryant',
|
||||
'email': 'jimenezbryant@comtours.com',
|
||||
'age': 45,
|
||||
}, {
|
||||
'id': 19,
|
||||
'firstName': 'Sandoval',
|
||||
'lastName': 'Jacobson',
|
||||
'username': '@Mcbride',
|
||||
'email': 'sandovalmcbride@comtours.com',
|
||||
'age': 32,
|
||||
}, {
|
||||
'id': 20,
|
||||
'firstName': 'Griffin',
|
||||
'lastName': 'Torres',
|
||||
'username': '@Charles',
|
||||
'email': 'griffincharles@comtours.com',
|
||||
'age': 19,
|
||||
}, {
|
||||
'id': 21,
|
||||
'firstName': 'Cora',
|
||||
'lastName': 'Parker',
|
||||
'username': '@Caldwell',
|
||||
'email': 'coracaldwell@comtours.com',
|
||||
'age': 27,
|
||||
}, {
|
||||
'id': 22,
|
||||
'firstName': 'Cindy',
|
||||
'lastName': 'Bond',
|
||||
'username': '@Velez',
|
||||
'email': 'cindyvelez@comtours.com',
|
||||
'age': 24,
|
||||
}, {
|
||||
'id': 23,
|
||||
'firstName': 'Frieda',
|
||||
'lastName': 'Tyson',
|
||||
'username': '@Craig',
|
||||
'email': 'friedacraig@comtours.com',
|
||||
'age': 45,
|
||||
}, {
|
||||
'id': 24,
|
||||
'firstName': 'Cote',
|
||||
'lastName': 'Holcomb',
|
||||
'username': '@Rowe',
|
||||
'email': 'coterowe@comtours.com',
|
||||
'age': 20,
|
||||
}, {
|
||||
'id': 25,
|
||||
'firstName': 'Trujillo',
|
||||
'lastName': 'Mejia',
|
||||
'username': '@Valenzuela',
|
||||
'email': 'trujillovalenzuela@comtours.com',
|
||||
'age': 16,
|
||||
}, {
|
||||
'id': 26,
|
||||
'firstName': 'Pruitt',
|
||||
'lastName': 'Shepard',
|
||||
'username': '@Sloan',
|
||||
'email': 'pruittsloan@comtours.com',
|
||||
'age': 44,
|
||||
}, {
|
||||
'id': 27,
|
||||
'firstName': 'Sutton',
|
||||
'lastName': 'Ortega',
|
||||
'username': '@Black',
|
||||
'email': 'suttonblack@comtours.com',
|
||||
'age': 42,
|
||||
}, {
|
||||
'id': 28,
|
||||
'firstName': 'Marion',
|
||||
'lastName': 'Heath',
|
||||
'username': '@Espinoza',
|
||||
'email': 'marionespinoza@comtours.com',
|
||||
'age': 47,
|
||||
}, {
|
||||
'id': 29,
|
||||
'firstName': 'Newman',
|
||||
'lastName': 'Hicks',
|
||||
'username': '@Keith',
|
||||
'email': 'newmankeith@comtours.com',
|
||||
'age': 15,
|
||||
}, {
|
||||
'id': 30,
|
||||
'firstName': 'Boyle',
|
||||
'lastName': 'Larson',
|
||||
'username': '@Summers',
|
||||
'email': 'boylesummers@comtours.com',
|
||||
'age': 32,
|
||||
}, {
|
||||
'id': 31,
|
||||
'firstName': 'Haynes',
|
||||
'lastName': 'Vinson',
|
||||
'username': '@Mckenzie',
|
||||
'email': 'haynesmckenzie@comtours.com',
|
||||
'age': 15,
|
||||
}, {
|
||||
'id': 32,
|
||||
'firstName': 'Miller',
|
||||
'lastName': 'Acosta',
|
||||
'username': '@Young',
|
||||
'email': 'milleryoung@comtours.com',
|
||||
'age': 55,
|
||||
}, {
|
||||
'id': 33,
|
||||
'firstName': 'Johnston',
|
||||
'lastName': 'Brown',
|
||||
'username': '@Knight',
|
||||
'email': 'johnstonknight@comtours.com',
|
||||
'age': 29,
|
||||
}, {
|
||||
'id': 34,
|
||||
'firstName': 'Lena',
|
||||
'lastName': 'Pitts',
|
||||
'username': '@Forbes',
|
||||
'email': 'lenaforbes@comtours.com',
|
||||
'age': 25,
|
||||
}, {
|
||||
'id': 35,
|
||||
'firstName': 'Terrie',
|
||||
'lastName': 'Kennedy',
|
||||
'username': '@Branch',
|
||||
'email': 'terriebranch@comtours.com',
|
||||
'age': 37,
|
||||
}, {
|
||||
'id': 36,
|
||||
'firstName': 'Louise',
|
||||
'lastName': 'Aguirre',
|
||||
'username': '@Kirby',
|
||||
'email': 'louisekirby@comtours.com',
|
||||
'age': 44,
|
||||
}, {
|
||||
'id': 37,
|
||||
'firstName': 'David',
|
||||
'lastName': 'Patton',
|
||||
'username': '@Sanders',
|
||||
'email': 'davidsanders@comtours.com',
|
||||
'age': 26,
|
||||
}, {
|
||||
'id': 38,
|
||||
'firstName': 'Holden',
|
||||
'lastName': 'Barlow',
|
||||
'username': '@Mckinney',
|
||||
'email': 'holdenmckinney@comtours.com',
|
||||
'age': 11,
|
||||
}, {
|
||||
'id': 39,
|
||||
'firstName': 'Baker',
|
||||
'lastName': 'Rivera',
|
||||
'username': '@Montoya',
|
||||
'email': 'bakermontoya@comtours.com',
|
||||
'age': 47,
|
||||
}, {
|
||||
'id': 40,
|
||||
'firstName': 'Belinda',
|
||||
'lastName': 'Lloyd',
|
||||
'username': '@Calderon',
|
||||
'email': 'belindacalderon@comtours.com',
|
||||
'age': 21,
|
||||
}, {
|
||||
'id': 41,
|
||||
'firstName': 'Pearson',
|
||||
'lastName': 'Patrick',
|
||||
'username': '@Clements',
|
||||
'email': 'pearsonclements@comtours.com',
|
||||
'age': 42,
|
||||
}, {
|
||||
'id': 42,
|
||||
'firstName': 'Alyce',
|
||||
'lastName': 'Mckee',
|
||||
'username': '@Daugherty',
|
||||
'email': 'alycedaugherty@comtours.com',
|
||||
'age': 55,
|
||||
}, {
|
||||
'id': 43,
|
||||
'firstName': 'Valencia',
|
||||
'lastName': 'Spence',
|
||||
'username': '@Olsen',
|
||||
'email': 'valenciaolsen@comtours.com',
|
||||
'age': 20,
|
||||
}, {
|
||||
'id': 44,
|
||||
'firstName': 'Leach',
|
||||
'lastName': 'Holcomb',
|
||||
'username': '@Humphrey',
|
||||
'email': 'leachhumphrey@comtours.com',
|
||||
'age': 28,
|
||||
}, {
|
||||
'id': 45,
|
||||
'firstName': 'Moss',
|
||||
'lastName': 'Baxter',
|
||||
'username': '@Fitzpatrick',
|
||||
'email': 'mossfitzpatrick@comtours.com',
|
||||
'age': 51,
|
||||
}, {
|
||||
'id': 46,
|
||||
'firstName': 'Jeanne',
|
||||
'lastName': 'Cooke',
|
||||
'username': '@Ward',
|
||||
'email': 'jeanneward@comtours.com',
|
||||
'age': 59,
|
||||
}, {
|
||||
'id': 47,
|
||||
'firstName': 'Wilma',
|
||||
'lastName': 'Briggs',
|
||||
'username': '@Kidd',
|
||||
'email': 'wilmakidd@comtours.com',
|
||||
'age': 53,
|
||||
}, {
|
||||
'id': 48,
|
||||
'firstName': 'Beatrice',
|
||||
'lastName': 'Perry',
|
||||
'username': '@Gilbert',
|
||||
'email': 'beatricegilbert@comtours.com',
|
||||
'age': 39,
|
||||
}, {
|
||||
'id': 49,
|
||||
'firstName': 'Whitaker',
|
||||
'lastName': 'Hyde',
|
||||
'username': '@Mcdonald',
|
||||
'email': 'whitakermcdonald@comtours.com',
|
||||
'age': 35,
|
||||
}, {
|
||||
'id': 50,
|
||||
'firstName': 'Rebekah',
|
||||
'lastName': 'Duran',
|
||||
'username': '@Gross',
|
||||
'email': 'rebekahgross@comtours.com',
|
||||
'age': 40,
|
||||
}, {
|
||||
'id': 51,
|
||||
'firstName': 'Earline',
|
||||
'lastName': 'Mayer',
|
||||
'username': '@Woodward',
|
||||
'email': 'earlinewoodward@comtours.com',
|
||||
'age': 52,
|
||||
}, {
|
||||
'id': 52,
|
||||
'firstName': 'Moran',
|
||||
'lastName': 'Baxter',
|
||||
'username': '@Johns',
|
||||
'email': 'moranjohns@comtours.com',
|
||||
'age': 20,
|
||||
}, {
|
||||
'id': 53,
|
||||
'firstName': 'Nanette',
|
||||
'lastName': 'Hubbard',
|
||||
'username': '@Cooke',
|
||||
'email': 'nanettecooke@comtours.com',
|
||||
'age': 55,
|
||||
}, {
|
||||
'id': 54,
|
||||
'firstName': 'Dalton',
|
||||
'lastName': 'Walker',
|
||||
'username': '@Hendricks',
|
||||
'email': 'daltonhendricks@comtours.com',
|
||||
'age': 25,
|
||||
}, {
|
||||
'id': 55,
|
||||
'firstName': 'Bennett',
|
||||
'lastName': 'Blake',
|
||||
'username': '@Pena',
|
||||
'email': 'bennettpena@comtours.com',
|
||||
'age': 13,
|
||||
}, {
|
||||
'id': 56,
|
||||
'firstName': 'Kellie',
|
||||
'lastName': 'Horton',
|
||||
'username': '@Weiss',
|
||||
'email': 'kellieweiss@comtours.com',
|
||||
'age': 48,
|
||||
}, {
|
||||
'id': 57,
|
||||
'firstName': 'Hobbs',
|
||||
'lastName': 'Talley',
|
||||
'username': '@Sanford',
|
||||
'email': 'hobbssanford@comtours.com',
|
||||
'age': 28,
|
||||
}, {
|
||||
'id': 58,
|
||||
'firstName': 'Mcguire',
|
||||
'lastName': 'Donaldson',
|
||||
'username': '@Roman',
|
||||
'email': 'mcguireroman@comtours.com',
|
||||
'age': 38,
|
||||
}, {
|
||||
'id': 59,
|
||||
'firstName': 'Rodriquez',
|
||||
'lastName': 'Saunders',
|
||||
'username': '@Harper',
|
||||
'email': 'rodriquezharper@comtours.com',
|
||||
'age': 20,
|
||||
}, {
|
||||
'id': 60,
|
||||
'firstName': 'Lou',
|
||||
'lastName': 'Conner',
|
||||
'username': '@Sanchez',
|
||||
'email': 'lousanchez@comtours.com',
|
||||
'age': 16,
|
||||
}];
|
||||
|
||||
getData() {
|
||||
return this.data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { of as observableOf, Observable } from 'rxjs';
|
||||
import { SolarData } from '../data/solar';
|
||||
|
||||
@Injectable()
|
||||
export class SolarService extends SolarData {
|
||||
private value = 42;
|
||||
|
||||
getSolarData(): Observable<number> {
|
||||
return observableOf(this.value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { of as observableOf, Observable } from 'rxjs';
|
||||
import { StatsBarData } from '../data/stats-bar';
|
||||
|
||||
@Injectable()
|
||||
export class StatsBarService extends StatsBarData {
|
||||
|
||||
private statsBarData: number[] = [
|
||||
300, 520, 435, 530,
|
||||
730, 620, 660, 860,
|
||||
];
|
||||
|
||||
getStatsBarData(): Observable<number[]> {
|
||||
return observableOf(this.statsBarData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { of as observableOf, Observable } from 'rxjs';
|
||||
import { ProgressInfo, StatsProgressBarData } from '../data/stats-progress-bar';
|
||||
|
||||
@Injectable()
|
||||
export class StatsProgressBarService extends StatsProgressBarData {
|
||||
private progressInfoData: ProgressInfo[] = [
|
||||
{
|
||||
title: 'Today’s Profit',
|
||||
value: 572900,
|
||||
activeProgress: 70,
|
||||
description: 'Better than last week (70%)',
|
||||
},
|
||||
{
|
||||
title: 'New Orders',
|
||||
value: 6378,
|
||||
activeProgress: 30,
|
||||
description: 'Better than last week (30%)',
|
||||
},
|
||||
{
|
||||
title: 'New Comments',
|
||||
value: 200,
|
||||
activeProgress: 55,
|
||||
description: 'Better than last week (55%)',
|
||||
},
|
||||
];
|
||||
|
||||
getProgressInfoData(): Observable<ProgressInfo[]> {
|
||||
return observableOf(this.progressInfoData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { of as observableOf, Observable } from 'rxjs';
|
||||
import { TemperatureHumidityData, Temperature } from '../data/temperature-humidity';
|
||||
|
||||
@Injectable()
|
||||
export class TemperatureHumidityService extends TemperatureHumidityData {
|
||||
|
||||
private temperatureDate: Temperature = {
|
||||
value: 24,
|
||||
min: 12,
|
||||
max: 30,
|
||||
};
|
||||
|
||||
private humidityDate: Temperature = {
|
||||
value: 87,
|
||||
min: 0,
|
||||
max: 100,
|
||||
};
|
||||
|
||||
getTemperatureData(): Observable<Temperature> {
|
||||
return observableOf(this.temperatureDate);
|
||||
}
|
||||
|
||||
getHumidityData(): Observable<Temperature> {
|
||||
return observableOf(this.humidityDate);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { of as observableOf, Observable } from 'rxjs';
|
||||
import { PeriodsService } from './periods.service';
|
||||
import { TrafficBarData, TrafficBar } from '../data/traffic-bar';
|
||||
|
||||
@Injectable()
|
||||
export class TrafficBarService extends TrafficBarData {
|
||||
|
||||
private data = { };
|
||||
|
||||
constructor(private period: PeriodsService) {
|
||||
super();
|
||||
this.data = {
|
||||
week: this.getDataForWeekPeriod(),
|
||||
month: this.getDataForMonthPeriod(),
|
||||
year: this.getDataForYearPeriod(),
|
||||
};
|
||||
}
|
||||
|
||||
getDataForWeekPeriod(): TrafficBar {
|
||||
return {
|
||||
data: [10, 15, 19, 7, 20, 13, 15],
|
||||
labels: this.period.getWeeks(),
|
||||
formatter: '{c0} MB',
|
||||
};
|
||||
}
|
||||
|
||||
getDataForMonthPeriod(): TrafficBar {
|
||||
return {
|
||||
data: [0.5, 0.3, 0.8, 0.2, 0.3, 0.7, 0.8, 1, 0.7, 0.8, 0.6, 0.7],
|
||||
labels: this.period.getMonths(),
|
||||
formatter: '{c0} GB',
|
||||
};
|
||||
}
|
||||
|
||||
getDataForYearPeriod(): TrafficBar {
|
||||
return {
|
||||
data: [10, 15, 19, 7, 20, 13, 15, 19, 11],
|
||||
labels: this.period.getYears(),
|
||||
formatter: '{c0} GB',
|
||||
};
|
||||
}
|
||||
|
||||
getTrafficBarData(period: string): Observable<TrafficBar> {
|
||||
return observableOf(this.data[period]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { of as observableOf, Observable } from 'rxjs';
|
||||
import { TrafficChartData } from '../data/traffic-chart';
|
||||
|
||||
@Injectable()
|
||||
export class TrafficChartService extends TrafficChartData {
|
||||
|
||||
private data: number[] = [
|
||||
300, 520, 435, 530,
|
||||
730, 620, 660, 860,
|
||||
];
|
||||
|
||||
getTrafficChartData(): Observable<number[]> {
|
||||
return observableOf(this.data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { of as observableOf, Observable } from 'rxjs';
|
||||
import { PeriodsService } from './periods.service';
|
||||
import { TrafficList, TrafficListData } from '../data/traffic-list';
|
||||
|
||||
@Injectable()
|
||||
export class TrafficListService extends TrafficListData {
|
||||
|
||||
private getRandom = (roundTo: number) => Math.round(Math.random() * roundTo);
|
||||
private data = {};
|
||||
|
||||
constructor(private period: PeriodsService) {
|
||||
super();
|
||||
this.data = {
|
||||
week: this.getDataWeek(),
|
||||
month: this.getDataMonth(),
|
||||
year: this.getDataYear(),
|
||||
};
|
||||
}
|
||||
|
||||
private getDataWeek(): TrafficList[] {
|
||||
const getFirstDateInPeriod = () => {
|
||||
const weeks = this.period.getWeeks();
|
||||
|
||||
return weeks[weeks.length - 1];
|
||||
};
|
||||
|
||||
return this.reduceData(this.period.getWeeks(), getFirstDateInPeriod);
|
||||
}
|
||||
|
||||
private getDataMonth(): TrafficList[] {
|
||||
const getFirstDateInPeriod = () => {
|
||||
const months = this.period.getMonths();
|
||||
|
||||
return months[months.length - 1];
|
||||
};
|
||||
|
||||
return this.reduceData(this.period.getMonths(), getFirstDateInPeriod);
|
||||
}
|
||||
|
||||
private getDataYear(): TrafficList[] {
|
||||
const getFirstDateInPeriod = () => {
|
||||
const years = this.period.getYears();
|
||||
|
||||
return `${parseInt(years[0], 10) - 1}`;
|
||||
};
|
||||
|
||||
return this.reduceData(this.period.getYears(), getFirstDateInPeriod);
|
||||
}
|
||||
|
||||
private reduceData(timePeriods: string[], getFirstDateInPeriod: () => string): TrafficList[] {
|
||||
return timePeriods.reduce((result, timePeriod, index) => {
|
||||
const hasResult = result[index - 1];
|
||||
const prevDate = hasResult ?
|
||||
result[index - 1].comparison.nextDate :
|
||||
getFirstDateInPeriod();
|
||||
const prevValue = hasResult ?
|
||||
result[index - 1].comparison.nextValue :
|
||||
this.getRandom(100);
|
||||
const nextValue = this.getRandom(100);
|
||||
const deltaValue = prevValue - nextValue;
|
||||
|
||||
const item = {
|
||||
date: timePeriod,
|
||||
value: this.getRandom(1000),
|
||||
delta: {
|
||||
up: deltaValue <= 0,
|
||||
value: Math.abs(deltaValue),
|
||||
},
|
||||
comparison: {
|
||||
prevDate,
|
||||
prevValue,
|
||||
nextDate: timePeriod,
|
||||
nextValue,
|
||||
},
|
||||
};
|
||||
|
||||
return [...result, item];
|
||||
}, []);
|
||||
}
|
||||
|
||||
getTrafficListData(period: string): Observable<TrafficList> {
|
||||
return observableOf(this.data[period]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { of as observableOf, Observable } from 'rxjs';
|
||||
import { PeriodsService } from './periods.service';
|
||||
import { UserActive, UserActivityData } from '../data/user-activity';
|
||||
|
||||
@Injectable()
|
||||
export class UserActivityService extends UserActivityData {
|
||||
|
||||
private getRandom = (roundTo: number) => Math.round(Math.random() * roundTo);
|
||||
private generateUserActivityRandomData(date) {
|
||||
return {
|
||||
date,
|
||||
pagesVisitCount: this.getRandom(1000),
|
||||
deltaUp: this.getRandom(1) % 2 === 0,
|
||||
newVisits: this.getRandom(100),
|
||||
};
|
||||
}
|
||||
|
||||
data = {};
|
||||
|
||||
constructor(private periods: PeriodsService) {
|
||||
super();
|
||||
this.data = {
|
||||
week: this.getDataWeek(),
|
||||
month: this.getDataMonth(),
|
||||
year: this.getDataYear(),
|
||||
};
|
||||
}
|
||||
|
||||
private getDataWeek(): UserActive[] {
|
||||
return this.periods.getWeeks().map((week) => {
|
||||
return this.generateUserActivityRandomData(week);
|
||||
});
|
||||
}
|
||||
|
||||
private getDataMonth(): UserActive[] {
|
||||
const currentDate = new Date();
|
||||
const days = currentDate.getDate();
|
||||
const month = this.periods.getMonths()[currentDate.getMonth()];
|
||||
|
||||
return Array.from(Array(days)).map((_, index) => {
|
||||
const date = `${index + 1} ${month}`;
|
||||
|
||||
return this.generateUserActivityRandomData(date);
|
||||
});
|
||||
}
|
||||
|
||||
private getDataYear(): UserActive[] {
|
||||
return this.periods.getYears().map((year) => {
|
||||
return this.generateUserActivityRandomData(year);
|
||||
});
|
||||
}
|
||||
|
||||
getUserActivityData(period: string): Observable<UserActive[]> {
|
||||
return observableOf(this.data[period]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import { of as observableOf, Observable } from 'rxjs';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Contacts, RecentUsers, UserData } from '../data/users';
|
||||
|
||||
@Injectable()
|
||||
export class UserService extends UserData {
|
||||
|
||||
private time: Date = new Date;
|
||||
|
||||
private users = {
|
||||
nick: { name: 'Nick Jones', picture: 'assets/images/nick.png' },
|
||||
eva: { name: 'Eva Moor', picture: 'assets/images/eva.png' },
|
||||
jack: { name: 'Jack Williams', picture: 'assets/images/jack.png' },
|
||||
lee: { name: 'Lee Wong', picture: 'assets/images/lee.png' },
|
||||
alan: { name: 'Alan Thompson', picture: 'assets/images/alan.png' },
|
||||
kate: { name: 'Kate Martinez', picture: 'assets/images/kate.png' },
|
||||
};
|
||||
private types = {
|
||||
mobile: 'mobile',
|
||||
home: 'home',
|
||||
work: 'work',
|
||||
};
|
||||
private contacts: Contacts[] = [
|
||||
{ user: this.users.nick, type: this.types.mobile },
|
||||
{ user: this.users.eva, type: this.types.home },
|
||||
{ user: this.users.jack, type: this.types.mobile },
|
||||
{ user: this.users.lee, type: this.types.mobile },
|
||||
{ user: this.users.alan, type: this.types.home },
|
||||
{ user: this.users.kate, type: this.types.work },
|
||||
];
|
||||
private recentUsers: RecentUsers[] = [
|
||||
{ user: this.users.alan, type: this.types.home, time: this.time.setHours(21, 12)},
|
||||
{ user: this.users.eva, type: this.types.home, time: this.time.setHours(17, 45)},
|
||||
{ user: this.users.nick, type: this.types.mobile, time: this.time.setHours(5, 29)},
|
||||
{ user: this.users.lee, type: this.types.mobile, time: this.time.setHours(11, 24)},
|
||||
{ user: this.users.jack, type: this.types.mobile, time: this.time.setHours(10, 45)},
|
||||
{ user: this.users.kate, type: this.types.work, time: this.time.setHours(9, 42)},
|
||||
{ user: this.users.kate, type: this.types.work, time: this.time.setHours(9, 31)},
|
||||
{ user: this.users.jack, type: this.types.mobile, time: this.time.setHours(8, 0)},
|
||||
];
|
||||
|
||||
getUsers(): Observable<any> {
|
||||
return observableOf(this.users);
|
||||
}
|
||||
|
||||
getContacts(): Observable<Contacts[]> {
|
||||
return observableOf(this.contacts);
|
||||
}
|
||||
|
||||
getRecentUsers(): Observable<RecentUsers[]> {
|
||||
return observableOf(this.recentUsers);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { of as observableOf, Observable } from 'rxjs';
|
||||
import { PeriodsService } from './periods.service';
|
||||
import { OutlineData, VisitorsAnalyticsData } from '../data/visitors-analytics';
|
||||
|
||||
@Injectable()
|
||||
export class VisitorsAnalyticsService extends VisitorsAnalyticsData {
|
||||
|
||||
constructor(private periodService: PeriodsService) {
|
||||
super();
|
||||
}
|
||||
|
||||
private pieChartValue = 75;
|
||||
private innerLinePoints: number[] = [
|
||||
94, 188, 225, 244, 253, 254, 249, 235, 208,
|
||||
173, 141, 118, 105, 97, 94, 96, 104, 121, 147,
|
||||
183, 224, 265, 302, 333, 358, 375, 388, 395,
|
||||
400, 400, 397, 390, 377, 360, 338, 310, 278,
|
||||
241, 204, 166, 130, 98, 71, 49, 32, 20, 13, 9,
|
||||
];
|
||||
private outerLinePoints: number[] = [
|
||||
85, 71, 59, 50, 45, 42, 41, 44 , 58, 88,
|
||||
136 , 199, 267, 326, 367, 391, 400, 397,
|
||||
376, 319, 200, 104, 60, 41, 36, 37, 44,
|
||||
55, 74, 100 , 131, 159, 180, 193, 199, 200,
|
||||
195, 184, 164, 135, 103, 73, 50, 33, 22, 15, 11,
|
||||
];
|
||||
private generateOutlineLineData(): OutlineData[] {
|
||||
const months = this.periodService.getMonths();
|
||||
const outerLinePointsLength = this.outerLinePoints.length;
|
||||
const monthsLength = months.length;
|
||||
|
||||
return this.outerLinePoints.map((p, index) => {
|
||||
const monthIndex = Math.round(index / 4);
|
||||
const label = (index % Math.round(outerLinePointsLength / monthsLength) === 0)
|
||||
? months[monthIndex]
|
||||
: '';
|
||||
|
||||
return {
|
||||
label,
|
||||
value: p,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
getInnerLineChartData(): Observable<number[]> {
|
||||
return observableOf(this.innerLinePoints);
|
||||
}
|
||||
|
||||
getOutlineLineChartData(): Observable<OutlineData[]> {
|
||||
return observableOf(this.generateOutlineLineData());
|
||||
}
|
||||
|
||||
getPieChartData(): Observable<number> {
|
||||
return observableOf(this.pieChartValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export function throwIfAlreadyLoaded(parentModule: any, moduleName: string) {
|
||||
if (parentModule) {
|
||||
throw new Error(`${moduleName} has already been loaded. Import Core modules in the AppModule only.`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { NavigationEnd, Router } from '@angular/router';
|
||||
import { Location } from '@angular/common';
|
||||
import { filter } from 'rxjs/operators';
|
||||
|
||||
declare const ga: any;
|
||||
|
||||
@Injectable()
|
||||
export class AnalyticsService {
|
||||
private enabled: boolean;
|
||||
|
||||
constructor(private location: Location, private router: Router) {
|
||||
this.enabled = false;
|
||||
}
|
||||
|
||||
trackPageViews() {
|
||||
if (this.enabled) {
|
||||
this.router.events.pipe(
|
||||
filter((event) => event instanceof NavigationEnd),
|
||||
)
|
||||
.subscribe(() => {
|
||||
ga('send', {hitType: 'pageview', page: this.location.path()});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
trackEvent(eventName: string) {
|
||||
if (this.enabled) {
|
||||
ga('send', 'event', eventName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { LayoutService } from './layout.service';
|
||||
import { AnalyticsService } from './analytics.service';
|
||||
import { PlayerService } from './player.service';
|
||||
import { StateService } from './state.service';
|
||||
|
||||
export {
|
||||
LayoutService,
|
||||
AnalyticsService,
|
||||
PlayerService,
|
||||
StateService,
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { delay, share } from 'rxjs/operators';
|
||||
|
||||
@Injectable()
|
||||
export class LayoutService {
|
||||
|
||||
protected layoutSize$ = new Subject();
|
||||
|
||||
changeLayoutSize() {
|
||||
this.layoutSize$.next();
|
||||
}
|
||||
|
||||
onChangeLayoutSize(): Observable<any> {
|
||||
return this.layoutSize$.pipe(
|
||||
share(),
|
||||
delay(1),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
export class Track {
|
||||
name: string;
|
||||
artist: string;
|
||||
url: string;
|
||||
cover: string;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class PlayerService {
|
||||
current: number;
|
||||
playlist: Track[] = [
|
||||
{
|
||||
name: 'Don\'t Wanna Fight',
|
||||
artist: 'Alabama Shakes',
|
||||
url: 'https://p.scdn.co/mp3-preview/6156cdbca425a894972c02fca9d76c0b70e001af',
|
||||
cover: 'assets/images/cover1.jpg',
|
||||
},
|
||||
{
|
||||
name: 'Harder',
|
||||
artist: 'Daft Punk',
|
||||
url: 'https://p.scdn.co/mp3-preview/92a04c7c0e96bf93a1b1b1cae7dfff1921969a7b',
|
||||
cover: 'assets/images/cover2.jpg',
|
||||
},
|
||||
{
|
||||
name: 'Come Together',
|
||||
artist: 'Beatles',
|
||||
url: 'https://p.scdn.co/mp3-preview/83090a4db6899eaca689ae35f69126dbe65d94c9',
|
||||
cover: 'assets/images/cover3.jpg',
|
||||
},
|
||||
];
|
||||
|
||||
random(): Track {
|
||||
this.current = Math.floor(Math.random() * this.playlist.length);
|
||||
return this.playlist[this.current];
|
||||
}
|
||||
|
||||
next(): Track {
|
||||
return this.getNextTrack();
|
||||
}
|
||||
|
||||
prev() {
|
||||
return this.getPrevTrack();
|
||||
}
|
||||
|
||||
private getNextTrack(): Track {
|
||||
if (this.current === this.playlist.length - 1) {
|
||||
this.current = 0;
|
||||
} else {
|
||||
this.current++;
|
||||
}
|
||||
|
||||
return this.playlist[this.current];
|
||||
}
|
||||
|
||||
private getPrevTrack(): Track {
|
||||
if (this.current === 0) {
|
||||
this.current = this.playlist.length - 1;
|
||||
} else {
|
||||
this.current--;
|
||||
}
|
||||
|
||||
return this.playlist[this.current];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
import { Injectable, OnDestroy } from '@angular/core';
|
||||
import { of as observableOf, Observable, BehaviorSubject } from 'rxjs';
|
||||
import { takeWhile } from 'rxjs/operators';
|
||||
|
||||
import { NbLayoutDirectionService, NbLayoutDirection } from '@nebular/theme';
|
||||
|
||||
@Injectable()
|
||||
export class StateService implements OnDestroy {
|
||||
|
||||
protected layouts: any = [
|
||||
{
|
||||
name: 'One Column',
|
||||
icon: 'nb-layout-default',
|
||||
id: 'one-column',
|
||||
selected: true,
|
||||
},
|
||||
{
|
||||
name: 'Two Column',
|
||||
icon: 'nb-layout-two-column',
|
||||
id: 'two-column',
|
||||
},
|
||||
{
|
||||
name: 'Center Column',
|
||||
icon: 'nb-layout-centre',
|
||||
id: 'center-column',
|
||||
},
|
||||
];
|
||||
|
||||
protected sidebars: any = [
|
||||
{
|
||||
name: 'Sidebar at layout start',
|
||||
icon: 'nb-layout-sidebar-left',
|
||||
id: 'start',
|
||||
selected: true,
|
||||
},
|
||||
{
|
||||
name: 'Sidebar at layout end',
|
||||
icon: 'nb-layout-sidebar-right',
|
||||
id: 'end',
|
||||
},
|
||||
];
|
||||
|
||||
protected layoutState$ = new BehaviorSubject(this.layouts[0]);
|
||||
protected sidebarState$ = new BehaviorSubject(this.sidebars[0]);
|
||||
|
||||
alive = true;
|
||||
|
||||
constructor(directionService: NbLayoutDirectionService) {
|
||||
directionService.onDirectionChange()
|
||||
.pipe(takeWhile(() => this.alive))
|
||||
.subscribe(direction => this.updateSidebarIcons(direction));
|
||||
|
||||
this.updateSidebarIcons(directionService.getDirection());
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.alive = false;
|
||||
}
|
||||
|
||||
private updateSidebarIcons(direction: NbLayoutDirection) {
|
||||
const [ startSidebar, endSidebar ] = this.sidebars;
|
||||
const isLtr = direction === NbLayoutDirection.LTR;
|
||||
const startIconClass = isLtr ? 'nb-layout-sidebar-left' : 'nb-layout-sidebar-right';
|
||||
const endIconClass = isLtr ? 'nb-layout-sidebar-right' : 'nb-layout-sidebar-left';
|
||||
startSidebar.icon = startIconClass;
|
||||
endSidebar.icon = endIconClass;
|
||||
}
|
||||
|
||||
setLayoutState(state: any): any {
|
||||
this.layoutState$.next(state);
|
||||
}
|
||||
|
||||
getLayoutStates(): Observable<any[]> {
|
||||
return observableOf(this.layouts);
|
||||
}
|
||||
|
||||
onLayoutState(): Observable<any> {
|
||||
return this.layoutState$.asObservable();
|
||||
}
|
||||
|
||||
setSidebarState(state: any): any {
|
||||
this.sidebarState$.next(state);
|
||||
}
|
||||
|
||||
getSidebarStates(): Observable<any[]> {
|
||||
return observableOf(this.sidebars);
|
||||
}
|
||||
|
||||
onSidebarState(): Observable<any> {
|
||||
return this.sidebarState$.asObservable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
@import '../../styles/themes';
|
||||
@import '~@nebular/theme/styles/global/breakpoints';
|
||||
@import '~bootstrap/scss/mixins/breakpoints';
|
||||
|
||||
@include nb-install-component() {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.socials {
|
||||
font-size: 2rem;
|
||||
|
||||
a {
|
||||
padding: 0.4rem;
|
||||
color: nb-theme(text-hint-color);
|
||||
transition: color ease-out 0.1s;
|
||||
|
||||
&:hover {
|
||||
color: nb-theme(text-basic-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(is) {
|
||||
.socials {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-footer',
|
||||
styleUrls: ['./footer.component.scss'],
|
||||
template: `
|
||||
<span class="created-by">Created with ♥ by <b><a href="https://akveo.com" target="_blank">Akveo</a></b> 2019</span>
|
||||
<div class="socials">
|
||||
<a href="#" target="_blank" class="ion ion-social-github"></a>
|
||||
<a href="#" target="_blank" class="ion ion-social-facebook"></a>
|
||||
<a href="#" target="_blank" class="ion ion-social-twitter"></a>
|
||||
<a href="#" target="_blank" class="ion ion-social-linkedin"></a>
|
||||
</div>
|
||||
`,
|
||||
})
|
||||
export class FooterComponent {
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<div class="header-container">
|
||||
<div class="logo-container">
|
||||
<a (click)="toggleSidebar()" href="#" class="sidebar-toggle">
|
||||
<nb-icon icon="menu-2-outline"></nb-icon>
|
||||
</a>
|
||||
<a class="logo" href="#" (click)="navigateHome()">ngx-<span>admin</span></a>
|
||||
</div>
|
||||
<nb-select [selected]="currentTheme" (selectedChange)="changeTheme($event)" status="primary">
|
||||
<nb-option *ngFor="let theme of themes" [value]="theme.value"> {{ theme.name }}</nb-option>
|
||||
</nb-select>
|
||||
</div>
|
||||
|
||||
<div class="header-container">
|
||||
<nb-actions size="small">
|
||||
|
||||
<nb-action class="control-item">
|
||||
<nb-search type="rotate-layout"></nb-search>
|
||||
</nb-action>
|
||||
<nb-action class="control-item" icon="email-outline"></nb-action>
|
||||
<nb-action class="control-item" icon="bell-outline"></nb-action>
|
||||
<nb-action class="user-action" *nbIsGranted="['view', 'user']" >
|
||||
<nb-user [nbContextMenu]="userMenu"
|
||||
[onlyPicture]="userPictureOnly"
|
||||
[name]="user?.name"
|
||||
[picture]="user?.picture">
|
||||
</nb-user>
|
||||
</nb-action>
|
||||
</nb-actions>
|
||||
</div>
|
||||
@@ -0,0 +1,70 @@
|
||||
@import '~bootstrap/scss/mixins/breakpoints';
|
||||
@import '~@nebular/theme/styles/global/breakpoints';
|
||||
@import '../../styles/themes';
|
||||
|
||||
@include nb-install-component() {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
|
||||
.logo-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: calc(#{nb-theme(sidebar-width)} - #{nb-theme(header-padding)});
|
||||
}
|
||||
|
||||
nb-action {
|
||||
height: auto;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
nb-user {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
::ng-deep nb-search button {
|
||||
padding: 0!important;
|
||||
}
|
||||
|
||||
.header-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: auto;
|
||||
|
||||
.sidebar-toggle {
|
||||
@include nb-ltr(padding-right, 1.25rem);
|
||||
@include nb-rtl(padding-left, 1.25rem);
|
||||
text-decoration: none;
|
||||
color: nb-theme(text-hint-color);
|
||||
nb-icon {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
padding: 0 1.25rem;
|
||||
font-size: 1.75rem;
|
||||
@include nb-ltr(border-left, 1px solid nb-theme(divider-color));
|
||||
@include nb-rtl(border-right, 1px solid nb-theme(divider-color));
|
||||
white-space: nowrap;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(sm) {
|
||||
.control-item {
|
||||
display: none;
|
||||
}
|
||||
.user-action {
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(is) {
|
||||
nb-select {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { NbMediaBreakpointsService, NbMenuService, NbSidebarService, NbThemeService } from '@nebular/theme';
|
||||
|
||||
import { UserData } from '../../../@core/data/users';
|
||||
import { LayoutService } from '../../../@core/utils';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-header',
|
||||
styleUrls: ['./header.component.scss'],
|
||||
templateUrl: './header.component.html',
|
||||
})
|
||||
export class HeaderComponent implements OnInit, OnDestroy {
|
||||
|
||||
private destroy$: Subject<void> = new Subject<void>();
|
||||
userPictureOnly: boolean = false;
|
||||
user: any;
|
||||
|
||||
themes = [
|
||||
{
|
||||
value: 'default',
|
||||
name: 'Light',
|
||||
},
|
||||
{
|
||||
value: 'dark',
|
||||
name: 'Dark',
|
||||
},
|
||||
{
|
||||
value: 'cosmic',
|
||||
name: 'Cosmic',
|
||||
},
|
||||
{
|
||||
value: 'corporate',
|
||||
name: 'Corporate',
|
||||
},
|
||||
];
|
||||
|
||||
currentTheme = 'default';
|
||||
|
||||
userMenu = [ { title: 'Profile' }, { title: 'Log out' } ];
|
||||
|
||||
constructor(private sidebarService: NbSidebarService,
|
||||
private menuService: NbMenuService,
|
||||
private themeService: NbThemeService,
|
||||
private userService: UserData,
|
||||
private layoutService: LayoutService,
|
||||
private breakpointService: NbMediaBreakpointsService) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.currentTheme = this.themeService.currentTheme;
|
||||
|
||||
this.userService.getUsers()
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe((users: any) => this.user = users.nick);
|
||||
|
||||
const { xl } = this.breakpointService.getBreakpointsMap();
|
||||
this.themeService.onMediaQueryChange()
|
||||
.pipe(
|
||||
map(([, currentBreakpoint]) => currentBreakpoint.width < xl),
|
||||
takeUntil(this.destroy$),
|
||||
)
|
||||
.subscribe((isLessThanXl: boolean) => this.userPictureOnly = isLessThanXl);
|
||||
|
||||
this.themeService.onThemeChange()
|
||||
.pipe(
|
||||
map(({ name }) => name),
|
||||
takeUntil(this.destroy$),
|
||||
)
|
||||
.subscribe(themeName => this.currentTheme = themeName);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
|
||||
changeTheme(themeName: string) {
|
||||
this.themeService.changeTheme(themeName);
|
||||
}
|
||||
|
||||
toggleSidebar(): boolean {
|
||||
this.sidebarService.toggle(true, 'menu-sidebar');
|
||||
this.layoutService.changeLayoutSize();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
navigateHome() {
|
||||
this.menuService.navigateHome();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export * from './header/header.component';
|
||||
export * from './footer/footer.component';
|
||||
export * from './search-input/search-input.component';
|
||||
export * from './tiny-mce/tiny-mce.component';
|
||||
@@ -0,0 +1,33 @@
|
||||
:host {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
i.control-icon {
|
||||
&::before {
|
||||
font-size: 2.3rem;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
border: none;
|
||||
outline: none;
|
||||
margin-left: 1rem;
|
||||
width: 15rem;
|
||||
transition: width 0.2s ease;
|
||||
|
||||
&.hidden {
|
||||
width: 0;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
::ng-deep search-input {
|
||||
input {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { Component, ElementRef, EventEmitter, Output, ViewChild } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-search-input',
|
||||
styleUrls: ['./search-input.component.scss'],
|
||||
template: `
|
||||
<i class="control-icon ion ion-ios-search"
|
||||
(click)="showInput()"></i>
|
||||
<input placeholder="Type your search request here..."
|
||||
#input
|
||||
[class.hidden]="!isInputShown"
|
||||
(blur)="hideInput()"
|
||||
(input)="onInput($event)">
|
||||
`,
|
||||
})
|
||||
export class SearchInputComponent {
|
||||
@ViewChild('input', { static: true }) input: ElementRef;
|
||||
|
||||
@Output() search: EventEmitter<string> = new EventEmitter<string>();
|
||||
|
||||
isInputShown = false;
|
||||
|
||||
showInput() {
|
||||
this.isInputShown = true;
|
||||
this.input.nativeElement.focus();
|
||||
}
|
||||
|
||||
hideInput() {
|
||||
this.isInputShown = false;
|
||||
}
|
||||
|
||||
onInput(val: string) {
|
||||
this.search.emit(val);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { Component, OnDestroy, AfterViewInit, Output, EventEmitter, ElementRef } from '@angular/core';
|
||||
import { LocationStrategy } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-tiny-mce',
|
||||
template: '',
|
||||
})
|
||||
export class TinyMCEComponent implements OnDestroy, AfterViewInit {
|
||||
|
||||
@Output() editorKeyup = new EventEmitter<any>();
|
||||
|
||||
editor: any;
|
||||
|
||||
constructor(
|
||||
private host: ElementRef,
|
||||
private locationStrategy: LocationStrategy,
|
||||
) { }
|
||||
|
||||
ngAfterViewInit() {
|
||||
tinymce.init({
|
||||
target: this.host.nativeElement,
|
||||
plugins: ['link', 'paste', 'table'],
|
||||
skin_url: `${this.locationStrategy.getBaseHref()}assets/skins/lightgray`,
|
||||
setup: editor => {
|
||||
this.editor = editor;
|
||||
editor.on('keyup', () => {
|
||||
this.editorKeyup.emit(editor.getContent());
|
||||
});
|
||||
},
|
||||
height: '320',
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
tinymce.remove(this.editor);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from './one-column/one-column.layout';
|
||||
export * from './two-columns/two-columns.layout';
|
||||
export * from './three-columns/three-columns.layout';
|
||||
@@ -0,0 +1,9 @@
|
||||
@import '../../styles/themes';
|
||||
@import '~bootstrap/scss/mixins/breakpoints';
|
||||
@import '~@nebular/theme/styles/global/breakpoints';
|
||||
|
||||
@include nb-install-component() {
|
||||
.menu-sidebar ::ng-deep .scrollable {
|
||||
padding-top: nb-theme(layout-padding-top);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-one-column-layout',
|
||||
styleUrls: ['./one-column.layout.scss'],
|
||||
template: `
|
||||
<nb-layout windowMode>
|
||||
<nb-layout-header fixed>
|
||||
<ngx-header></ngx-header>
|
||||
</nb-layout-header>
|
||||
|
||||
<nb-sidebar class="menu-sidebar" tag="menu-sidebar" responsive>
|
||||
<ng-content select="nb-menu"></ng-content>
|
||||
</nb-sidebar>
|
||||
|
||||
<nb-layout-column>
|
||||
<ng-content select="router-outlet"></ng-content>
|
||||
</nb-layout-column>
|
||||
|
||||
<nb-layout-footer fixed>
|
||||
<ngx-footer></ngx-footer>
|
||||
</nb-layout-footer>
|
||||
</nb-layout>
|
||||
`,
|
||||
})
|
||||
export class OneColumnLayoutComponent {}
|
||||
@@ -0,0 +1,9 @@
|
||||
@import '../../styles/themes';
|
||||
@import '~bootstrap/scss/mixins/breakpoints';
|
||||
@import '~@nebular/theme/styles/global/breakpoints';
|
||||
|
||||
@include nb-install-component() {
|
||||
.menu-sidebar ::ng-deep .scrollable {
|
||||
padding-top: nb-theme(layout-padding-top);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-three-columns-layout',
|
||||
styleUrls: ['./three-columns.layout.scss'],
|
||||
template: `
|
||||
<nb-layout windowMode>
|
||||
<nb-layout-header fixed>
|
||||
<ngx-header></ngx-header>
|
||||
</nb-layout-header>
|
||||
|
||||
<nb-sidebar class="menu-sidebar" tag="menu-sidebar" responsive>
|
||||
<ng-content select="nb-menu"></ng-content>
|
||||
</nb-sidebar>
|
||||
|
||||
<nb-layout-column class="small">
|
||||
</nb-layout-column>
|
||||
|
||||
<nb-layout-column>
|
||||
<ng-content select="router-outlet"></ng-content>
|
||||
</nb-layout-column>
|
||||
|
||||
<nb-layout-column class="small">
|
||||
</nb-layout-column>
|
||||
|
||||
<nb-layout-footer fixed>
|
||||
<ngx-footer></ngx-footer>
|
||||
</nb-layout-footer>
|
||||
</nb-layout>
|
||||
`,
|
||||
})
|
||||
export class ThreeColumnsLayoutComponent {}
|
||||
@@ -0,0 +1,9 @@
|
||||
@import '../../styles/themes';
|
||||
@import '~bootstrap/scss/mixins/breakpoints';
|
||||
@import '~@nebular/theme/styles/global/breakpoints';
|
||||
|
||||
@include nb-install-component() {
|
||||
.menu-sidebar ::ng-deep .scrollable {
|
||||
padding-top: nb-theme(layout-padding-top);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-two-columns-layout',
|
||||
styleUrls: ['./two-columns.layout.scss'],
|
||||
template: `
|
||||
<nb-layout windowMode>
|
||||
<nb-layout-header fixed>
|
||||
<ngx-header></ngx-header>
|
||||
</nb-layout-header>
|
||||
|
||||
<nb-sidebar class="menu-sidebar" tag="menu-sidebar" responsive>
|
||||
<ng-content select="nb-menu"></ng-content>
|
||||
</nb-sidebar>
|
||||
|
||||
<nb-layout-column class="small">
|
||||
</nb-layout-column>
|
||||
|
||||
<nb-layout-column>
|
||||
<ng-content select="router-outlet"></ng-content>
|
||||
</nb-layout-column>
|
||||
|
||||
<nb-layout-footer fixed>
|
||||
<ngx-footer></ngx-footer>
|
||||
</nb-layout-footer>
|
||||
|
||||
</nb-layout>
|
||||
`,
|
||||
})
|
||||
export class TwoColumnsLayoutComponent {}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
@Pipe({ name: 'ngxCapitalize' })
|
||||
export class CapitalizePipe implements PipeTransform {
|
||||
|
||||
transform(input: string): string {
|
||||
return input && input.length
|
||||
? (input.charAt(0).toUpperCase() + input.slice(1).toLowerCase())
|
||||
: input;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export * from './capitalize.pipe';
|
||||
export * from './plural.pipe';
|
||||
export * from './round.pipe';
|
||||
export * from './timing.pipe';
|
||||
export * from './number-with-commas.pipe';
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
@Pipe({ name: 'ngxNumberWithCommas' })
|
||||
export class NumberWithCommasPipe implements PipeTransform {
|
||||
|
||||
transform(input: number): string {
|
||||
return new Intl.NumberFormat().format(input);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
@Pipe({ name: 'ngxPlural' })
|
||||
export class PluralPipe implements PipeTransform {
|
||||
|
||||
transform(input: number, label: string, pluralLabel: string = ''): string {
|
||||
input = input || 0;
|
||||
return input === 1
|
||||
? `${input} ${label}`
|
||||
: pluralLabel
|
||||
? `${input} ${pluralLabel}`
|
||||
: `${input} ${label}s`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
@Pipe({ name: 'ngxRound' })
|
||||
export class RoundPipe implements PipeTransform {
|
||||
|
||||
transform(input: number): number {
|
||||
return Math.round(input);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
@Pipe({ name: 'timing' })
|
||||
export class TimingPipe implements PipeTransform {
|
||||
transform(time: number): string {
|
||||
if (time) {
|
||||
const minutes = Math.floor(time / 60);
|
||||
const seconds = Math.floor(time % 60);
|
||||
return `${this.initZero(minutes)}${minutes}:${this.initZero(seconds)}${seconds}`;
|
||||
}
|
||||
|
||||
return '00:00';
|
||||
}
|
||||
|
||||
private initZero(time: number): string {
|
||||
return time < 10 ? '0' : '';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
@mixin ngx-layout() {
|
||||
@include media-breakpoint-down(is) {
|
||||
.row {
|
||||
margin-left: -10px;
|
||||
margin-right: -10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
@import './themes';
|
||||
|
||||
@mixin nb-overrides() {
|
||||
nb-select.size-medium button {
|
||||
padding: 0.4375rem 2.2rem 0.4375rem 1.125rem !important;
|
||||
|
||||
nb-icon {
|
||||
right: 0.41rem !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Akveo. All Rights Reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
|
||||
@mixin ngx-pace-theme() {
|
||||
|
||||
.pace .pace-progress {
|
||||
background: nb-theme(color-primary-default);
|
||||
}
|
||||
|
||||
.pace .pace-progress-inner {
|
||||
box-shadow: 0 0 10px nb-theme(color-primary-default), 0 0 5px nb-theme(color-primary-default);
|
||||
}
|
||||
|
||||
.pace .pace-activity {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,600,700&display=swap');
|
||||
|
||||
// themes - our custom or/and out of the box themes
|
||||
@import 'themes';
|
||||
|
||||
// framework component themes (styles tied to theme variables)
|
||||
@import '~@nebular/theme/styles/globals';
|
||||
@import '~@nebular/auth/styles/all';
|
||||
|
||||
@import '~bootstrap/scss/functions';
|
||||
@import '~bootstrap/scss/variables';
|
||||
@import '~bootstrap/scss/mixins';
|
||||
@import '~bootstrap/scss/grid';
|
||||
|
||||
// loading progress bar theme
|
||||
@import './pace.theme';
|
||||
|
||||
@import './layout';
|
||||
@import './overrides';
|
||||
|
||||
// install the framework and custom global styles
|
||||
@include nb-install() {
|
||||
|
||||
// framework global styles
|
||||
@include nb-theme-global();
|
||||
@include nb-auth-global();
|
||||
|
||||
@include ngx-layout();
|
||||
// loading progress bar
|
||||
@include ngx-pace-theme();
|
||||
|
||||
@include nb-overrides();
|
||||
};
|
||||
@@ -0,0 +1,308 @@
|
||||
import { NbJSThemeOptions, CORPORATE_THEME as baseTheme } from '@nebular/theme';
|
||||
|
||||
const baseThemeVariables = baseTheme.variables;
|
||||
|
||||
export const CORPORATE_THEME = {
|
||||
name: 'corporate',
|
||||
base: 'corporate',
|
||||
variables: {
|
||||
temperature: {
|
||||
arcFill: [ '#ffa36b', '#ffa36b', '#ff9e7a', '#ff9888', '#ff8ea0' ],
|
||||
arcEmpty: baseThemeVariables.bg2,
|
||||
thumbBg: baseThemeVariables.bg2,
|
||||
thumbBorder: '#ffa36b',
|
||||
},
|
||||
|
||||
solar: {
|
||||
gradientLeft: baseThemeVariables.primary,
|
||||
gradientRight: baseThemeVariables.primary,
|
||||
shadowColor: 'rgba(0, 0, 0, 0)',
|
||||
secondSeriesFill: baseThemeVariables.bg2,
|
||||
radius: ['80%', '90%'],
|
||||
},
|
||||
|
||||
traffic: {
|
||||
tooltipBg: baseThemeVariables.bg,
|
||||
tooltipBorderColor: baseThemeVariables.border2,
|
||||
tooltipExtraCss: 'border-radius: 10px; padding: 4px 16px;',
|
||||
tooltipTextColor: baseThemeVariables.fgText,
|
||||
tooltipFontWeight: 'normal',
|
||||
|
||||
yAxisSplitLine: 'rgba(0, 0, 0, 0)',
|
||||
|
||||
lineBg: baseThemeVariables.primary,
|
||||
lineShadowBlur: '0',
|
||||
itemColor: baseThemeVariables.border4,
|
||||
itemBorderColor: baseThemeVariables.border4,
|
||||
itemEmphasisBorderColor: baseThemeVariables.primaryLight,
|
||||
shadowLineDarkBg: 'rgba(0, 0, 0, 0)',
|
||||
shadowLineShadow: 'rgba(0, 0, 0, 0)',
|
||||
gradFrom: baseThemeVariables.bg,
|
||||
gradTo: baseThemeVariables.bg,
|
||||
},
|
||||
|
||||
electricity: {
|
||||
tooltipBg: baseThemeVariables.bg,
|
||||
tooltipLineColor: baseThemeVariables.fgText,
|
||||
tooltipLineWidth: '0',
|
||||
tooltipBorderColor: baseThemeVariables.border2,
|
||||
tooltipExtraCss: 'border-radius: 10px; padding: 8px 24px;',
|
||||
tooltipTextColor: baseThemeVariables.fgText,
|
||||
tooltipFontWeight: 'normal',
|
||||
|
||||
axisLineColor: baseThemeVariables.border3,
|
||||
xAxisTextColor: baseThemeVariables.fg,
|
||||
yAxisSplitLine: baseThemeVariables.separator,
|
||||
|
||||
itemBorderColor: baseThemeVariables.primary,
|
||||
lineStyle: 'solid',
|
||||
lineWidth: '4',
|
||||
lineGradFrom: baseThemeVariables.primary,
|
||||
lineGradTo: baseThemeVariables.primary,
|
||||
lineShadow: 'rgba(0, 0, 0, 0)',
|
||||
|
||||
areaGradFrom: 'rgba(0, 0, 0, 0)',
|
||||
areaGradTo: 'rgba(0, 0, 0, 0)',
|
||||
shadowLineDarkBg: 'rgba(0, 0, 0, 0)',
|
||||
},
|
||||
|
||||
bubbleMap: {
|
||||
titleColor: baseThemeVariables.fgText,
|
||||
areaColor: baseThemeVariables.bg4,
|
||||
areaHoverColor: baseThemeVariables.fgHighlight,
|
||||
areaBorderColor: baseThemeVariables.border5,
|
||||
},
|
||||
|
||||
profitBarAnimationEchart: {
|
||||
textColor: baseThemeVariables.fgText,
|
||||
|
||||
firstAnimationBarColor: baseThemeVariables.primary,
|
||||
secondAnimationBarColor: baseThemeVariables.success,
|
||||
|
||||
splitLineStyleOpacity: '1',
|
||||
splitLineStyleWidth: '1',
|
||||
splitLineStyleColor: baseThemeVariables.separator,
|
||||
|
||||
tooltipTextColor: baseThemeVariables.fgText,
|
||||
tooltipFontWeight: 'normal',
|
||||
tooltipFontSize: '16',
|
||||
tooltipBg: baseThemeVariables.bg,
|
||||
tooltipBorderColor: baseThemeVariables.border2,
|
||||
tooltipBorderWidth: '1',
|
||||
tooltipExtraCss: 'border-radius: 10px; padding: 4px 16px;',
|
||||
},
|
||||
|
||||
trafficBarEchart: {
|
||||
gradientFrom: baseThemeVariables.warningLight,
|
||||
gradientTo: baseThemeVariables.warning,
|
||||
shadow: baseThemeVariables.warningLight,
|
||||
shadowBlur: '0',
|
||||
|
||||
axisTextColor: baseThemeVariables.fgText,
|
||||
axisFontSize: '12',
|
||||
|
||||
tooltipBg: baseThemeVariables.bg,
|
||||
tooltipBorderColor: baseThemeVariables.border2,
|
||||
tooltipExtraCss: 'border-radius: 10px; padding: 8px 24px;',
|
||||
tooltipTextColor: baseThemeVariables.fgText,
|
||||
tooltipFontWeight: 'normal',
|
||||
},
|
||||
|
||||
countryOrders: {
|
||||
countryBorderColor: baseThemeVariables.border4,
|
||||
countryFillColor: baseThemeVariables.bg4,
|
||||
countryBorderWidth: '1',
|
||||
hoveredCountryBorderColor: baseThemeVariables.primary,
|
||||
hoveredCountryFillColor: baseThemeVariables.primaryLight,
|
||||
hoveredCountryBorderWidth: '1',
|
||||
|
||||
chartAxisLineColor: baseThemeVariables.border4,
|
||||
chartAxisTextColor: baseThemeVariables.fg,
|
||||
chartAxisFontSize: '16',
|
||||
chartGradientTo: baseThemeVariables.primary,
|
||||
chartGradientFrom: baseThemeVariables.primaryLight,
|
||||
chartAxisSplitLine: baseThemeVariables.separator,
|
||||
chartShadowLineColor: baseThemeVariables.primaryLight,
|
||||
|
||||
chartLineBottomShadowColor: baseThemeVariables.primary,
|
||||
|
||||
chartInnerLineColor: baseThemeVariables.bg2,
|
||||
},
|
||||
|
||||
echarts: {
|
||||
bg: baseThemeVariables.bg,
|
||||
textColor: baseThemeVariables.fgText,
|
||||
axisLineColor: baseThemeVariables.fgText,
|
||||
splitLineColor: baseThemeVariables.separator,
|
||||
itemHoverShadowColor: 'rgba(0, 0, 0, 0.5)',
|
||||
tooltipBackgroundColor: baseThemeVariables.primary,
|
||||
areaOpacity: '0.7',
|
||||
},
|
||||
|
||||
chartjs: {
|
||||
axisLineColor: baseThemeVariables.separator,
|
||||
textColor: baseThemeVariables.fgText,
|
||||
},
|
||||
|
||||
orders: {
|
||||
tooltipBg: baseThemeVariables.bg,
|
||||
tooltipLineColor: 'rgba(0, 0, 0, 0)',
|
||||
tooltipLineWidth: '0',
|
||||
tooltipBorderColor: baseThemeVariables.border2,
|
||||
tooltipExtraCss: 'border-radius: 10px; padding: 8px 24px;',
|
||||
tooltipTextColor: baseThemeVariables.fgText,
|
||||
tooltipFontWeight: 'normal',
|
||||
tooltipFontSize: '20',
|
||||
|
||||
axisLineColor: baseThemeVariables.border4,
|
||||
axisFontSize: '16',
|
||||
axisTextColor: baseThemeVariables.fg,
|
||||
yAxisSplitLine: baseThemeVariables.separator,
|
||||
|
||||
itemBorderColor: baseThemeVariables.primary,
|
||||
lineStyle: 'solid',
|
||||
lineWidth: '4',
|
||||
|
||||
// first line
|
||||
firstAreaGradFrom: baseThemeVariables.bg3,
|
||||
firstAreaGradTo: baseThemeVariables.bg3,
|
||||
firstShadowLineDarkBg: 'rgba(0, 0, 0, 0)',
|
||||
|
||||
// second line
|
||||
secondLineGradFrom: baseThemeVariables.primary,
|
||||
secondLineGradTo: baseThemeVariables.primary,
|
||||
|
||||
secondAreaGradFrom: 'rgba(0, 0, 0, 0)',
|
||||
secondAreaGradTo: 'rgba(0, 0, 0, 0)',
|
||||
secondShadowLineDarkBg: 'rgba(0, 0, 0, 0)',
|
||||
|
||||
// third line
|
||||
thirdLineGradFrom: baseThemeVariables.success,
|
||||
thirdLineGradTo: baseThemeVariables.successLight,
|
||||
|
||||
thirdAreaGradFrom: 'rgba(0, 0, 0, 0)',
|
||||
thirdAreaGradTo: 'rgba(0, 0, 0, 0)',
|
||||
thirdShadowLineDarkBg: 'rgba(0, 0, 0, 0)',
|
||||
},
|
||||
|
||||
profit: {
|
||||
bg: baseThemeVariables.bg,
|
||||
textColor: baseThemeVariables.fgText,
|
||||
axisLineColor: baseThemeVariables.border4,
|
||||
splitLineColor: baseThemeVariables.separator,
|
||||
areaOpacity: '1',
|
||||
|
||||
axisFontSize: '16',
|
||||
axisTextColor: baseThemeVariables.fg,
|
||||
|
||||
// first bar
|
||||
firstLineGradFrom: baseThemeVariables.bg3,
|
||||
firstLineGradTo: baseThemeVariables.bg3,
|
||||
firstLineShadow: 'rgba(0, 0, 0, 0)',
|
||||
|
||||
// second bar
|
||||
secondLineGradFrom: baseThemeVariables.primary,
|
||||
secondLineGradTo: baseThemeVariables.primary,
|
||||
secondLineShadow: 'rgba(0, 0, 0, 0)',
|
||||
|
||||
// third bar
|
||||
thirdLineGradFrom: baseThemeVariables.success,
|
||||
thirdLineGradTo: baseThemeVariables.success,
|
||||
thirdLineShadow: 'rgba(0, 0, 0, 0)',
|
||||
},
|
||||
|
||||
orderProfitLegend: {
|
||||
firstItem: baseThemeVariables.success,
|
||||
secondItem: baseThemeVariables.primary,
|
||||
thirdItem: baseThemeVariables.bg3,
|
||||
},
|
||||
|
||||
visitors: {
|
||||
tooltipBg: baseThemeVariables.bg,
|
||||
tooltipLineColor: 'rgba(0, 0, 0, 0)',
|
||||
tooltipLineWidth: '1',
|
||||
tooltipBorderColor: baseThemeVariables.border2,
|
||||
tooltipExtraCss: 'border-radius: 10px; padding: 8px 24px;',
|
||||
tooltipTextColor: baseThemeVariables.fgText,
|
||||
tooltipFontWeight: 'normal',
|
||||
tooltipFontSize: '20',
|
||||
|
||||
axisLineColor: baseThemeVariables.border4,
|
||||
axisFontSize: '16',
|
||||
axisTextColor: baseThemeVariables.fg,
|
||||
yAxisSplitLine: baseThemeVariables.separator,
|
||||
|
||||
itemBorderColor: baseThemeVariables.primary,
|
||||
lineStyle: 'dotted',
|
||||
lineWidth: '6',
|
||||
lineGradFrom: '#ffffff',
|
||||
lineGradTo: '#ffffff',
|
||||
lineShadow: 'rgba(0, 0, 0, 0)',
|
||||
|
||||
areaGradFrom: baseThemeVariables.primary,
|
||||
areaGradTo: baseThemeVariables.primaryLight,
|
||||
|
||||
innerLineStyle: 'solid',
|
||||
innerLineWidth: '1',
|
||||
|
||||
innerAreaGradFrom: baseThemeVariables.success,
|
||||
innerAreaGradTo: baseThemeVariables.success,
|
||||
},
|
||||
|
||||
visitorsLegend: {
|
||||
firstIcon: baseThemeVariables.success,
|
||||
secondIcon: baseThemeVariables.primary,
|
||||
},
|
||||
|
||||
visitorsPie: {
|
||||
firstPieGradientLeft: baseThemeVariables.success,
|
||||
firstPieGradientRight: baseThemeVariables.success,
|
||||
firstPieShadowColor: 'rgba(0, 0, 0, 0)',
|
||||
firstPieRadius: ['65%', '90%'],
|
||||
|
||||
secondPieGradientLeft: baseThemeVariables.warning,
|
||||
secondPieGradientRight: baseThemeVariables.warningLight,
|
||||
secondPieShadowColor: 'rgba(0, 0, 0, 0)',
|
||||
secondPieRadius: ['63%', '92%'],
|
||||
shadowOffsetX: '-4',
|
||||
shadowOffsetY: '-4',
|
||||
},
|
||||
|
||||
visitorsPieLegend: {
|
||||
firstSection: baseThemeVariables.warning,
|
||||
secondSection: baseThemeVariables.success,
|
||||
},
|
||||
|
||||
earningPie: {
|
||||
radius: ['65%', '100%'],
|
||||
center: ['50%', '50%'],
|
||||
|
||||
fontSize: '22',
|
||||
|
||||
firstPieGradientLeft: baseThemeVariables.success,
|
||||
firstPieGradientRight: baseThemeVariables.success,
|
||||
firstPieShadowColor: 'rgba(0, 0, 0, 0)',
|
||||
|
||||
secondPieGradientLeft: baseThemeVariables.primary,
|
||||
secondPieGradientRight: baseThemeVariables.primary,
|
||||
secondPieShadowColor: 'rgba(0, 0, 0, 0)',
|
||||
|
||||
thirdPieGradientLeft: baseThemeVariables.warning,
|
||||
thirdPieGradientRight: baseThemeVariables.warning,
|
||||
thirdPieShadowColor: 'rgba(0, 0, 0, 0)',
|
||||
},
|
||||
|
||||
earningLine: {
|
||||
gradFrom: baseThemeVariables.primary,
|
||||
gradTo: baseThemeVariables.primary,
|
||||
|
||||
tooltipTextColor: baseThemeVariables.fgText,
|
||||
tooltipFontWeight: 'normal',
|
||||
tooltipFontSize: '16',
|
||||
tooltipBg: baseThemeVariables.bg,
|
||||
tooltipBorderColor: baseThemeVariables.border2,
|
||||
tooltipBorderWidth: '1',
|
||||
tooltipExtraCss: 'border-radius: 10px; padding: 4px 16px;',
|
||||
},
|
||||
},
|
||||
} as NbJSThemeOptions;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user