before frontend login

This commit is contained in:
peter
2019-11-06 11:15:00 +01:00
parent 9d6681843b
commit 5466a3e8e8
57 changed files with 1013 additions and 2085 deletions
+143 -3
View File
@@ -1382,6 +1382,14 @@
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
}, },
"define-properties": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
"integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
"requires": {
"object-keys": "^1.0.12"
}
},
"define-property": { "define-property": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
@@ -1571,6 +1579,33 @@
"prr": "~1.0.1" "prr": "~1.0.1"
} }
}, },
"es-abstract": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz",
"integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==",
"requires": {
"es-to-primitive": "^1.2.0",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.0",
"is-callable": "^1.1.4",
"is-regex": "^1.0.4",
"object-inspect": "^1.6.0",
"object-keys": "^1.1.1",
"string.prototype.trimleft": "^2.1.0",
"string.prototype.trimright": "^2.1.0"
}
},
"es-to-primitive": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
"integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
"requires": {
"is-callable": "^1.1.4",
"is-date-object": "^1.0.1",
"is-symbol": "^1.0.2"
}
},
"escape-html": { "escape-html": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -2764,6 +2799,11 @@
} }
} }
}, },
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"gauge": { "gauge": {
"version": "2.7.4", "version": "2.7.4",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
@@ -2982,12 +3022,25 @@
"har-schema": "^2.0.0" "har-schema": "^2.0.0"
} }
}, },
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"requires": {
"function-bind": "^1.1.1"
}
},
"has-flag": { "has-flag": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true "dev": true
}, },
"has-symbols": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
"integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q="
},
"has-unicode": { "has-unicode": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
@@ -3235,6 +3288,11 @@
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
}, },
"is-callable": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
"integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA=="
},
"is-data-descriptor": { "is-data-descriptor": {
"version": "0.1.4", "version": "0.1.4",
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
@@ -3253,6 +3311,11 @@
} }
} }
}, },
"is-date-object": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
"integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY="
},
"is-descriptor": { "is-descriptor": {
"version": "0.1.6", "version": "0.1.6",
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
@@ -3340,6 +3403,14 @@
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
"integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o="
}, },
"is-regex": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
"integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
"requires": {
"has": "^1.0.1"
}
},
"is-relative": { "is-relative": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
@@ -3354,6 +3425,14 @@
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
"dev": true "dev": true
}, },
"is-symbol": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
"integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
"requires": {
"has-symbols": "^1.0.0"
}
},
"is-typedarray": { "is-typedarray": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
@@ -4182,6 +4261,16 @@
} }
} }
}, },
"object-inspect": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz",
"integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ=="
},
"object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
},
"object-visit": { "object-visit": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
@@ -4201,6 +4290,15 @@
"isobject": "^3.0.0" "isobject": "^3.0.0"
} }
}, },
"object.getownpropertydescriptors": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
"integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
"requires": {
"define-properties": "^1.1.2",
"es-abstract": "^1.5.1"
}
},
"object.map": { "object.map": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
@@ -4863,9 +4961,9 @@
} }
}, },
"rpclibrary": { "rpclibrary": {
"version": "1.3.17", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.3.17.tgz", "resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.4.0.tgz",
"integrity": "sha512-ZdhZ1TSDO+bcz5kCJ7Ol+YAAyYpwg7YI/hETS4vv3RYerUEQVZSZjcm22J5a91RnQVN2SRiXzdoXbbFb/Renog==", "integrity": "sha512-JUU7+HymV2ZTI+NrIVOiIr5LGFoRsPq4k/ffdUonqIpd9fjOHBQ2/PFLVXx9z94+dKxdqN8/D9ZXPwU03ovZrg==",
"requires": { "requires": {
"bsock": "^0.1.9", "bsock": "^0.1.9",
"http": "0.0.0", "http": "0.0.0",
@@ -5403,6 +5501,24 @@
"strip-ansi": "^5.1.0" "strip-ansi": "^5.1.0"
} }
}, },
"string.prototype.trimleft": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz",
"integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==",
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
}
},
"string.prototype.trimright": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz",
"integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==",
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
}
},
"string_decoder": { "string_decoder": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -5842,6 +5958,15 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
}, },
"util.promisify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz",
"integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==",
"requires": {
"define-properties": "^1.1.2",
"object.getownpropertydescriptors": "^2.0.3"
}
},
"utils-merge": { "utils-merge": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
@@ -6080,6 +6205,21 @@
} }
} }
}, },
"xml2js": {
"version": "0.4.22",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.22.tgz",
"integrity": "sha512-MWTbxAQqclRSTnehWWe5nMKzI3VmJ8ltiJEco8akcC6j3miOhjjfzKum5sId+CWhfxdOs/1xauYr8/ZDBtQiRw==",
"requires": {
"sax": ">=0.6.0",
"util.promisify": "~1.0.0",
"xmlbuilder": "~11.0.0"
}
},
"xmlbuilder": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
},
"xtend": { "xtend": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+4 -3
View File
@@ -9,7 +9,7 @@
"build-backend": "tsc; npm run webpack", "build-backend": "tsc; npm run webpack",
"build-frontend": "npm run build-dashboard; cp node_modules/rpclibrary/js/browser/rpclibrary.browser.js ./dist/static/FrontblockLib.js", "build-frontend": "npm run build-dashboard; cp node_modules/rpclibrary/js/browser/rpclibrary.browser.js ./dist/static/FrontblockLib.js",
"build-dashboard": "cd src/frontend; npm i && npm run build; mkdir ../../dist/static; cp -r dist/* ../../dist/static", "build-dashboard": "cd src/frontend; npm i && npm run build; mkdir ../../dist/static; cp -r dist/* ../../dist/static",
"clean": "rm -rf lib static plugins conf dist widget .rpt2_cache *.js *.ts src/frontend/dist data", "clean": "rm -rf lib static plugins conf dist/static widget .rpt2_cache *.js *.ts src/frontend/dist data",
"update-frontblock": "npm remove frontblock frontblock-generic; npm install frontblock-generic@latest frontblock@latest", "update-frontblock": "npm remove frontblock frontblock-generic; npm install frontblock-generic@latest frontblock@latest",
"webpack": "webpack --config src/backend/webpack.prod.js --progress --colors" "webpack": "webpack --config src/backend/webpack.prod.js --progress --colors"
}, },
@@ -37,13 +37,14 @@
"node-fetch": "^2.6.0", "node-fetch": "^2.6.0",
"path": "^0.12.7", "path": "^0.12.7",
"rimraf": "^3.0.0", "rimraf": "^3.0.0",
"rpclibrary": "^1.3.17", "rpclibrary": "^1.4.0",
"simple-git": "^1.124.0", "simple-git": "^1.124.0",
"spawn-sync": "^2.0.0", "spawn-sync": "^2.0.0",
"sqlite3": "^4.1.0", "sqlite3": "^4.1.0",
"trash": "^6.0.0", "trash": "^6.0.0",
"upgiter": "^1.0.4", "upgiter": "^1.0.4",
"uuid": "^3.3.3" "uuid": "^3.3.3",
"xml2js": "^0.4.22"
}, },
"devDependencies": { "devDependencies": {
"@types/express": "^4.17.0", "@types/express": "^4.17.0",
@@ -3,52 +3,26 @@
import { getLogger } from 'frontblock-generic/Types'; import { getLogger } from 'frontblock-generic/Types';
import { promises as fs, mkdirSync } from "fs" import { promises as fs, mkdirSync } from "fs"
import { RPCServer } from 'rpclibrary' import { RPCServer } from 'rpclibrary'
import { AdminConf, TableDefiniton } from './Types'; import { AdminConf, TableDefiniton } from '../Types/Types';
import { RPCConfigLoader } from './RPCConfigLoader'; import { RPCConfigLoader } from '../Components/RPCConfigLoader';
import { RPCPluginLoader } from './PluginLoader';
import * as Path from 'path' import * as Path from 'path'
import Knex = require('knex'); import * as Knex from 'knex';
import http = require('http'); import * as http from 'http';
import express = require('express'); import * as express from 'express';
import { TableDefinitionExporter } from './Interfaces'; import { TableDefinitionExporter } from '../Types/Interfaces';
import { FrontworkEventBus } from './Eventbus'; import { FrontworkComponent } from '../Types/FrontworkComponent';
const logger = getLogger("admin", 'debug') const logger = getLogger("admin", 'debug')
export class FrontworkAdmin export class FrontworkAdmin
implements TableDefinitionExporter { implements TableDefinitionExporter {
knex:Knex
config: RPCConfigLoader<AdminConf>
private express private express
private httpServer private httpServer
private pluginLoader:RPCPluginLoader = new RPCPluginLoader(this)
private eventBus:FrontworkEventBus = new FrontworkEventBus(this)
config: RPCConfigLoader<AdminConf>
knex:Knex
constructor(){} constructor(private components: FrontworkComponent[]){
async start(){
this.initConfig()
await this.makeKnex()
this.startWebsocket()
this.startWebserver()
}
protected configChangeHandler = (conf:AdminConf, key?:string) => {
if(key === 'dbConf'){
this.makeKnex()
}
}
getConfigKey(key:string){
return this.config.getConfigKey(key)
}
setConfigKey(key:string, value:any){
return this.config.setConfigKey(key, value)
}
private initConfig(){
this.config = new RPCConfigLoader<AdminConf>({ this.config = new RPCConfigLoader<AdminConf>({
name: "FrontworkAdminConf", name: "FrontworkAdminConf",
getDefaultConfig: () => { getDefaultConfig: () => {
@@ -65,20 +39,44 @@ implements TableDefinitionExporter {
} }
} }
}, './config', this.configChangeHandler) }, './config', this.configChangeHandler)
components.forEach(c => {
c.admin = this
if(c.onSetAdmin) c.onSetAdmin(this)
})
}
async start(){
await this.makeKnex()
this.startWebsocket()
await Promise.all( this.components.map(c => c.initialize?c.initialize():undefined ))
this.startWebserver()
}
protected configChangeHandler = (conf:AdminConf, key?:string) => {
if(key === 'dbConf'){
this.makeKnex()
}
}
getConfigKey(key:string){
return this.config.getConfigKey(key)
}
setConfigKey(key:string, value:any){
return this.config.setConfigKey(key, value)
} }
getTableDefinitions(): TableDefiniton[]{ getTableDefinitions(): TableDefiniton[]{
return [ return [
this.eventBus, ...this.components
...this.pluginLoader.getPlugins()
].flatMap(exporter => exporter.getTableDefinitions()) ].flatMap(exporter => exporter.getTableDefinitions())
} }
private startWebsocket(){ private startWebsocket(){
new RPCServer(20000, [ new RPCServer(20000, [
this.config, ...this.components,
this.pluginLoader,
this.eventBus
]) ])
} }
@@ -0,0 +1,34 @@
import { RPCExporter } from "rpclibrary"
import { FrontworkAdmin } from "../../Admin/Admin"
import { TableDefiniton } from "../../Types/Types"
import { PrivilegedRPCExporter } from "../../Types/PrivilegedRPCExporter"
import { FrontworkComponent } from "../../Types/FrontworkComponent"
export class Debugger
implements FrontworkComponent<any,any>{
public admin: FrontworkAdmin
name = "Debugger"
constructor(private exporters: PrivilegedRPCExporter[]){
}
exportRPCs(){
return [{
name: 'getTable',
call: async(table:string) => this.admin.knex.select('*').from(table)
},
...this.exporters.flatMap(e => e.exportRPCs()),
...this.exporters.flatMap(e => e.exportRPCFeatures().flatMap(e => e.exportRPCs()))]
}
exportRPCFeatures(): RPCExporter<any, any, {}>[] {
return []
}
getTableDefinitions(): TableDefiniton[] {
return []
}
}
@@ -1,9 +1,10 @@
import { RPCExporter, SubscriptionResponse, ErrorResponse, SuccessResponse } from "rpclibrary"; import { RPCExporter, SubscriptionResponse, ErrorResponse, SuccessResponse } from "rpclibrary";
import { FrontworkAdmin } from "./Admin"; import { FrontworkAdmin } from "../Admin/Admin";
import { TableDefinitionExporter } from "./Interfaces"; import { TableDefinitionExporter } from "../Types/Interfaces";
import { getLogger } from 'frontblock-generic/Types'; import { getLogger } from 'frontblock-generic/Types';
import * as uuid from 'uuid/v4' import * as uuid from 'uuid/v4'
import { TableDefiniton } from "../Types/Types";
export type NotificationSeverity = 'Info' | 'Important' | 'Error' export type NotificationSeverity = 'Info' | 'Important' | 'Error'
@@ -84,11 +85,11 @@ implements RPCExporter<EventbusIfc, "Eventbus">, TableDefinitionExporter {
}] }]
} }
getTableDefinitions(){ getTableDefinitions(): TableDefiniton[]{
return [{ return [{
name: 'notifications', name: 'notifications',
tableBuilder: (table) => { tableBuilder: (table) => {
table.increments('ID'); table.increments('ID').primary();
table.string('severity'); table.string('severity');
table.string('topic'); table.string('topic');
table.string('message'); table.string('message');
+107
View File
@@ -0,0 +1,107 @@
import { TableDefinitionExporter } from "../../Types/Interfaces";
import { TableDefiniton, _Rank } from "../../Types/Types";
import { FrontworkAdmin } from "../../Admin/Admin";
import { T1 } from "../../Types/Items";
import { FrontworkComponent } from "../../Types/FrontworkComponent";
import { RPC } from "rpclibrary";
const fetch = require('node-fetch')
const xml2js = require('xml2js');
const parser = new xml2js.Parser(/* options */);
export type ItemManagerFeatureIfc = any
export type Item = {
id?:number
name:string
iconname:string
url:string
quality:string
hidden:boolean
}
export class ItemManager
implements FrontworkComponent<ItemManagerFeatureIfc>, TableDefinitionExporter{
admin:FrontworkAdmin
name = "ItemManager";
exportRPCs(): RPC<any, any>[]{
return [{
name: 'getItems',
call: async () => await this.getItems()
},{
name: 'getItem',
call: async (name:string) => await this.getItem(name)
}]
}
exportRPCFeatures() {
return []
}
getItems = async () :Promise<Item[]> => await this.admin.knex.select('*').from('items')
getItem = async (name:string):Promise<Item> => {
const res = await fetch('https://classic.wowhead.com/item='+name+'&xml');
const txt = await res.text();
const r = await parser.parseStringPromise(txt);
try{
return <Item>{
name: r.wowhead.item[0].name[0],
iconname: r.wowhead.item[0].icon[0]._,
url: r.wowhead.item[0].link[0],
quality: r.wowhead.item[0].quality[0]._,
}
}catch (e){
console.log(name)
throw e
}
}
getTableDefinitions(): TableDefiniton[] {
return [
{
name: 'reservations',
tableBuilder: (table) => {
table.integer("user_id").primary()
table.foreign("user_id").references("id").inTable('users')
table.integer("item_id").primary()
table.foreign("item_id").references("id").inTable('items')
table.integer("raid_id").primary()
table.foreign("raid_id").references("id").inTable('raids')
}
},{
name: 'items',
tableBuilder: (table) => {
table.increments("id").primary()
table.string('name').unique().notNullable()
table.string('iconname').notNullable()
table.string('url').notNullable()
table.string('quality').defaultTo('Epic').notNullable()
table.boolean('hidden').defaultTo(false).notNullable()
}
}]
}
countItems = async() :Promise<number> => {
const count = await this.admin.knex('items').count('*');
return <number>count[0]['count(*)']
}
initialize = async() => {
const allItems = [...T1]
const countCache = await this.countItems()
if(countCache != allItems.length){
const items:Item[] = await Promise.all(allItems.map(async (i) => this.getItem(i)))
try{
await this.admin
.knex('items')
.insert(items)
}catch(e){
console.error(e)
}
}
}
}
@@ -0,0 +1,196 @@
import { RPCServer } from "rpclibrary";
import { TableDefiniton, AnyRPCExporter, User, RPCPermission, _Rank, Token, Auth } from "../../Types/Types";
import { FrontworkAdmin } from "../../Admin/Admin";
import { PrivilegedRPCExporter } from "../../Types/PrivilegedRPCExporter";
import { FrontworkComponent } from "../../Types/FrontworkComponent";
const uuid = require('uuid/v4')
export class LoginManager
implements FrontworkComponent{
name = "Authenticator" as "Authenticator";
admin:FrontworkAdmin
constructor(private exporters: PrivilegedRPCExporter[]){}
exportRPCs() {
return [
{
name: 'login' as 'login',
call: async (username:string, pwHash:string) => await this.login(username, pwHash)
},{
name: 'authenticate' as 'authenticate',
call: async (tokenValue:string | Token) => await this.authenticate(tokenValue)
}
]
}
onSetAdmin(admin:FrontworkAdmin){
this.exporters.forEach(e => e['admin'] = admin)
}
exportRPCFeatures() {
return [{
name: 'createUser' as 'createUser',
exportRPCs: () => [{
name: 'createUser' as 'createUser',
call: async (user:User) => {
return await this.createUser(user)
}
}]
},{
name: 'modifyPermissions' as 'modifyPermissions',
exportRPCs: () => [{
name: 'getPermissions' as 'getPermissions',
call: async () => await this.getPermissions()
},{
name: 'setPermission' as 'setPermission',
call: async (perm: RPCPermission) => await this.setPermission(perm)
}]
}]
}
getTableDefinitions(): TableDefiniton[] {
return [
{
name: 'users',
tableBuilder: (table) => {
table.increments("id").primary()
table.string("name").notNullable().unique()
table.string("pwhash").notNullable()
table.string("rank").notNullable()
table.string("class").notNullable()
table.string("email").nullable().unique()
}
},{
name: 'rpcpermissions',
tableBuilder: (table) => {
table.string("rpcName").primary().notNullable()
table.boolean("ADMIN").defaultTo(true).notNullable()
_Rank.forEach(r => table.boolean(r).defaultTo(false).notNullable())
}
},{
name: 'tokens',
tableBuilder: (table) => {
table.string('value').primary()
table.integer('user_id').notNullable()
table.foreign('user_id').references('users')
table.dateTime('created').defaultTo(this.admin.knex.fn.now())
}
}
,...this.exporters.flatMap(exp => exp['getTableDefinitions']?exp['getTableDefinitions']():undefined)]
}
async initialize(){
await Promise.all(
[this, ...this.exporters].flatMap(exp => exp.exportRPCFeatures().map(async (rpc) => {
try{
await this.admin.knex.insert({ rpcname: rpc.name }).into('rpcpermissions')
}catch(e){}
})))
await Promise.all(this.exporters.map(ex => ex['initialize']?ex['initialize']():undefined))
}
async setPermission(permission: RPCPermission){
await this.admin.knex('rpcpermissions')
.where('rpcname', '=', permission.name)
.update(permission)
}
getPermissions = async () : Promise<RPCPermission[]> => {
return await this.admin.knex.select('*').from('rpcpermissions')
}
getRPCForUser = async (user:User): Promise<AnyRPCExporter[]> => {
return [...this.exportRPCFeatures(), ...this.exporters.flatMap((exp) => exp.exportRPCFeatures())]
}
createUser = async(user:User): Promise<User> => {
await this.admin.knex('users')
.insert(user)
const users = await this.admin.knex
.select("*")
.from('users')
.where(user)
return users[0]
}
login = async(username:string, pwHash:string) : Promise<Token> => {
const res:User[] = await this.admin.knex
.select("*")
.from('users')
.where({ name: username })
if(res.length > 0 && pwHash === res[0].pwhash){
return await this.createToken(res[0])
}
throw new Error('login failed')
}
authenticate = async(tokenValue: string | Token) : Promise<Auth> => {
if(typeof tokenValue !== 'string') tokenValue = tokenValue.value
const res : User[] = await this.admin.knex
.select('users.id', 'name', 'class', 'rank', 'email')
.from('tokens')
.join('users', function(){
this.on('users.id', '=', 'tokens.user_id')
})
.where({ value: tokenValue})
if(res.length === 0)
throw new Error('authentication failed')
const allowedRPCs = await this.getRPCForUser(res[0])
const randomPort = 20000 + Math.floor(Math.random() * 10000)
while(true){
try{
let commSock = new RPCServer(randomPort, allowedRPCs, {
closeHandler: () => {
console.log(res[0].name, 'disconnected')
commSock.destroy()
},
connectionHandler: () => {
console.log(res[0].name, 'connected')
cancelTimeout()
},
sesame: tokenValue
})
const timeout = setTimeout(() => {
console.log(res[0].name, 'timeout')
commSock.destroy()
}, 10000)
const cancelTimeout = () => { clearTimeout(timeout) }
break;
}catch(e){
//retry
}
}
return {
port: randomPort,
user: res[0],
token: {
value: tokenValue,
user_id: res[0].id!
}
}
}
createToken = async(user:User): Promise<Token> => {
const old = await this.admin.knex.select('*').from('tokens').where({user_id: user.id})
if(old.length === 0){
const token:Token = {
value: uuid(),
user_id: user.id!
}
await this.admin.knex('tokens').insert(token)
return token
}else{
return old[0]
}
}
}
@@ -1,8 +1,8 @@
import { RPCExporter } from "rpclibrary"; import { RPCExporter } from "rpclibrary";
import { Git } from "upgiter" import { Git } from "upgiter"
import { FolderStatus } from "upgiter/js/src/Types"; import { FolderStatus } from "upgiter/js/src/Types";
import { Plugin } from "./Plugin"; import { Plugin } from "../Types/Plugin";
import { FrontworkAdmin } from "./Admin"; import { FrontworkAdmin } from "../Admin/Admin";
class PluginLoader { class PluginLoader {
private runningPlugins: Plugin[] = [] private runningPlugins: Plugin[] = []
@@ -0,0 +1,95 @@
import { TableDefiniton, User, _Rank, Raid, Signup, RaidManagerFeatureIfc } from "../../Types/Types";
import { FrontworkAdmin } from "../../Admin/Admin";
import { FrontworkComponent } from "../../Types/FrontworkComponent";
export class RaidManager
implements FrontworkComponent<RaidManagerFeatureIfc>{
name = "RaidManager";
admin: FrontworkAdmin
exportRPCs = () => []
exportRPCFeatures() {
return [{
name: 'manageRaid' as 'manageRaid',
exportRPCs: () => [{
name: 'createRaid' as 'createRaid',
call: async (raid:Raid) => await this.createRaid(raid)
},{
name: 'addSignup' as 'addSignup',
call: async(signup: Signup) => await this.addSignup(signup)
},{
name: 'removeSignup' as 'removeSignup',
call: async(signup: Signup) => await this.removeSignup(signup)
}]
},{
name: 'signup' as 'signup',
exportRPCs: () => [{
name: 'getRaids' as 'getRaids',
call: async () => await this.getRaids()
},{
name: 'getSingups' as 'getSingups',
call: async(raid: Raid) => await this.getSignups(raid)
},{
name: 'sign' as 'sign',
call: async(user:User, raid:Raid) => await this.sign(user, raid)
}]
},]
}
getTableDefinitions(): TableDefiniton[] {
return [
{
name: 'raids',
tableBuilder: (table) => {
table.increments('id').primary()
table.dateTime('start').notNullable()
table.string('description').notNullable()
table.string('title').notNullable()
table.integer('minrank').notNullable()
}
},{
name: 'signups',
tableBuilder: (table) => {
table.integer('raid_id').primary()
table.foreign('raid_id').references('id').inTable('raids')
table.integer('user_id').primary()
table.foreign('user_id').references('id').inTable('users')
}
}
]
}
createRaid = async (raid:Raid) => await this.admin
.knex('raids')
.insert(raid)
addSignup = async (signup: Signup) => await this.admin
.knex('signups')
.insert(signup)
removeSignup = async (signup: Signup) => await this.admin
.knex('signups')
.where({
raid_id: signup.raid_id,
user_id: signup.user_id
})
.delete()
getRaids = async () => await this.admin.knex
.select('*')
.from('raids')
getSignups = async (raid:Raid) => await this.admin.knex
.select('*')
.from('signups')
.where('raid_id', '=', raid.id!)
sign = async (user:User, raid:Raid) => await this.admin
.knex('signups')
.insert({
raid_id: raid.id!,
user_id: user.id!
})
}
-24
View File
@@ -1,24 +0,0 @@
import { Plugin } from "./Plugin"
import { getLogger } from "frontblock-generic/Types"
import { FrontworkAdmin } from "./Admin";
var exec = require('child-process-promise').exec;
const logger = getLogger("installer", 'info')
export type NPMPkgName = string
export type NPMVersion = string
export const installAdmin = (plugins: Plugin[] = []) => {
const npmPkgs:[NPMPkgName, NPMVersion][] = [['sqlite3', '4.1.0'], ['knex', '0.19.2']]
const deps = npmPkgs.map(tuple => tuple.join('@') ).join(" ")
logger.info("Installing plaform dependencies: "+deps)
exec("npm i " + deps).then(async process => {
logger.debug(process.stdout)
const Admin = require("./Admin").FrontworkAdmin
const fbAdmin:FrontworkAdmin = new Admin(plugins)
fbAdmin.start()
})
}
+20 -2
View File
@@ -1,2 +1,20 @@
import { installAdmin } from "./Installer"; import { FrontworkAdmin } from './Admin/Admin'
installAdmin() import { RaidManager } from "./Components/Raid/RaidManager";
import { ItemManager } from "./Components/Item/ItemManager";
import { LoginManager } from "./Components/Login/LoginManager";
import { Debugger } from './Components/Debugger/Debugger';
import { FrontworkComponent } from './Types/FrontworkComponent';
require('events').EventEmitter.defaultMaxListeners = 0;
let raidManager = new RaidManager()
let itemManager = new ItemManager()
let loginManager = new LoginManager([
raidManager,
itemManager
])
let components:FrontworkComponent[] = [ raidManager, itemManager, loginManager ]
let dbg = new Debugger(components)
new FrontworkAdmin([dbg, ...components]).start()
-14
View File
@@ -1,14 +0,0 @@
import Knex = require("knex")
export declare type NotificationSeverity = 'Info' | 'Important' | 'Error';
export type AdminConf = {
httpPort: number,
dbConf:Knex.Config,
eventBusConf: { [topic in string]: NotificationSeverity}
}
export type TableDefiniton = {
name: string,
tableBuilder: (table: Knex.CreateTableBuilder) => void
}
+24
View File
@@ -0,0 +1,24 @@
import { PrivilegedRPCExporter } from "./PrivilegedRPCExporter";
import { RPCInterface, RPC, AnyFunction, RPCExporter } from "rpclibrary";
import { TableDefinitionExporter } from "./Interfaces";
import { FrontworkAdmin } from "../Admin/Admin";
import { TableDefiniton } from "./Types";
export interface FrontworkComponent<
Ifc extends RPCInterface = RPCInterface,
Name extends keyof Ifc = keyof Ifc,
SubresT = {}
> extends
PrivilegedRPCExporter<Ifc, Name, SubresT>,
TableDefinitionExporter
{
admin:FrontworkAdmin
name: string;
exportRPCFeatures(): RPCExporter<Ifc, Name, SubresT>[]
exportRPCs(): RPC<string, AnyFunction, {}>[]
getTableDefinitions(): TableDefiniton[]
initialize?(): Promise<any>
onSetAdmin?(admin:FrontworkAdmin): void
}
@@ -2,4 +2,4 @@ import { TableDefiniton } from "./Types";
export interface TableDefinitionExporter{ export interface TableDefinitionExporter{
getTableDefinitions(): TableDefiniton[] getTableDefinitions(): TableDefiniton[]
} }
+64
View File
@@ -0,0 +1,64 @@
export const T1 = [
"Robe of Volatile Power",
"Salamander Scale Pants",
"Heavy Dark Iron Ring",
"Ring of Spell Power",
"Sorcerous Dagger",
"Wristguards of Stability",
"Helm of the Lifegiver",
"Fire Runed Grimoire",
"Crimson Shocker",
"Mana Igniting Cord",
"Quick Strike Ring",
"Seal of the Archmagus",
"Talisman of Ephemeral Power",
"Flameguard Gauntlets",
"Magma Tempered Boots",
"Obsidian Edged Blade",
"Aged Core Leather Gloves",
"Sabatons of the Flamewalker",
"Striker's Mark",
"Medallion of Steadfast Might",
"Earthshaker",
"Brutality Blade",
"Aurastone Hammer",
"Gutgore Ripper",
"Drillborer Disk",
"Azuresong Mageblade",
"Staff of Dominance",
"Blastershot Launcher",
"The Eye of Divinity",
"Ancient Petrified Leaf",
"Finkle's Lava Dredger",
"Core Hound Tooth",
"Core Forged Greaves",
"Gloves of the Hypnotic Flame",
"Sash of Whispered Secrets",
"Wild Growth Spaulders",
"Fireproof Cloak",
"Wristguards of True Flight",
"Fireguard Shoulders",
"Cauterizing Band",
"Onslaught Girdle",
"Perdition's Blade",
"Cloak of the Shrouded Mists",
"Band of Accuria",
"Crown of Destruction",
"Choker of the Fire Lord",
"Band of Sulfuras",
"Dragon's Blood Cape",
"Malistar's Defender",
"Spinal Reaper",
"Bonereaver's Edge",
"Shard of the Flame",
"Essence of the Pure Flame",
"Eye of Sulfuras",
"Deathbringer",
"Vis'kag the Bloodletter",
"Sapphiron Drape",
"Ancient Cornerstone Grimoire",
"Eskhandar's Collar",
"Ring of Binding",
"Shard of the Scale",
"Head of Onyxia",
"Bindings of the Windseeker"]
@@ -1,4 +1,4 @@
import { FrontworkAdmin } from "./Admin" import { FrontworkAdmin } from "../Admin/Admin"
import { RPC, RPCExporter } from "rpclibrary" import { RPC, RPCExporter } from "rpclibrary"
import { TableDefiniton } from "./Types" import { TableDefiniton } from "./Types"
import { TableDefinitionExporter } from "./Interfaces" import { TableDefinitionExporter } from "./Interfaces"
@@ -0,0 +1,7 @@
import { RPCExporter, RPCInterface, RPC, RPCInterfaceArray } from "rpclibrary";
export interface PrivilegedRPCExporter <Ifc extends RPCInterface = RPCInterface, Name extends keyof Ifc = keyof Ifc, SubresT = {}>
extends RPCExporter<any,any>{
exportRPCFeatures() : RPCExporter<Ifc, Name, SubresT>[]
}
+91
View File
@@ -0,0 +1,91 @@
import * as Knex from "knex"
import { RPCExporter } from "rpclibrary";
export declare type NotificationSeverity = 'Info' | 'Important' | 'Error';
export type AdminConf = {
httpPort: number,
dbConf:Knex.Config,
eventBusConf: { [topic in string]: NotificationSeverity}
}
export type TableDefiniton = {
name: string,
tableBuilder: (table: Knex.CreateTableBuilder) => void
}
export type Rank = "ADMIN" | "Guildmaster" | "Officer" | "Classleader" | "Raider" | "Trial" | "Social" | "Guest"
export const _Rank : Rank[] = ["Guildmaster" , "Officer" , "Classleader" , "Raider" , "Trial" , "Social" , "Guest"]
export type Class = "Warrior" | "Rogue" | "Hunter" | "Mage" | "Warlock" | "Priest" | "Shaman" | "Paladin" | "Druid"
export const _Class : Class[] = ["Warrior" , "Rogue" , "Hunter" , "Mage" , "Warlock" , "Priest" , "Shaman" , "Paladin" , "Druid"]
export type AnyRPCExporter = RPCExporter<any,any>
export type RPCPermission = {
name: string
} & {
[rank in Rank] : boolean
}
export type User = {
id?: number
name: string
pwhash: string
class: Class
rank: Rank
email?: string
}
export type Raid = {
id?: number
title: string
description: string
start: string
minrank: Rank
}
export type Signup = {
raid_id: number
user_id: number
}
export type Token = {
value: string
user_id: number
created?: number
}
export type Auth = {port: number, user: User, token: Token}
export type FrontcraftFeatureIfc = RaidManagerFeatureIfc & LoginManagerFeatureIfc
export type LoginManagerIfc = {
Authenticator: {
login: (username:string, pwHash:string) => Promise<Token>
authenticate: (token:string | Token) => Promise<Auth>
}
}
export type LoginManagerFeatureIfc = {
createUser: {
createUser: (user:User) => Promise<User>
}
modifyPermissions: {
setPermission: (perm: RPCPermission) => Promise<void>
getPermissions: () => Promise<RPCPermission[]>
}
}
export type RaidManagerFeatureIfc = {
manageRaid: {
createRaid: (raid:Raid) => Promise<any>
addSignup: (signup: Signup) => Promise<any>
removeSignup: (signup: Signup) => Promise<any>
}
signup: {
getRaids: () => Promise<Raid[]>
getSingups: (raid:Raid) => Promise<Signup[]>
sign: (user:User, raid:Raid, attending:boolean) => Promise<any>
}
}
+6 -2
View File
@@ -9,8 +9,12 @@
"projectType": "application", "projectType": "application",
"architect": { "architect": {
"build": { "build": {
"builder": "@angular-devkit/build-angular:browser", "builder": "@angular-builders/custom-webpack:browser",
"options": { "options": {
"customWebpackConfig": {
"path": "./custom-webpack.config.js",
"replaceDuplicatePlugins": true
},
"preserveSymlinks": true, "preserveSymlinks": true,
"rebaseRootRelativeCssUrls": true, "rebaseRootRelativeCssUrls": true,
"outputPath": "dist", "outputPath": "dist",
@@ -75,7 +79,7 @@
} }
}, },
"serve": { "serve": {
"builder": "@angular-devkit/build-angular:dev-server", "builder": "@angular-builders/custom-webpack:dev-server",
"options": { "options": {
"browserTarget": "ngx-admin-demo:build" "browserTarget": "ngx-admin-demo:build"
}, },
+4
View File
@@ -0,0 +1,4 @@
module.exports = {
externals: ['http'],
node: {global: true, fs: 'empty'}
}
+24 -4
View File
@@ -9,6 +9,22 @@
"resolved": "https://registry.npmjs.org/@agm/core/-/core-1.0.0-beta.5.tgz", "resolved": "https://registry.npmjs.org/@agm/core/-/core-1.0.0-beta.5.tgz",
"integrity": "sha512-LVENJqtBZEWpX+uJkGI0zgg+Xkm2KkktQm4ojZozArbeNvQkVL6pqVc04Mme6vvOzwJpD1cET5w4byC8Xaq1QQ==" "integrity": "sha512-LVENJqtBZEWpX+uJkGI0zgg+Xkm2KkktQm4ojZozArbeNvQkVL6pqVc04Mme6vvOzwJpD1cET5w4byC8Xaq1QQ=="
}, },
"@angular-builders/custom-webpack": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/@angular-builders/custom-webpack/-/custom-webpack-8.2.0.tgz",
"integrity": "sha512-6654RfyqhTGhCI0edC9YU/iMn1UJnzX01bxYJbDWFgvReCqXdlgy+Fe9tp1MeqKweX6BQ1d0gRroR/WjY1aX0A==",
"requires": {
"lodash": "^4.17.10",
"webpack-merge": "^4.2.1"
},
"dependencies": {
"lodash": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
}
}
},
"@angular-devkit/architect": { "@angular-devkit/architect": {
"version": "0.800.2", "version": "0.800.2",
"resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.800.2.tgz", "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.800.2.tgz",
@@ -11695,6 +11711,11 @@
} }
} }
}, },
"ngx-cookie-service": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/ngx-cookie-service/-/ngx-cookie-service-2.2.0.tgz",
"integrity": "sha512-2kaC1itlEMxiMAPJ320hOpcwU9vhvjbKQCZ1Go6bGhYjJtqG7eYvhNP7mM9IhFz1/afG2tBryJPySWmFUGhRpA=="
},
"ngx-echarts": { "ngx-echarts": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/ngx-echarts/-/ngx-echarts-4.0.1.tgz", "resolved": "https://registry.npmjs.org/ngx-echarts/-/ngx-echarts-4.0.1.tgz",
@@ -14314,9 +14335,9 @@
"integrity": "sha512-ZYzRkETgBrdEGzL5JSKimvjI2CX7ioyZCkX2BpcfyjqI+079W0wHAyj5W4rIZMcDSOHgLZtgz1IdDi/vU77KEQ==" "integrity": "sha512-ZYzRkETgBrdEGzL5JSKimvjI2CX7ioyZCkX2BpcfyjqI+079W0wHAyj5W4rIZMcDSOHgLZtgz1IdDi/vU77KEQ=="
}, },
"rpclibrary": { "rpclibrary": {
"version": "1.3.17", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.3.17.tgz", "resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.4.0.tgz",
"integrity": "sha512-ZdhZ1TSDO+bcz5kCJ7Ol+YAAyYpwg7YI/hETS4vv3RYerUEQVZSZjcm22J5a91RnQVN2SRiXzdoXbbFb/Renog==", "integrity": "sha512-JUU7+HymV2ZTI+NrIVOiIr5LGFoRsPq4k/ffdUonqIpd9fjOHBQ2/PFLVXx9z94+dKxdqN8/D9ZXPwU03ovZrg==",
"requires": { "requires": {
"bsock": "^0.1.9", "bsock": "^0.1.9",
"http": "0.0.0", "http": "0.0.0",
@@ -20446,7 +20467,6 @@
"version": "4.2.1", "version": "4.2.1",
"resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.1.tgz", "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.1.tgz",
"integrity": "sha512-4p8WQyS98bUJcCvFMbdGZyZmsKuWjWVnVHnAS3FFg0HDaRVrPbkivx2RYCre8UiemD67RsiFFLfn4JhLAin8Vw==", "integrity": "sha512-4p8WQyS98bUJcCvFMbdGZyZmsKuWjWVnVHnAS3FFg0HDaRVrPbkivx2RYCre8UiemD67RsiFFLfn4JhLAin8Vw==",
"dev": true,
"requires": { "requires": {
"lodash": "^4.17.5" "lodash": "^4.17.5"
} }
+3 -1
View File
@@ -30,6 +30,7 @@
}, },
"dependencies": { "dependencies": {
"@agm/core": "^1.0.0-beta.5", "@agm/core": "^1.0.0-beta.5",
"@angular-builders/custom-webpack": "^8.2.0",
"@angular/animations": "^8.0.0", "@angular/animations": "^8.0.0",
"@angular/cdk": "^8.0.0", "@angular/cdk": "^8.0.0",
"@angular/common": "^8.0.0", "@angular/common": "^8.0.0",
@@ -62,12 +63,13 @@
"ng2-ckeditor": "^1.2.2", "ng2-ckeditor": "^1.2.2",
"ng2-completer": "2.0.8", "ng2-completer": "2.0.8",
"ng2-smart-table": "1.3.5", "ng2-smart-table": "1.3.5",
"ngx-cookie-service": "^2.2.0",
"ngx-echarts": "^4.0.1", "ngx-echarts": "^4.0.1",
"node-sass": "^4.12.0", "node-sass": "^4.12.0",
"normalize.css": "6.0.0", "normalize.css": "6.0.0",
"pace-js": "1.0.2", "pace-js": "1.0.2",
"roboto-fontface": "0.8.0", "roboto-fontface": "0.8.0",
"rpclibrary": "^1.3.17", "rpclibrary": "^1.4.0",
"rxjs": "6.5.2", "rxjs": "6.5.2",
"rxjs-compat": "6.3.0", "rxjs-compat": "6.3.0",
"socicon": "3.0.5", "socicon": "3.0.5",
+13 -125
View File
@@ -1,146 +1,35 @@
import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core'; import { ModuleWithProviders, NgModule, Optional, SkipSelf, APP_INITIALIZER } from '@angular/core';
import { CommonModule } from '@angular/common'; 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 { throwIfAlreadyLoaded } from './module-import-guard';
import { CookieService } from 'ngx-cookie-service';
import { import {
AnalyticsService, AnalyticsService,
LayoutService, LayoutService,
PlayerService, PlayerService,
StateService, StateService,
} from './utils'; } from './utils';
import { UserData } from './data/users'; import { LoginApiService, initializeLoginSvc } from '../frontcraft/login-api';
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'; const DATA_SERVICES = [
import { ElectricityService } from './mock/electricity.service'; {provide: LoginApiService, useClass: LoginApiService},
import { SmartTableService } from './mock/smart-table.service'; {provide: CookieService, useClass: CookieService},
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', provide: APP_INITIALIZER,
target: '_blank', useFactory: initializeLoginSvc,
icon: 'github', deps: [LoginApiService, CookieService],
}, multi: true
{
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 = [ export const NB_CORE_PROVIDERS = [
...MockDataModule.forRoot().providers,
...DATA_SERVICES, ...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, AnalyticsService,
LayoutService, LayoutService,
PlayerService, PlayerService,
StateService, StateService,
CookieService,
]; ];
@NgModule({ @NgModule({
@@ -148,7 +37,6 @@ export const NB_CORE_PROVIDERS = [
CommonModule, CommonModule,
], ],
exports: [ exports: [
NbAuthModule,
], ],
declarations: [], declarations: [],
}) })
@@ -1 +0,0 @@
Application-wise data providers.
@@ -1,29 +0,0 @@
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));
}
}
@@ -1,103 +0,0 @@
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);
}
}
@@ -1,95 +0,0 @@
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);
}
}
@@ -1,65 +0,0 @@
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,
],
};
}
}
@@ -1,155 +0,0 @@
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];
}
}
@@ -1,45 +0,0 @@
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));
}
}
@@ -1,33 +0,0 @@
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',
];
}
}
@@ -1,43 +0,0 @@
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);
}
}
@@ -1,77 +0,0 @@
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];
}
}
@@ -1,30 +0,0 @@
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);
}
}
@@ -1,432 +0,0 @@
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;
}
}
@@ -1,12 +0,0 @@
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);
}
}
@@ -1,16 +0,0 @@
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);
}
}
@@ -1,31 +0,0 @@
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: 'Todays 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);
}
}
@@ -1,27 +0,0 @@
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);
}
}
@@ -1,47 +0,0 @@
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]);
}
}
@@ -1,16 +0,0 @@
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);
}
}
@@ -1,85 +0,0 @@
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]);
}
}
@@ -1,57 +0,0 @@
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]);
}
}
@@ -1,53 +0,0 @@
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);
}
}
@@ -1,57 +0,0 @@
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);
}
}
@@ -6,10 +6,7 @@ import { Component } from '@angular/core';
template: ` template: `
<span class="created-by">Created with by <b><a href="https://akveo.com" target="_blank">Akveo</a></b> 2019</span> <span class="created-by">Created with by <b><a href="https://akveo.com" target="_blank">Akveo</a></b> 2019</span>
<div class="socials"> <div class="socials">
<a href="#" target="_blank" class="ion ion-social-github"></a> <a href="http://www.versioncontrol.me/" 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> </div>
`, `,
}) })
@@ -3,11 +3,8 @@
<a (click)="toggleSidebar()" href="#" class="sidebar-toggle"> <a (click)="toggleSidebar()" href="#" class="sidebar-toggle">
<nb-icon icon="menu-2-outline"></nb-icon> <nb-icon icon="menu-2-outline"></nb-icon>
</a> </a>
<a class="logo" href="#" (click)="navigateHome()">ngx-<span>admin</span></a> <a class="logo" href="#" (click)="navigateHome()">Frontcraft</a>
</div> </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>
<div class="header-container"> <div class="header-container">
@@ -18,7 +15,7 @@
</nb-action> </nb-action>
<nb-action class="control-item" icon="email-outline"></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="control-item" icon="bell-outline"></nb-action>
<nb-action class="user-action" *nbIsGranted="['view', 'user']" > <nb-action class="user-action">
<nb-user [nbContextMenu]="userMenu" <nb-user [nbContextMenu]="userMenu"
[onlyPicture]="userPictureOnly" [onlyPicture]="userPictureOnly"
[name]="user?.name" [name]="user?.name"
@@ -36,14 +36,13 @@ export class HeaderComponent implements OnInit, OnDestroy {
}, },
]; ];
currentTheme = 'default'; currentTheme = 'dark';
userMenu = [ { title: 'Profile' }, { title: 'Log out' } ]; userMenu = [ { title: 'Profile' }, { title: 'Log out' } ];
constructor(private sidebarService: NbSidebarService, constructor(private sidebarService: NbSidebarService,
private menuService: NbMenuService, private menuService: NbMenuService,
private themeService: NbThemeService, private themeService: NbThemeService,
private userService: UserData,
private layoutService: LayoutService, private layoutService: LayoutService,
private breakpointService: NbMediaBreakpointsService) { private breakpointService: NbMediaBreakpointsService) {
} }
@@ -51,10 +50,12 @@ export class HeaderComponent implements OnInit, OnDestroy {
ngOnInit() { ngOnInit() {
this.currentTheme = this.themeService.currentTheme; this.currentTheme = this.themeService.currentTheme;
/*
this.userService.getUsers() this.userService.getUsers()
.pipe(takeUntil(this.destroy$)) .pipe(takeUntil(this.destroy$))
.subscribe((users: any) => this.user = users.nick); .subscribe((users: any) => this.user = users.lee);
*/
const { xl } = this.breakpointService.getBreakpointsMap(); const { xl } = this.breakpointService.getBreakpointsMap();
this.themeService.onMediaQueryChange() this.themeService.onMediaQueryChange()
.pipe( .pipe(
+1 -1
View File
@@ -82,7 +82,7 @@ export class ThemeModule {
providers: [ providers: [
...NbThemeModule.forRoot( ...NbThemeModule.forRoot(
{ {
name: 'default', name: 'dark',
}, },
[ DEFAULT_THEME, COSMIC_THEME, CORPORATE_THEME, DARK_THEME ], [ DEFAULT_THEME, COSMIC_THEME, CORPORATE_THEME, DARK_THEME ],
).providers, ).providers,
+2 -32
View File
@@ -1,7 +1,6 @@
import { ExtraOptions, RouterModule, Routes } from '@angular/router'; import { ExtraOptions, RouterModule, Routes } from '@angular/router';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { import {
NbAuthComponent,
NbLoginComponent, NbLoginComponent,
NbLogoutComponent, NbLogoutComponent,
NbRegisterComponent, NbRegisterComponent,
@@ -12,39 +11,10 @@ import {
const routes: Routes = [ const routes: Routes = [
{ {
path: 'pages', path: 'pages',
loadChildren: () => import('app/pages/pages.module') loadChildren: () => import('./pages/pages.module')
.then(m => m.PagesModule), .then(m => m.PagesModule),
}, },
{
path: 'auth',
component: NbAuthComponent,
children: [
{
path: '',
component: NbLoginComponent,
},
{
path: 'login',
component: NbLoginComponent,
},
{
path: 'register',
component: NbRegisterComponent,
},
{
path: 'logout',
component: NbLogoutComponent,
},
{
path: 'request-password',
component: NbRequestPasswordComponent,
},
{
path: 'reset-password',
component: NbResetPasswordComponent,
},
],
},
{ path: '', redirectTo: 'pages', pathMatch: 'full' }, { path: '', redirectTo: 'pages', pathMatch: 'full' },
{ path: '**', redirectTo: 'pages' }, { path: '**', redirectTo: 'pages' },
]; ];
+3 -1
View File
@@ -5,6 +5,7 @@
*/ */
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { AnalyticsService } from './@core/utils/analytics.service'; import { AnalyticsService } from './@core/utils/analytics.service';
import { LoginApiService } from './frontcraft/login-api';
@Component({ @Component({
selector: 'ngx-app', selector: 'ngx-app',
@@ -12,11 +13,12 @@ import { AnalyticsService } from './@core/utils/analytics.service';
}) })
export class AppComponent implements OnInit { export class AppComponent implements OnInit {
constructor(private analytics: AnalyticsService) { constructor(private loginSvc: LoginApiService, private analytics: AnalyticsService) {
} }
ngOnInit(): void { ngOnInit(): void {
this.analytics.trackPageViews(); this.analytics.trackPageViews();
window['s'] = this.loginSvc
} }
} }
@@ -0,0 +1,95 @@
import { Injectable } from "@angular/core";
import {RPCSocket} from 'rpclibrary/js/src/Frontend'
import { Token, Auth, User, _Rank, _Class, FrontcraftFeatureIfc, LoginManagerIfc, } from '../../../../backend/Types/Types'
import { CookieService } from 'ngx-cookie-service';
@Injectable()
export class LoginApiService{
private socket:RPCSocket & LoginManagerIfc;
private auth:Auth
private privSocket: RPCSocket & FrontcraftFeatureIfc
constructor(
private cookieSvc : CookieService
){}
getUnprivilegedSocket = () : RPCSocket & LoginManagerIfc => this.socket
private getPrivilegedSocket = async (auth:Auth) : Promise<RPCSocket & FrontcraftFeatureIfc> => {
if(this.privSocket) return this.privSocket
try{
const sock: RPCSocket & FrontcraftFeatureIfc = await new RPCSocket(auth.port, window.location.hostname).connect(auth.token.value)
//login success
this.auth = auth
this.privSocket = sock
this.setCookie(auth.token)
return sock
}catch(e){
//login failed
throw new Error('login failed')
}
}
getCurrentUser = () : User => this.auth
? this.auth.user
: {
name: 'Guest',
class: _Class[Math.floor(_Class.length * Math.random())],
pwhash: '',
rank: 'Guest'
}
authenticate = async (token : Token | string) : Promise<RPCSocket & FrontcraftFeatureIfc> => {
const auth = await this.socket.Authenticator.authenticate(token)
return await this.getPrivilegedSocket(auth)
}
login = async (username, password) => {
const buf = str2arraybuf(password)
const pwHash = await crypto.subtle.digest('SHA-256', buf);
const token = await this.socket.Authenticator.login(username, buf2hex(pwHash))
return await this.authenticate(token)
}
logout = () => {
this.cookieSvc.deleteAll()
this.auth = null
if(this.privSocket) this.privSocket.destroy()
this.privSocket = null
}
private setCookie = (token: string | Token) => {
token = 'string' === typeof token? token : token.value
this.cookieSvc.set('token', token)
}
private getCookie = () : string | Token | undefined => {
return this.cookieSvc.get('token')
}
initialize = async () : Promise<RPCSocket> => {
const sock : RPCSocket & LoginManagerIfc = await new RPCSocket(20000, window.location.hostname).connect()
this.socket = sock
const cookie = this.getCookie()
if(cookie) {
return await this.authenticate(cookie)
}
return sock
}
}
function str2arraybuf(str:string): ArrayBuffer {
return new Buffer(str)
}
function buf2hex(buffer) { // buffer is an ArrayBuffer
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}
export function initializeLoginSvc(svc: LoginApiService): () => Promise<RPCSocket> {
return svc.initialize
}
@@ -0,0 +1,18 @@
import { Injectable } from "@angular/core";
import {RPCSocket} from 'rpclibrary'
var crypto = require('crypto');
import { User, } from '../../../../backend/Types/Types'
@Injectable()
export class UserService{
private loginSocket = new RPCSocket(20000, window.location.hostname).connect()
constructor(){}
login = async (username:string, password:string) => {
const pwHash = crypto.createHash('sha256').update(password).digest('hex');
}
}
-243
View File
@@ -1,247 +1,4 @@
import { NbMenuItem } from '@nebular/theme'; import { NbMenuItem } from '@nebular/theme';
export const MENU_ITEMS: NbMenuItem[] = [ export const MENU_ITEMS: NbMenuItem[] = [
{
title: 'E-commerce',
icon: 'shopping-cart-outline',
link: '/pages/dashboard',
home: true,
},
{
title: 'IoT Dashboard',
icon: 'home-outline',
link: '/pages/iot-dashboard',
},
{
title: 'FEATURES',
group: true,
},
{
title: 'Layout',
icon: 'layout-outline',
children: [
{
title: 'Stepper',
link: '/pages/layout/stepper',
},
{
title: 'List',
link: '/pages/layout/list',
},
{
title: 'Infinite List',
link: '/pages/layout/infinite-list',
},
{
title: 'Accordion',
link: '/pages/layout/accordion',
},
{
title: 'Tabs',
pathMatch: 'prefix',
link: '/pages/layout/tabs',
},
],
},
{
title: 'Forms',
icon: 'edit-2-outline',
children: [
{
title: 'Form Inputs',
link: '/pages/forms/inputs',
},
{
title: 'Form Layouts',
link: '/pages/forms/layouts',
},
{
title: 'Buttons',
link: '/pages/forms/buttons',
},
{
title: 'Datepicker',
link: '/pages/forms/datepicker',
},
],
},
{
title: 'UI Features',
icon: 'keypad-outline',
link: '/pages/ui-features',
children: [
{
title: 'Grid',
link: '/pages/ui-features/grid',
},
{
title: 'Icons',
link: '/pages/ui-features/icons',
},
{
title: 'Typography',
link: '/pages/ui-features/typography',
},
{
title: 'Animated Searches',
link: '/pages/ui-features/search-fields',
},
],
},
{
title: 'Modal & Overlays',
icon: 'browser-outline',
children: [
{
title: 'Dialog',
link: '/pages/modal-overlays/dialog',
},
{
title: 'Window',
link: '/pages/modal-overlays/window',
},
{
title: 'Popover',
link: '/pages/modal-overlays/popover',
},
{
title: 'Toastr',
link: '/pages/modal-overlays/toastr',
},
{
title: 'Tooltip',
link: '/pages/modal-overlays/tooltip',
},
],
},
{
title: 'Extra Components',
icon: 'message-circle-outline',
children: [
{
title: 'Calendar',
link: '/pages/extra-components/calendar',
},
{
title: 'Progress Bar',
link: '/pages/extra-components/progress-bar',
},
{
title: 'Spinner',
link: '/pages/extra-components/spinner',
},
{
title: 'Alert',
link: '/pages/extra-components/alert',
},
{
title: 'Calendar Kit',
link: '/pages/extra-components/calendar-kit',
},
{
title: 'Chat',
link: '/pages/extra-components/chat',
},
],
},
{
title: 'Maps',
icon: 'map-outline',
children: [
{
title: 'Google Maps',
link: '/pages/maps/gmaps',
},
{
title: 'Leaflet Maps',
link: '/pages/maps/leaflet',
},
{
title: 'Bubble Maps',
link: '/pages/maps/bubble',
},
{
title: 'Search Maps',
link: '/pages/maps/searchmap',
},
],
},
{
title: 'Charts',
icon: 'pie-chart-outline',
children: [
{
title: 'Echarts',
link: '/pages/charts/echarts',
},
{
title: 'Charts.js',
link: '/pages/charts/chartjs',
},
{
title: 'D3',
link: '/pages/charts/d3',
},
],
},
{
title: 'Editors',
icon: 'text-outline',
children: [
{
title: 'TinyMCE',
link: '/pages/editors/tinymce',
},
{
title: 'CKEditor',
link: '/pages/editors/ckeditor',
},
],
},
{
title: 'Tables & Data',
icon: 'grid-outline',
children: [
{
title: 'Smart Table',
link: '/pages/tables/smart-table',
},
{
title: 'Tree Grid',
link: '/pages/tables/tree-grid',
},
],
},
{
title: 'Miscellaneous',
icon: 'shuffle-2-outline',
children: [
{
title: '404',
link: '/pages/miscellaneous/404',
},
],
},
{
title: 'Auth',
icon: 'lock-outline',
children: [
{
title: 'Login',
link: '/auth/login',
},
{
title: 'Register',
link: '/auth/register',
},
{
title: 'Request Password',
link: '/auth/request-password',
},
{
title: 'Reset Password',
link: '/auth/reset-password',
},
],
},
]; ];
@@ -10,64 +10,7 @@ const routes: Routes = [{
path: '', path: '',
component: PagesComponent, component: PagesComponent,
children: [ children: [
{
path: 'dashboard',
component: ECommerceComponent,
},
{
path: 'iot-dashboard',
component: DashboardComponent,
},
{
path: 'layout',
loadChildren: () => import('./layout/layout.module')
.then(m => m.LayoutModule),
},
{
path: 'forms',
loadChildren: () => import('./forms/forms.module')
.then(m => m.FormsModule),
},
{
path: 'ui-features',
loadChildren: () => import('./ui-features/ui-features.module')
.then(m => m.UiFeaturesModule),
},
{
path: 'modal-overlays',
loadChildren: () => import('./modal-overlays/modal-overlays.module')
.then(m => m.ModalOverlaysModule),
},
{
path: 'extra-components',
loadChildren: () => import('./extra-components/extra-components.module')
.then(m => m.ExtraComponentsModule),
},
{
path: 'maps',
loadChildren: () => import('./maps/maps.module')
.then(m => m.MapsModule),
},
{
path: 'charts',
loadChildren: () => import('./charts/charts.module')
.then(m => m.ChartsModule),
},
{
path: 'editors',
loadChildren: () => import('./editors/editors.module')
.then(m => m.EditorsModule),
},
{
path: 'tables',
loadChildren: () => import('./tables/tables.module')
.then(m => m.TablesModule),
},
{
path: 'miscellaneous',
loadChildren: () => import('./miscellaneous/miscellaneous.module')
.then(m => m.MiscellaneousModule),
},
{ {
path: '', path: '',
redirectTo: 'dashboard', redirectTo: 'dashboard',
+2 -1
View File
@@ -15,7 +15,8 @@
"exclude": [ "exclude": [
"test.ts", "test.ts",
"**/*.spec.ts", "**/*.spec.ts",
"../node_modules/@nebular/**/*.spec.ts" "../node_modules/@nebular/**/*.spec.ts",
"../node_modules/rpclibrary/js/**/*"
], ],
"include": [ "include": [
"../src/*.ts", "../src/*.ts",