More useful prod & dev modes in dashboard

This commit is contained in:
peter
2019-08-14 00:27:43 +02:00
parent 1c3249c0f8
commit b706e36b49
35 changed files with 471 additions and 273 deletions
+2 -1
View File
@@ -12,4 +12,5 @@ conf
*.js *.js
*.ts *.ts
!src/**/* !src/**/*
node_modules
+21
View File
@@ -12,6 +12,14 @@
"tslib": "^1.9.0" "tslib": "^1.9.0"
} }
}, },
"@angular/compiler": {
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-8.2.1.tgz",
"integrity": "sha512-kOGNh0K4k7vEIMLlEyG1A+UxPOIMp2b3IT0vBq5isRjXxGzEnahyBYtXwGI7G6ox+OoNKy1OZOPaK473fcO8zg==",
"requires": {
"tslib": "^1.9.0"
}
},
"@angular/core": { "@angular/core": {
"version": "8.2.1", "version": "8.2.1",
"resolved": "https://registry.npmjs.org/@angular/core/-/core-8.2.1.tgz", "resolved": "https://registry.npmjs.org/@angular/core/-/core-8.2.1.tgz",
@@ -36,6 +44,14 @@
"tslib": "^1.9.0" "tslib": "^1.9.0"
} }
}, },
"@angular/platform-browser-dynamic": {
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-8.2.1.tgz",
"integrity": "sha512-9tdpvEXFCgbMUeyVvIklyDPyg39cRN6MOrQihObAoBKOkcko9MKJIxDPCv8o/5FBrlBcu0VhREPK56aVD0g6UQ==",
"requires": {
"tslib": "^1.9.0"
}
},
"@angular/router": { "@angular/router": {
"version": "8.2.1", "version": "8.2.1",
"resolved": "https://registry.npmjs.org/@angular/router/-/router-8.2.1.tgz", "resolved": "https://registry.npmjs.org/@angular/router/-/router-8.2.1.tgz",
@@ -264,6 +280,11 @@
"tslib": "^1.9.0" "tslib": "^1.9.0"
} }
}, },
"@clr/ui": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@clr/ui/-/ui-2.1.1.tgz",
"integrity": "sha512-8R46KRxA6kPr6zEPJlsQIbo4m6gqg0GGxoxTNxCtkloOlMs5UetDYnx8/gGm3+e0vqNdUL7cbKlGDOZyy9uwmQ=="
},
"@cnakazawa/watch": { "@cnakazawa/watch": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.3.tgz", "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.3.tgz",
+3
View File
@@ -21,11 +21,14 @@
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@angular/common": "^8.2.1", "@angular/common": "^8.2.1",
"@angular/compiler": "^8.2.1",
"@angular/core": "^8.2.1", "@angular/core": "^8.2.1",
"@angular/forms": "^8.2.1", "@angular/forms": "^8.2.1",
"@angular/platform-browser": "^8.2.1", "@angular/platform-browser": "^8.2.1",
"@angular/platform-browser-dynamic": "^8.2.1",
"@angular/router": "^8.2.1", "@angular/router": "^8.2.1",
"@clr/angular": "^2.1.1", "@clr/angular": "^2.1.1",
"@clr/ui": "^2.1.1",
"@uirouter/angularjs": "^1.0.5", "@uirouter/angularjs": "^1.0.5",
"adm-zip": "^0.4.13", "adm-zip": "^0.4.13",
"angular": "^1.7.8", "angular": "^1.7.8",
+1 -1
View File
@@ -25,7 +25,7 @@
"@clr/ui": "^2.1.1", "@clr/ui": "^2.1.1",
"@webcomponents/custom-elements": "^1.0.0", "@webcomponents/custom-elements": "^1.0.0",
"frontblock": "latest", "frontblock": "latest",
"frontblock-generic": "latest", "frontblock-generic": "^0.22.0",
"key-file-storage": "^2.2.4", "key-file-storage": "^2.2.4",
"rxjs": "~6.5.2", "rxjs": "~6.5.2",
"systemjs": "^0.21.3", "systemjs": "^0.21.3",
@@ -1,11 +1,41 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { fbind } from 'q';
import { FrontblockApiConf } from 'frontblock'; import { FrontblockApiConf } from 'frontblock';
import { SubscriptionResponse, parseResponse, SuccessResponse } from 'frontblock-generic/Types.js'; import { SubscriptionResponse, parseResponse, SuccessResponse } from 'frontblock-generic/Types.js';
import { environment } from "../../environments/environment"
let fb
if(environment.production){
fb = window["fb"]
}else{
fb = {
ApiClient : {
setConfig: async () => {
await new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise A win!');
}, 500)
})
},
getConsumptions: async () => {
return await new Promise((resolve, reject) => {
setTimeout(() => {
resolve([new SubscriptionResponse("654", "321"), new SubscriptionResponse("456", "123")]);
}, 500)
})
},
getSubscriptions: async () => {
return await new Promise((resolve, reject) => {
setTimeout(() => {
resolve([new SubscriptionResponse("321"), new SubscriptionResponse("123")]);
}, 500)
})
},
unsubscribe: (uid) => new SuccessResponse(),
quit: (uid) => new SuccessResponse()
declare const fb }
}
}
@Component({ @Component({
selector: 'consumptions', selector: 'consumptions',
template: ` template: `
@@ -1,6 +1,7 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { SidebarEntry } from 'frontblock-generic/Plugin'; import { SidebarEntry } from 'frontblock-generic/Plugin';
declare const fb import { environment } from "../../environments/environment"
@Component({ @Component({
selector: 'apiclient', //!!!! selector: 'apiclient', //!!!!
template: ` template: `
@@ -8,9 +9,7 @@ declare const fb
<div class="clr-col-lg-auto"> <div class="clr-col-lg-auto">
<settings></settings> <settings></settings>
</div> </div>
</div> <div class="clr-col-12 clr-col-lg-12 clr-col-xl-12 clr-col-sm-12">
<div class="clr-row">
<div class="clr-col">
<consumptions></consumptions> <consumptions></consumptions>
</div> </div>
</div> </div>
@@ -1,10 +1,23 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { fbind } from 'q'; import { fbind } from 'q';
import { FrontblockApiConf } from 'frontblock'; import { FrontblockApiConf } from 'frontblock';
import { environment } from "../../environments/environment"
let fb
declare const fb if(environment.production){
fb = window["fb"]
}else{
fb = {
ApiClient : {
setConfig: async () => {
await new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise A win!');
}, 500)
})}
}
}
}
@Component({ @Component({
selector: 'settings', selector: 'settings',
template: ` template: `
@@ -2,9 +2,41 @@ import { Component, OnInit } from '@angular/core';
import { fbind } from 'q'; import { fbind } from 'q';
import { FrontblockApiConf } from 'frontblock'; import { FrontblockApiConf } from 'frontblock';
import { SubscriptionResponse, SuccessResponse, ErrorResponse, parseResponse } from 'frontblock-generic/Types.js'; import { SubscriptionResponse, SuccessResponse, ErrorResponse, parseResponse } from 'frontblock-generic/Types.js';
import { environment } from "../../environments/environment"
let fb
if(environment.production){
fb = window["fb"]
}else{
fb = {
ApiClient : {
setConfig: async () => {
await new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise A win!');
}, 500)
})
},
getConsumptions: async () => {
return await new Promise((resolve, reject) => {
setTimeout(() => {
resolve([new SubscriptionResponse("654", "321"), new SubscriptionResponse("456", "123")]);
}, 500)
})
},
getSubscriptions: async () => {
return await new Promise((resolve, reject) => {
setTimeout(() => {
resolve([new SubscriptionResponse("321"), new SubscriptionResponse("123")]);
}, 500)
})
},
unsubscribe: (uid) => new SuccessResponse(),
quit: (uid) => new SuccessResponse()
declare const fb }
}
}
@Component({ @Component({
selector: 'subscriptions', selector: 'subscriptions',
@@ -0,0 +1,41 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { ApiclientDevComponent as ApiclientComponent } from './apiclient-dev.component';
import { ApiclientFormComponent } from './apiclient-settings-form.component';
import { ApiclientConsumptionComponent } from './apiclient-consumptions.component';
import { ApiclientSubscriptionComponent } from './apiclient-subscriptions.component';
import { FrontendPlugin, SidebarEntry } from 'frontblock-generic/Plugin';
import { ClarityModule } from '@clr/angular';
import { FormsModule } from '@angular/forms';
@NgModule({
imports: [
FormsModule,
ClarityModule,
CommonModule,
RouterModule.forChild([
{path: "apiclient", component: ApiclientComponent},
]),
],
exports: [RouterModule],
declarations: [
ApiclientComponent,
ApiclientFormComponent,
ApiclientConsumptionComponent,
ApiclientSubscriptionComponent
]
})
export class PluginModule implements FrontendPlugin{
getSidebarEntry(): SidebarEntry {
return {
icon: "key",
route: "apiclient",
text: "Api client",
}
}
}
@@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core';
import { SidebarEntry } from 'frontblock-generic/Plugin'; import { SidebarEntry } from 'frontblock-generic/Plugin';
declare const fb declare const fb
@Component({ @Component({
selector: 'pluginmanager', //!!!! selector: 'debug', //!!!!
template: ` template: `
<div class="clr-row"> <div class="clr-row">
<div class="clr-col"> <div class="clr-col">
@@ -30,7 +30,7 @@ declare const fb
</div> </div>
` `
}) })
export class PluginmanagerDevComponent implements OnInit { export class PluginmanagerDEBUG implements OnInit {
constructor() { } constructor() { }
@@ -0,0 +1,45 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { PluginmanagerDEBUG } from './debug.component';
import { PluginsComponent } from './plugins.component';
import { FrontendPlugin, SidebarEntries } from 'frontblock-generic/Plugin';
import { ClarityModule } from '@clr/angular';
import { FormsModule } from '@angular/forms';
@NgModule({
imports: [
FormsModule,
ClarityModule,
CommonModule,
RouterModule.forChild([
{path: "debug", component: PluginmanagerDEBUG},
{path: "plugins", component: PluginsComponent}
]),
],
exports: [RouterModule],
declarations: [
PluginmanagerDEBUG,
PluginsComponent
]
})
export class PluginModule implements FrontendPlugin{
getSidebarEntry(): SidebarEntries {
return {
icon: "plugin",
text: "Plugin manager",
parentRoute: "pluginmanager",
links: [{
route: "debug",
text: "DEBUG"
},{
route: "plugins",
text: "Plugins"
}]
}
}
}
@@ -0,0 +1,116 @@
import { Component, OnInit } from '@angular/core';
import { SidebarEntry } from 'frontblock-generic/Plugin';
declare const fb
@Component({
selector: 'plugins', //!!!!
template: `
<div class="modal" *ngIf="!updatepending">
<div class="modal-dialog fadeDown in" role="dialog" aria-hidden="true">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">Confirm installation</h3>
</div>
<div class="modal-body">
<p>{{updateCandidate}} But not much to say...</p>
</div>
<div class="modal-footer">
<button class="btn btn-icon btn-success" (click)="download(updateCandidate)"><clr-icon shape="check"></clr-icon></button>
<button class="btn btn-icon btn-danger" (click)="cancelModal()"><clr-icon shape="times"></clr-icon></button>
</div>
</div>
</div>
</div>
<div class="modal-backdrop fade in" aria-hidden="true" *ngIf="!updatepending"></div>
<div class="clr-row">
<div class="clr-col">
<div class="card">
<div class="card-header">
Plugins
</div>
<div class="card-block">
<div class="card-text">
<clr-accordion>
<clr-accordion-panel *ngFor="let entry of plugins">
<clr-accordion-title>{{entry.name}}</clr-accordion-title>
<clr-accordion-content *clrIfExpanded>
<div class="btn-group btn-primary">
<button *ngIf="entry.status === 'Stopped'" class="btn btn-icon btn-success-outline" (click)="start(entry.name)"><clr-icon shape="play"></clr-icon></button>
<button *ngIf="entry.status === 'Running'" class="btn btn-icon btn-warning-outline" (click)="stop(entry.name)"><clr-icon shape="stop"></clr-icon></button>
<button *ngIf="entry.status === 'Stopped'" class="btn btn-icon btn-danger-outline" (click)="delete(entry.name)"><clr-icon shape="trash"></clr-icon></button>
<button *ngIf="entry.status === 'Available'" class="btn btn-icon btn-info-outline" (click)="showConfirmation(entry.name)"><clr-icon shape="download"></clr-icon></button>
<button *ngIf="entry.available !== entry.installed && entry.status === 'Stopped'" class="btn btn-icon btn-outline " (click)="showConfirmation(entry.name)">
<clr-icon shape="sync"></clr-icon>
</button>
</div>
</clr-accordion-content>
</clr-accordion-panel>
</clr-accordion>
</div>
</div>
<div class="card-footer">
<!-- <button class="btn btn-success" onclick="setup()">HELLO</button> -->
</div>
</div>
</div>
</div>
`
})
export class PluginsComponent implements OnInit {
plugins = [{
name: "test",
available: "0.0.1",
installed: "0.0.1",
status: "Running"
},{
name: "test II: Return of test",
available: "0.0.1",
installed: "0.0.1",
status: "Available"
},{
name: "test 3",
available: "0.0.2",
installed: "0.0.1",
status: "Stopped"
},]
updatepending = true
updateCandidate = ""
constructor() { }
start(name){
this.plugins.find((el) => el.name === name).status = "Running"
}
stop(name){
this.plugins.find((el) => el.name === name).status = "Stopped"
}
delete(name){
this.plugins.find((el) => el.name === name).status = "Available"
}
showConfirmation(name){
this.updateCandidate = name
this.updatepending = !this.updatepending
}
download(name){
let plugin = this.plugins.find((el) => el.name === name)
plugin.status = "Stopped"
plugin.installed = plugin.available
this.updatepending = !this.updatepending
}
cancelModal(){
this.updateCandidate = ""
this.updatepending = !this.updatepending
}
ngOnInit() { }
}
@@ -2,17 +2,9 @@ import { NgModule } from '@angular/core';
import { Routes, RouterModule, Route } from '@angular/router'; import { Routes, RouterModule, Route } from '@angular/router';
import { HomeComponent } from './home/home.component'; import { HomeComponent } from './home/home.component';
import { ErrorDisplayComponent } from './error-display/error-display.component'; import { ErrorDisplayComponent } from './error-display/error-display.component';
import { PluginmanagerDevComponent } from './pluginmanager-dev/pluginmanager-dev.component'; import { environment } from 'src/environments/environment';
import { ApiclientDevComponent } from './apiclient-dev/apiclient-dev.component';
const routes: Routes = [{ const routes: Routes = [{
path: "dev/pluginmanager",
component: PluginmanagerDevComponent
},{
path: "dev/apiclient",
component: ApiclientDevComponent
},{
path: "", path: "",
component: HomeComponent component: HomeComponent
},{ },{
@@ -1,4 +1,8 @@
<div class="main-container"> <div class="main-container">
<header-bar></header-bar> <header-bar></header-bar>
<app-dynamic-loader></app-dynamic-loader> <subnav></subnav>
</div> <div class="content-container">
<sidebar></sidebar>
<dynamic-loader></dynamic-loader>
</div>
</div>
@@ -1,10 +1,30 @@
import { Component } from '@angular/core'; import { Component, ChangeDetectorRef, NgZone, ViewChild, OnInit, AfterContentInit } from '@angular/core';
import { SidebarComponent } from './sidebar/sidebar.component';
import { SidebarEntryService } from './sidebar-entry-service.service';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
templateUrl: './app.component.html', templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'] styleUrls: ['./app.component.scss']
}) })
export class AppComponent { export class AppComponent implements AfterContentInit {
title = 'dashboard'; title = 'dashboard';
@ViewChild(SidebarComponent, {static: false})
sidebar: SidebarComponent
constructor(private zone:NgZone, private sidebarService: SidebarEntryService){
window["refresh"] = () => zone.run(()=>{ /*this triggers an angular reload*/})
}
ngAfterContentInit(){
const _this = this;
(function awaitSidebar(){
if(_this.sidebar != null){
_this.sidebarService.setSidebar(_this.sidebar)
return
}
setTimeout(awaitSidebar,25)
})()
}
} }
+24 -30
View File
@@ -1,57 +1,51 @@
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core';
import { NgModule, ANALYZE_FOR_ENTRY_COMPONENTS, ModuleWithProviders } from '@angular/core'; import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule, getRoutes } from './app-routing.module';
import { ClarityModule } from '@clr/angular'; import { ClarityModule } from '@clr/angular';
import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { COMPILER_OPTIONS, CompilerFactory, Compiler } from '@angular/core'; import { COMPILER_OPTIONS, CompilerFactory, Compiler } from '@angular/core';
import { JitCompilerFactory } from '@angular/platform-browser-dynamic'; import { JitCompilerFactory } from '@angular/platform-browser-dynamic';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { SidebarComponent } from './sidebar/sidebar.component'; import { SidebarComponent } from './sidebar/sidebar.component';
import { MainComponent } from './main/main.component'; import { MainComponent } from './content-area/main.component';
import { DynamicLoaderComponent } from './dynamic-loader/dynamic-loader.component'; import { DynamicLoaderComponent } from './dynamic-loader/dynamic-loader.component';
import { HomeComponent } from './home/home.component'; import { HomeComponent } from './home/home.component';
import { ErrorDisplayComponent } from './error-display/error-display.component'; import { ErrorDisplayComponent } from './error-display/error-display.component';
import { PluginmanagerDevComponent } from './pluginmanager-dev/pluginmanager-dev.component';
import { HeaderBarComponent } from './header-bar/header-bar.component'; import { HeaderBarComponent } from './header-bar/header-bar.component';
import { ApiclientDevComponent } from './apiclient-dev/apiclient-dev.component'; import { SubnavComponent } from './subnav/subnav.component';
import { ApiclientFormComponent } from './apiclient-dev/apiclient-settings-form.component';
import { ApiclientConsumptionComponent } from './apiclient-dev/apiclient-consumptions.component'; import { environment } from 'src/environments/environment';
import { ApiclientSubscriptionComponent } from './apiclient-dev/apiclient-subscriptions.component';
export function createCompiler(fn: CompilerFactory): Compiler { export function createCompiler(fn: CompilerFactory): Compiler {
return fn.createCompiler(); return fn.createCompiler();
} }
const entryComps = [] const declarations = [
AppComponent,
SidebarComponent,
MainComponent,
DynamicLoaderComponent,
HomeComponent,
HeaderBarComponent,
ErrorDisplayComponent,
SubnavComponent,
]
@NgModule({ @NgModule({
declarations: [ declarations: declarations,
AppComponent,
SidebarComponent,
MainComponent,
DynamicLoaderComponent,
HomeComponent,
ErrorDisplayComponent,
PluginmanagerDevComponent,
HeaderBarComponent,
ApiclientDevComponent,
ApiclientFormComponent,
ApiclientConsumptionComponent,
ApiclientSubscriptionComponent
],
imports: [ imports: [
FormsModule, FormsModule,
BrowserModule, BrowserModule,
BrowserAnimationsModule, BrowserAnimationsModule,
ClarityModule, ClarityModule,
HttpClientModule, AppRoutingModule,
AppRoutingModule
], ],
entryComponents: entryComps, entryComponents: [],
providers: [ providers: [
{ {
provide: COMPILER_OPTIONS, provide: COMPILER_OPTIONS,
@@ -1,7 +1,7 @@
import { Component, OnInit, ViewContainerRef, ViewChild } from '@angular/core'; import { Component, OnInit, ViewContainerRef, ViewChild } from '@angular/core';
@Component({ @Component({
selector: 'app-main', selector: 'content-area',
templateUrl: './main.component.html', templateUrl: './main.component.html',
styleUrls: ['./main.component.scss'] styleUrls: ['./main.component.scss']
}) })
@@ -1,26 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { SidebarEntry } from 'frontblock-generic/Plugin';
declare const fb
@Component({
selector: 'apiclient', //!!!!
template: `
<div class="clr-row">
<div class="clr-col">
<settings></settings>
</div>
</div>
`
})
export class ApiclientDevComponent implements OnInit {
constructor() { }
ngOnInit() { }
}
export const sidebarEntry:SidebarEntry = {
icon: "wrench",
route: "dev/apiclient",
text: "DEV ApiClient",
}
@@ -1,135 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { fbind } from 'q';
import { FrontblockApiConf } from 'frontblock';
declare const fb
@Component({
selector: 'settings',
template: `
<div class="card">
<div class="card-header">
Configuration
</div>
<div class="card-block">
<div class="card-title">
Settings
</div>
<div class="card-text">
<form clrForm clrLayout="vertical">
<clr-input-container>
<label>testnet</label>
<clr-control-error>We need your first name for legal compliance</clr-control-error>
</clr-input-container>
<input type="checkbox" [(ngModel)]="testnet" (change)="updateTestnet($event)" name="testnetToggle" clrToggle />
<clr-input-container *ngIf="!testnet">
<label>API key</label>
<input clrInput type="text" name="apiKey" required />
<clr-control-error>We need your first name for legal compliance</clr-control-error>
</clr-input-container>
<clr-input-container *ngIf="advanced">
<label>API address</label>
<input type="text" [(ngModel)]="data.apiHost" (change)="updatePort($event)" clrInput name="apiHost" required />
<clr-control-error>This field is required!</clr-control-error>
</clr-input-container>
<clr-checkbox-wrapper *ngIf="advanced" >
<input [(ngModel)]="data.tls" type="checkbox" clrCheckbox value="tls" name="options" />
<label>Use TLS</label>
</clr-checkbox-wrapper>
<clr-input-container *ngIf="advanced">
<label>Port</label>
<input [(ngModel)]="data.apiPort" clrInput type="number" name="lastName" required />
<clr-control-error>Valid range 1024 - 65536
</clr-control-error>
</clr-input-container>
</form>
</div>
</div>
<div class="card-footer">
<button *ngIf="!saving" class="btn btn-success" (click)="save()">
<span>Save</span>
</button>
<button *ngIf="saving" class="btn btn-disabled" (click)="save()" disabled>
<span class="spinner spinner-inline"></span>
</button>
<button *ngIf="!advanced" class="btn btn-sm btn-link" (click)="setAdvanced()">Advanced</button>
</div>
</div>
`
})
export class ApiclientFormComponent implements OnInit {
testnet:boolean = true
saving:boolean = false
advanced:boolean = false
data:FrontblockApiConf = {
apiHost: "api.testnet.frontblock.me",
apiPort: 10001,
tls: false,
apiKey: ""
}
constructor() { }
ngOnInit() { }
setAdvanced(){ this.advanced = true }
checkData():boolean{
return (
typeof this.data.apiPort === "number" &&
typeof this.data.apiHost === "string" &&
typeof this.data.tls === "boolean" &&
typeof this.data.apiKey === "string"
)
}
updateTestnet(){
if(this.testnet){
this.data.apiHost = "api.testnet.frontblock.me"
this.data.apiPort = 10001
}else{
this.data.apiHost = "api.frontblock.me"
this.data.apiPort = 10000
}
}
updatePort(obj){
switch (this.data.apiHost) {
case "api.testnet.frontblock.me":
this.data.apiPort = 10001
break;
case "api.frontblock.me":
this.data.apiPort = 10000
break;
default:
console.warn("A non-standard api host was chosen: "+this.data.apiPort)
break;
}
console.log(this.data)
}
async save(){
this.saving = true;
if(typeof this.data.apiPort === "string")
this.data.apiPort = parseInt(this.data.apiPort)
if(this.checkData()){
const conf = await fb.ApiClient.setConfig(this.data)
console.log(conf)
}else{
//show error in gui
console.error("bad data :(")
}
this.saving = false
}
}
@@ -1,4 +1,3 @@
<div class="content-container"> <div class="content-container">
<app-sidebar></app-sidebar> <content-area></content-area>
<app-main></app-main>
</div> </div>
@@ -5,7 +5,6 @@
*/ */
import { System } from 'systemjs'; import { System } from 'systemjs';
declare const SystemJS: System; declare const SystemJS: System;
declare const fb
import * as angularRouter from '@angular/router'; import * as angularRouter from '@angular/router';
import * as angularCore from '@angular/core'; import * as angularCore from '@angular/core';
@@ -13,47 +12,76 @@ import * as angularCommon from '@angular/common';
import * as angularCommonHttp from '@angular/common/http'; import * as angularCommonHttp from '@angular/common/http';
import * as angularForms from '@angular/forms'; import * as angularForms from '@angular/forms';
import * as angularAnimations from '@angular/animations'; import * as angularAnimations from '@angular/animations';
//import * as angularAnimationsBrowser from '@angular/animations/browser'
import * as angularPlatformBrowser from '@angular/platform-browser'; import * as angularPlatformBrowser from '@angular/platform-browser';
import * as angularPlatformBrowserDynamic from '@angular/platform-browser-dynamic'; import * as angularPlatformBrowserDynamic from '@angular/platform-browser-dynamic';
import * as clarityModule from '@clr/angular';
import * as frontblockGenericTypes from 'frontblock-generic/Types.js'
//import * as browserAnimationsModule from "@angular/platform-browser/animations";
SystemJS.set('@clr/angular', SystemJS.newModule(clarityModule));
SystemJS.set('@angular/router', SystemJS.newModule(angularRouter)); SystemJS.set('@angular/router', SystemJS.newModule(angularRouter));
SystemJS.set('@angular/core', SystemJS.newModule(angularCore)); SystemJS.set('@angular/core', SystemJS.newModule(angularCore));
SystemJS.set('@angular/common', SystemJS.newModule(angularCommon)); SystemJS.set('@angular/common', SystemJS.newModule(angularCommon));
SystemJS.set('@angular/common/http', SystemJS.newModule(angularCommonHttp)); SystemJS.set('@angular/common/http', SystemJS.newModule(angularCommonHttp));
SystemJS.set('@angular/forms', SystemJS.newModule(angularForms)); SystemJS.set('@angular/forms', SystemJS.newModule(angularForms));
SystemJS.set('@angular/animations', SystemJS.newModule(angularAnimations)); SystemJS.set('@angular/animations', SystemJS.newModule(angularAnimations));
//SystemJS.set('@angular/animations/browser', SystemJS.newModule(angularAnimationsBrowser));
SystemJS.set('@angular/platform-browser', SystemJS.newModule(angularPlatformBrowser)); SystemJS.set('@angular/platform-browser', SystemJS.newModule(angularPlatformBrowser));
//SystemJS.set('@angular/platform-browser/animations', SystemJS.newModule(browserAnimationsModule));
SystemJS.set('@angular/platform-browser-dynamic', SystemJS.newModule(angularPlatformBrowserDynamic)); SystemJS.set('@angular/platform-browser-dynamic', SystemJS.newModule(angularPlatformBrowserDynamic));
SystemJS.set('frontblock-generic/Types', SystemJS.newModule(frontblockGenericTypes));
SystemJS.config({ meta: { '*': { authorization: true } } }); SystemJS.config({ meta: { '*': { authorization: true } } });
/** --------- */ /** --------- */
import { AfterViewInit, Component, ViewContainerRef, ViewChild } from '@angular/core'; import { AfterViewInit, Component, Input, ViewChild } from '@angular/core';
import { SidebarComponent } from '../sidebar/sidebar.component'; import { SidebarComponent } from '../sidebar/sidebar.component';
import { MainComponent } from '../main/main.component';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { FrontendPlugin, SidebarEntries, SidebarEntry } from "frontblock-generic/Plugin" import { FrontendPlugin, SidebarEntries, SidebarEntry } from "frontblock-generic/Plugin"
import { SidebarEntryService } from '../sidebar-entry-service.service';
import { environment } from "../../environments/environment"
let fb
if(environment.production){
fb = window["fb"]
}else{
fb = {
PluginManager : {
getLoadedPluginNames: () => ["ApiClient", "PluginManager"]
}
}
}
@Component({ @Component({
selector: 'app-dynamic-loader', selector: 'dynamic-loader',
templateUrl: './dynamic-loader.component.html', templateUrl: './dynamic-loader.component.html',
styleUrls: ['./dynamic-loader.component.scss'] styleUrls: ['./dynamic-loader.component.scss']
}) })
export class DynamicLoaderComponent implements AfterViewInit { export class DynamicLoaderComponent implements AfterViewInit {
sidebar:SidebarComponent
@ViewChild(SidebarComponent, {static: false})
sidebar: SidebarComponent
@ViewChild(MainComponent, {read: ViewContainerRef, static: false})
maincontent: ViewContainerRef
constructor( constructor(
private router: Router, private router: Router,
) { } private sidebarService:SidebarEntryService
) {
}
ngAfterViewInit() { ngAfterViewInit() {
this.loadWidgets() const _this = this;
(function awaitSidebar(){
const sb = _this.sidebarService.getSidebar()
if(sb != null){
_this.sidebar = sb
_this.loadWidgets()
return
}
setTimeout(awaitSidebar,25)
})()
} }
private async loadWidgets(){ private async loadWidgets(){
@@ -65,7 +93,12 @@ export class DynamicLoaderComponent implements AfterViewInit {
} }
private async installWidget(pluginName:string){ private async installWidget(pluginName:string){
const module: FrontendPlugin = await SystemJS.import("plugins/"+pluginName+".js"); let module: FrontendPlugin
if(environment.production)
module = await SystemJS.import("plugins/"+pluginName+".js");
else
module = await import("../"+pluginName+"/module")
const plugin = new module['PluginModule']() const plugin = new module['PluginModule']()
const entry:SidebarEntries | SidebarEntry = plugin.getSidebarEntry() const entry:SidebarEntries | SidebarEntry = plugin.getSidebarEntry()
const rc = this.router.config const rc = this.router.config
@@ -94,8 +127,6 @@ export class DynamicLoaderComponent implements AfterViewInit {
path: m.parentRoute, path: m.parentRoute,
loadChildren: async () => module['PluginModule'] loadChildren: async () => module['PluginModule']
}) })
console.log(this.sidebar.multientires)
break; break;
} }
this.router.resetConfig(rc) this.router.resetConfig(rc)
@@ -10,10 +10,3 @@
</a> </a>
</div> </div>
</header> </header>
<nav class="subnav">
<ul class="nav">
<li class="nav-item">
<a class="nav-link active" href="#">Dashboard</a>
</li>
</ul>
</nav>
@@ -1 +0,0 @@
<p>pluginmanager-dev works!</p>
@@ -0,0 +1,20 @@
import { Injectable } from '@angular/core';
import { SidebarComponent } from './sidebar/sidebar.component';
@Injectable({
providedIn: 'root'
})
export class SidebarEntryService {
private sidebar:SidebarComponent
constructor() { }
setSidebar(sidebar){
this.sidebar = sidebar
}
getSidebar():SidebarComponent{
return this.sidebar
}
}
@@ -1,4 +1,4 @@
<clr-vertical-nav [clrVerticalNavCollapsible]="true"> <clr-vertical-nav style="height: 100%" class="nav-trigger--bottom" [clrVerticalNavCollapsible]="true" [(clrVerticalNavCollapsed)]="collapsed">
<clr-vertical-nav-group *ngFor="let e of multientires" routerLinkActive="active"> <clr-vertical-nav-group *ngFor="let e of multientires" routerLinkActive="active">
<clr-icon [attr.shape]="e.icon" clrVerticalNavIcon></clr-icon> <clr-icon [attr.shape]="e.icon" clrVerticalNavIcon></clr-icon>
{{e.text}} {{e.text}}
@@ -17,7 +17,4 @@
{{entry.text}} {{entry.text}}
</a> </a>
</clr-vertical-nav> </clr-vertical-nav>
@@ -1,30 +1,19 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { SidebarEntries, SidebarEntry } from 'frontblock-generic/Plugin'; import { SidebarEntries, SidebarEntry } from 'frontblock-generic/Plugin';
import { sidebarEntry as apiclient } from "../apiclient-dev/apiclient-dev.component" import { environment } from 'src/environments/environment';
import { sidebarEntry as pluginmanager } from "../pluginmanager-dev/pluginmanager-dev.component"
@Component({ @Component({
selector: 'app-sidebar', selector: 'sidebar',
templateUrl: './sidebar.component.html', templateUrl: './sidebar.component.html',
styleUrls: ['./sidebar.component.scss'] styleUrls: ['./sidebar.component.scss']
}) })
export class SidebarComponent implements OnInit { export class SidebarComponent implements OnInit {
entries:SidebarEntry[] = [ entries:SidebarEntry[] = [
pluginmanager,
apiclient
] ]
multientires:SidebarEntries[] = [{ multientires:SidebarEntries[] = [
icon: "times", ]
text: "HELP",
parentRoute: "oops",
links: [{
route: "xd",
text: "XD"
}]
}]
constructor() { } constructor() { }
@@ -0,0 +1,7 @@
<nav class="subnav">
<ul class="nav">
<li class="nav-item">
<a class="nav-link active" href="#">Dashboard</a>
</li>
</ul>
</nav>
@@ -1,20 +1,20 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { PluginmanagerDevComponent } from './pluginmanager-dev.component'; import { SubnavComponent } from './subnav.component';
describe('PluginmanagerDevComponent', () => { describe('SubnavComponent', () => {
let component: PluginmanagerDevComponent; let component: SubnavComponent;
let fixture: ComponentFixture<PluginmanagerDevComponent>; let fixture: ComponentFixture<SubnavComponent>;
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ PluginmanagerDevComponent ] declarations: [ SubnavComponent ]
}) })
.compileComponents(); .compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
fixture = TestBed.createComponent(PluginmanagerDevComponent); fixture = TestBed.createComponent(SubnavComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
fixture.detectChanges(); fixture.detectChanges();
}); });
@@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'subnav',
templateUrl: './subnav.component.html',
styleUrls: ['./subnav.component.scss']
})
export class SubnavComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
+1
View File
@@ -8,6 +8,7 @@
"src/**/*.ts" "src/**/*.ts"
], ],
"exclude": [ "exclude": [
"node_modules",
"src/test.ts", "src/test.ts",
"src/**/*.spec.ts" "src/**/*.spec.ts"
] ]
-3
View File
@@ -1,6 +1,5 @@
import resolve from 'rollup-plugin-node-resolve'; import resolve from 'rollup-plugin-node-resolve';
import typescript from 'rollup-plugin-typescript2'; import typescript from 'rollup-plugin-typescript2';
import externals from 'rollup-plugin-node-externals'
export default { export default {
input: 'src/frontend/widget/main.ts', input: 'src/frontend/widget/main.ts',
@@ -21,8 +20,6 @@ export default {
}) })
], ],
external: [ external: [
"frontblock",
"frontblock-generic",
'plugins-core', 'plugins-core',
'@angular/core', '@angular/core',
'@angular/common', '@angular/common',