├── .editorconfig ├── .gitignore ├── README.md ├── angular.json ├── package-lock.json ├── package.json ├── src ├── app │ ├── app.component.css │ ├── app.component.html │ ├── app.component.spec.ts │ ├── app.component.ts │ ├── app.module.ts │ ├── auth │ │ ├── auth.component.html │ │ ├── auth.component.scss │ │ ├── auth.component.ts │ │ ├── auth.module.ts │ │ ├── config │ │ │ ├── abci │ │ │ │ ├── abci-add.component.css │ │ │ │ ├── abci-add.component.html │ │ │ │ ├── abci-add.component.ts │ │ │ │ ├── abci.component.css │ │ │ │ ├── abci.component.html │ │ │ │ ├── abci.component.ts │ │ │ │ └── abciConfig.ts │ │ │ ├── distributednode │ │ │ │ ├── chainnodeConfig.ts │ │ │ │ ├── chainnodeadd.component.html │ │ │ │ ├── chainnodeadd.component.ts │ │ │ │ ├── distributednode.component.css │ │ │ │ ├── distributednode.component.html │ │ │ │ ├── distributednode.component.ts │ │ │ │ ├── distributednodeConfig.ts │ │ │ │ ├── distributednodeadd.component.css │ │ │ │ ├── distributednodeadd.component.html │ │ │ │ └── distributednodeadd.component.ts │ │ │ ├── mdbserv │ │ │ │ ├── mdbserv-edit.component.css │ │ │ │ ├── mdbserv-edit.component.html │ │ │ │ ├── mdbserv-edit.component.ts │ │ │ │ ├── mdbserv.component.css │ │ │ │ ├── mdbserv.component.html │ │ │ │ ├── mdbserv.component.ts │ │ │ │ └── mdbservConfig.ts │ │ │ └── mdbuser │ │ │ │ ├── mdbuser-edit.component.css │ │ │ │ ├── mdbuser-edit.component.html │ │ │ │ ├── mdbuser-edit.component.ts │ │ │ │ ├── mdbuser.component.css │ │ │ │ ├── mdbuser.component.html │ │ │ │ ├── mdbuser.component.ts │ │ │ │ └── mdbuserConfig.ts │ │ ├── lazyloader.routes.ts │ │ ├── overview │ │ │ ├── overview-chart1 │ │ │ │ ├── overview-chart1.component.css │ │ │ │ ├── overview-chart1.component.html │ │ │ │ └── overview-chart1.component.ts │ │ │ ├── overview.component.css │ │ │ ├── overview.component.html │ │ │ └── overview.component.ts │ │ ├── search │ │ │ ├── assets-deal │ │ │ │ ├── assets-deal.component.css │ │ │ │ ├── assets-deal.component.html │ │ │ │ └── assets-deal.component.ts │ │ │ ├── assets │ │ │ │ ├── assets.component.css │ │ │ │ ├── assets.component.html │ │ │ │ └── assets.component.ts │ │ │ ├── block-deal-detail │ │ │ │ ├── block-deal-detail.component.css │ │ │ │ ├── block-deal-detail.component.html │ │ │ │ └── block-deal-detail.component.ts │ │ │ ├── block-deal │ │ │ │ ├── block-deal.component.css │ │ │ │ ├── block-deal.component.html │ │ │ │ └── block-deal.component.ts │ │ │ └── block │ │ │ │ ├── block.component.css │ │ │ │ ├── block.component.html │ │ │ │ └── block.component.ts │ │ └── system │ │ │ ├── aboutus │ │ │ ├── aboutus.component.css │ │ │ ├── aboutus.component.html │ │ │ └── aboutus.component.ts │ │ │ └── users │ │ │ ├── user-add │ │ │ ├── user-add.component.css │ │ │ ├── user-add.component.html │ │ │ ├── user-add.component.spec.ts │ │ │ ├── user-add.component.ts │ │ │ └── userConfig.ts │ │ │ ├── users.component.css │ │ │ ├── users.component.html │ │ │ └── users.component.ts │ ├── core │ │ ├── breadcrumb │ │ │ ├── breadcrumb.component.css │ │ │ ├── breadcrumb.component.html │ │ │ ├── breadcrumb.component.spec.ts │ │ │ └── breadcrumb.component.ts │ │ ├── core.module.ts │ │ ├── fullscreen │ │ │ ├── fullscreen.component.html │ │ │ ├── fullscreen.component.scss │ │ │ ├── fullscreen.component.spec.ts │ │ │ └── fullscreen.component.ts │ │ ├── search-bar │ │ │ ├── search-bar.component.html │ │ │ ├── search-bar.component.scss │ │ │ ├── search-bar.component.spec.ts │ │ │ └── search-bar.component.ts │ │ ├── sidebar │ │ │ ├── sidebar.component.html │ │ │ ├── sidebar.component.scss │ │ │ ├── sidebar.component.spec.ts │ │ │ └── sidebar.component.ts │ │ ├── sidemenu-item │ │ │ ├── sidemenu-item.component.html │ │ │ ├── sidemenu-item.component.scss │ │ │ ├── sidemenu-item.component.spec.ts │ │ │ └── sidemenu-item.component.ts │ │ ├── sidemenu │ │ │ ├── menu-element.ts │ │ │ ├── sidemenu.component.html │ │ │ ├── sidemenu.component.scss │ │ │ ├── sidemenu.component.spec.ts │ │ │ └── sidemenu.component.ts │ │ ├── toolbar-notification │ │ │ ├── toolbar-notification.component.html │ │ │ ├── toolbar-notification.component.scss │ │ │ ├── toolbar-notification.component.spec.ts │ │ │ └── toolbar-notification.component.ts │ │ ├── toolbar │ │ │ ├── toolbar.component.html │ │ │ ├── toolbar.component.scss │ │ │ ├── toolbar.component.spec.ts │ │ │ ├── toolbar.component.ts │ │ │ └── toolbar.helpers.ts │ │ └── user-menu │ │ │ ├── user-menu.component.html │ │ │ ├── user-menu.component.scss │ │ │ ├── user-menu.component.spec.ts │ │ │ └── user-menu.component.ts │ ├── lazy-load │ │ └── lazy-load.module.ts │ ├── login │ │ ├── login.component.html │ │ ├── login.component.scss │ │ ├── login.component.ts │ │ └── login.module.ts │ ├── modules │ │ ├── cdk-icons │ │ │ ├── cdk-icons.module.ts │ │ │ └── svg-icons.service.ts │ │ ├── css │ │ │ └── utility.scss │ │ ├── mc-confirm │ │ │ ├── confirm.interface.ts │ │ │ ├── mc-confirm.component.css │ │ │ ├── mc-confirm.component.html │ │ │ ├── mc-confirm.component.ts │ │ │ ├── mc-confirm.module.ts │ │ │ └── mc-confirm.service.ts │ │ └── pipes │ │ │ ├── pipes.module.spec.ts │ │ │ ├── pipes.module.ts │ │ │ └── pipes │ │ │ ├── keys.pipe.spec.ts │ │ │ ├── keys.pipe.ts │ │ │ ├── sort.pipe.spec.ts │ │ │ ├── sort.pipe.ts │ │ │ ├── status.pipe.spec.ts │ │ │ ├── status.pipe.ts │ │ │ ├── values.pipe.spec.ts │ │ │ └── values.pipe.ts │ └── services │ │ ├── cli.args.ts │ │ ├── config.service.ts │ │ ├── login.service.ts │ │ ├── restful.service.ts │ │ ├── service.module.ts │ │ └── user.service.ts ├── assets │ ├── .gitkeep │ ├── environments │ │ └── environment.json │ ├── icon │ │ ├── noWatch.svg │ │ ├── password.svg │ │ └── watch.svg │ ├── images │ │ ├── banner.png │ │ ├── cop_logo.png │ │ ├── favicon.png │ │ ├── logo.png │ │ ├── type_1.png │ │ ├── type_2.png │ │ ├── type_3.png │ │ ├── type_4.png │ │ ├── type_5.png │ │ └── type_6.png │ └── lib │ │ └── hover.css ├── browserslist ├── environments │ ├── environment.prod.ts │ ├── environment.ts │ └── environmentLoader.ts ├── favicon.png ├── index.html ├── karma.conf.js ├── main.ts ├── polyfills.ts ├── styles.css ├── test.ts ├── theme │ ├── theme.scss │ └── typography.scss ├── tsconfig.app.json ├── tsconfig.spec.json └── tslint.json ├── tsconfig.json └── tslint.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /tmp 5 | /out-tsc 6 | 7 | # dependencies 8 | /node_modules 9 | 10 | # IDEs and editors 11 | /.idea 12 | .project 13 | .classpath 14 | .c9/ 15 | *.launch 16 | .settings/ 17 | *.sublime-workspace 18 | 19 | # IDE - VSCode 20 | .vscode/* 21 | !.vscode/settings.json 22 | !.vscode/tasks.json 23 | !.vscode/launch.json 24 | !.vscode/extensions.json 25 | 26 | # misc 27 | /.sass-cache 28 | /connect.lock 29 | /coverage 30 | /libpeerconnection.log 31 | npm-debug.log 32 | yarn-error.log 33 | testem.log 34 | /typings 35 | 36 | # System Files 37 | .DS_Store 38 | Thumbs.db 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 项目启动 2 | 3 | --- 4 | 1、安装依赖 5 | 6 | ```bash 7 | npm install 8 | ``` 9 | 10 | 2、进入开发环境 11 | 12 | ```bash 13 | ng serve 14 | ``` 15 | 16 | -------------------------------------------------------------------------------- /angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "mdbui": { 7 | "root": "", 8 | "sourceRoot": "src", 9 | "projectType": "application", 10 | "prefix": "app", 11 | "schematics": {}, 12 | "architect": { 13 | "build": { 14 | "builder": "@angular-devkit/build-angular:browser", 15 | "options": { 16 | "outputPath": "dist/mdbui", 17 | "index": "src/index.html", 18 | "main": "src/main.ts", 19 | "polyfills": "src/polyfills.ts", 20 | "tsConfig": "src/tsconfig.app.json", 21 | "assets": [ 22 | "src/favicon.ico", 23 | "src/assets" 24 | ], 25 | "styles": [ 26 | "src/styles.css", 27 | "src/theme/theme.scss", 28 | "src/theme/typography.scss", 29 | "src/app/modules/css/utility.scss" 30 | ], 31 | "scripts": [] 32 | }, 33 | "configurations": { 34 | "production": { 35 | "fileReplacements": [ 36 | { 37 | "replace": "src/environments/environment.ts", 38 | "with": "src/environments/environment.prod.ts" 39 | } 40 | ], 41 | "optimization": true, 42 | "outputHashing": "all", 43 | "sourceMap": false, 44 | "extractCss": true, 45 | "namedChunks": false, 46 | "aot": true, 47 | "extractLicenses": true, 48 | "vendorChunk": false, 49 | "buildOptimizer": true 50 | } 51 | } 52 | }, 53 | "serve": { 54 | "builder": "@angular-devkit/build-angular:dev-server", 55 | "options": { 56 | "browserTarget": "mdbui:build", 57 | "port":4201, 58 | "host":"0.0.0.0" 59 | }, 60 | "configurations": { 61 | "production": { 62 | "browserTarget": "mdbui:build:production" 63 | } 64 | } 65 | }, 66 | "extract-i18n": { 67 | "builder": "@angular-devkit/build-angular:extract-i18n", 68 | "options": { 69 | "browserTarget": "mdbui:build" 70 | } 71 | }, 72 | "test": { 73 | "builder": "@angular-devkit/build-angular:karma", 74 | "options": { 75 | "main": "src/test.ts", 76 | "polyfills": "src/polyfills.ts", 77 | "tsConfig": "src/tsconfig.spec.json", 78 | "karmaConfig": "src/karma.conf.js", 79 | "styles": [ 80 | "src/styles.css", 81 | "src/theme/theme.scss", 82 | "src/theme/typography.scss" 83 | ], 84 | "scripts": [], 85 | "assets": [ 86 | "src/favicon.ico", 87 | "src/assets" 88 | ] 89 | } 90 | }, 91 | "lint": { 92 | "builder": "@angular-devkit/build-angular:tslint", 93 | "options": { 94 | "tsConfig": [ 95 | "src/tsconfig.app.json", 96 | "src/tsconfig.spec.json" 97 | ], 98 | "exclude": [ 99 | "**/node_modules/**" 100 | ] 101 | } 102 | } 103 | } 104 | }, 105 | "mdbui-e2e": { 106 | "root": "e2e/", 107 | "projectType": "application", 108 | "architect": { 109 | "e2e": { 110 | "builder": "@angular-devkit/build-angular:protractor", 111 | "options": { 112 | "protractorConfig": "e2e/protractor.conf.js", 113 | "devServerTarget": "mdbui:serve" 114 | }, 115 | "configurations": { 116 | "production": { 117 | "devServerTarget": "mdbui:serve:production" 118 | } 119 | } 120 | }, 121 | "lint": { 122 | "builder": "@angular-devkit/build-angular:tslint", 123 | "options": { 124 | "tsConfig": "e2e/tsconfig.e2e.json", 125 | "exclude": [ 126 | "**/node_modules/**" 127 | ] 128 | } 129 | } 130 | } 131 | } 132 | }, 133 | "defaultProject": "mdbui" 134 | } 135 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mdbui", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "test": "ng test", 9 | "lint": "ng lint", 10 | "e2e": "ng e2e" 11 | }, 12 | "private": true, 13 | "dependencies": { 14 | "@angular/animation": "^4.0.0-beta.8", 15 | "@angular/animations": "^6.0.3", 16 | "@angular/cdk": "^6.4.0", 17 | "@angular/common": "^6.0.3", 18 | "@angular/compiler": "^6.0.3", 19 | "@angular/core": "^6.0.3", 20 | "@angular/flex-layout": "^6.0.0-beta.16", 21 | "@angular/forms": "^6.0.3", 22 | "@angular/http": "^6.0.3", 23 | "@angular/material": "^6.4.0", 24 | "@angular/platform-browser": "^6.0.3", 25 | "@angular/platform-browser-dynamic": "^6.0.3", 26 | "@angular/router": "^6.0.3", 27 | "core-js": "^2.5.4", 28 | "echarts": "^4.2.0-rc.2", 29 | "hammerjs": "^2.0.8", 30 | "material-design-icons": "^3.0.1", 31 | "ngx-auto-unsubscribe": "^2.4.1", 32 | "ngx-echarts": "^4.0.1", 33 | "ngx-perfect-scrollbar": "^6.2.0", 34 | "ngx-spinner": "^6.0.0", 35 | "rxjs": "^6.0.0", 36 | "screenfull": "^3.3.2", 37 | "ts-md5": "^1.2.4", 38 | "zone.js": "^0.8.26" 39 | }, 40 | "devDependencies": { 41 | "@angular-devkit/build-angular": "^0.11.3", 42 | "@angular/cli": "~6.0.8", 43 | "@angular/compiler-cli": "^6.0.3", 44 | "@angular/language-service": "^6.0.3", 45 | "@types/echarts": "^4.1.3", 46 | "@types/jasmine": "~2.8.6", 47 | "@types/jasminewd2": "~2.0.3", 48 | "@types/node": "~8.9.4", 49 | "codelyzer": "~4.2.1", 50 | "jasmine-core": "~2.99.1", 51 | "jasmine-spec-reporter": "~4.2.1", 52 | "karma": "~1.7.1", 53 | "karma-chrome-launcher": "~2.2.0", 54 | "karma-coverage-istanbul-reporter": "~2.0.0", 55 | "karma-jasmine": "~1.1.1", 56 | "karma-jasmine-html-reporter": "^0.2.2", 57 | "protractor": "^5.4.1", 58 | "ts-node": "~5.0.1", 59 | "tslint": "~5.9.1", 60 | "typescript": "~2.7.2" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/app/app.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemo-crypto/angular6-material/e387fd39877dd833a171ba3e9227fb2d5b909957/src/app/app.component.css -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | describe('AppComponent', () => { 4 | beforeEach(async(() => { 5 | TestBed.configureTestingModule({ 6 | declarations: [ 7 | AppComponent 8 | ], 9 | }).compileComponents(); 10 | })); 11 | it('should create the app', async(() => { 12 | const fixture = TestBed.createComponent(AppComponent); 13 | const app = fixture.debugElement.componentInstance; 14 | expect(app).toBeTruthy(); 15 | })); 16 | it(`should have as title 'app'`, async(() => { 17 | const fixture = TestBed.createComponent(AppComponent); 18 | const app = fixture.debugElement.componentInstance; 19 | expect(app.title).toEqual('app'); 20 | })); 21 | it('should render title in a h1 tag', async(() => { 22 | const fixture = TestBed.createComponent(AppComponent); 23 | fixture.detectChanges(); 24 | const compiled = fixture.debugElement.nativeElement; 25 | expect(compiled.querySelector('h1').textContent).toContain('Welcome to mdbui!'); 26 | })); 27 | }); 28 | -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.css'] 7 | }) 8 | export class AppComponent { 9 | title = 'app'; 10 | } 11 | -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule , APP_INITIALIZER } from '@angular/core'; 3 | import { RouterModule } from '@angular/router'; 4 | import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 5 | import { HttpClientModule } from '@angular/common/http'; 6 | import { LazyLoadModule } from './lazy-load/lazy-load.module'; 7 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 8 | import { CoreModule } from './core/core.module'; 9 | import { ServiceModule } from './services/service.module'; 10 | import { NgxSpinnerModule } from 'ngx-spinner'; 11 | 12 | 13 | import { McConfirmModule } from './modules/mc-confirm/mc-confirm.module'; 14 | 15 | import { AppComponent } from './app.component'; 16 | import {CdkIconsModule, SvgIconsService} from './modules/cdk-icons/cdk-icons.module'; 17 | 18 | @NgModule({ 19 | declarations: [ 20 | AppComponent 21 | ], 22 | imports: [ 23 | BrowserModule, 24 | RouterModule, 25 | LazyLoadModule, 26 | CoreModule, 27 | FormsModule, 28 | HttpClientModule, 29 | ReactiveFormsModule, 30 | ServiceModule, 31 | McConfirmModule, 32 | CdkIconsModule, 33 | 34 | BrowserAnimationsModule, 35 | NgxSpinnerModule 36 | ], 37 | providers: [ 38 | { 39 | provide: APP_INITIALIZER, 40 | useFactory: (si: SvgIconsService) => 41 | function () { 42 | return si.init(); 43 | }, 44 | deps: [SvgIconsService], 45 | multi: true 46 | } 47 | ], 48 | bootstrap: [AppComponent] 49 | }) 50 | export class AppModule { } 51 | -------------------------------------------------------------------------------- /src/app/auth/auth.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 60 | 61 | 62 | 63 | 64 | 65 |
66 | search 67 | 68 |
69 |
70 | 71 | 72 | 73 | 74 | 75 | 76 |
77 | 84 | 105 |
106 | 107 | 108 |
109 | 110 | 111 |
112 | 113 |
114 | -------------------------------------------------------------------------------- /src/app/auth/auth.component.scss: -------------------------------------------------------------------------------- 1 | 2 | @mixin auth($theme) { 3 | $primary: map-get($theme, primary); 4 | $accent: map-get($theme, accent); 5 | $warn: map-get($theme, warn); 6 | 7 | 8 | .sidenav,.drawer{ 9 | background: mat-color($primary,700); 10 | overflow: hidden; 11 | position: relative; 12 | width: 200px; 13 | } 14 | [no-over-flow] { 15 | overflow: hidden; 16 | } 17 | .router-outlet{ 18 | position: relative;padding: 0px 5px; 19 | } 20 | .spacer { 21 | width: 100%; 22 | } 23 | .logo{ 24 | font-size: 26px;font-family: Roboto;color:white; 25 | } 26 | } 27 | 28 | :host { 29 | height: 100%; 30 | } 31 | 32 | .toolbar-user-container { 33 | height: 100%; 34 | position: relative; 35 | 36 | .toolbar-user-btn { 37 | display: flex; 38 | justify-content: center; 39 | height: 100%; 40 | min-width: 160px; 41 | 42 | .avatar { 43 | width: 30px; 44 | height: 30px; 45 | border-radius: 50%; 46 | } 47 | 48 | .name { 49 | margin: 0 8px 0 10px; 50 | } 51 | 52 | .icon { 53 | width: 16px; 54 | height: 16px; 55 | font-size: 16px; 56 | transform: rotate(0); 57 | transition: transform .25s cubic-bezier(.25,.8,.25,1); 58 | } 59 | 60 | &.open { 61 | background: rgba(0, 0, 0, .05); 62 | 63 | .icon { 64 | transform: rotate(-180deg); 65 | } 66 | } 67 | } 68 | 69 | .dropdown { 70 | background: white; 71 | z-index: 2; 72 | position: absolute; 73 | width: 100%; 74 | min-width: 160px; 75 | opacity: 0; 76 | visibility: hidden; 77 | transition: all .25s linear, max-height .25s linear, opacity .25s linear; 78 | 79 | @media screen and (max-width: 599px) { 80 | min-width: 65px; 81 | } 82 | 83 | &.open { 84 | opacity: 1; 85 | visibility: visible; 86 | } 87 | } 88 | } 89 | 90 | mat-toolbar{ 91 | /*background-color: #2196f3;*/ 92 | background-color: #3f51b5; 93 | } 94 | 95 | .mat-elevation-z4{ 96 | position: fixed; 97 | left: 0; 98 | right: 0; 99 | top: 0; 100 | z-index: 100; 101 | } 102 | 103 | div.logo{ 104 | padding-left: 47px; 105 | padding-right: 47px; 106 | } 107 | 108 | div.MDB-body{ 109 | //格子背景-css 110 | background: linear-gradient(135deg,#f0f0f0 22px,rgba(0,0,0,.04) 22px,rgba(0,0,0,.04) 24px,transparent 24px,transparent 67px,rgba(0,0,0,.04) 67px,rgba(0,0,0,.04) 69px,transparent 69px),linear-gradient(225deg,#f0f0f0 22px,rgba(0,0,0,.04) 22px,rgba(0,0,0,.04) 24px,transparent 24px,transparent 67px,rgba(0,0,0,.04) 67px,rgba(0,0,0,.04) 69px,transparent 69px) 0 64px; 111 | background-color: #f0f0f0; 112 | background-size: 64px 128px; 113 | 114 | padding-bottom: 60px; 115 | padding-left: 60px; 116 | padding-right: 60px; 117 | } 118 | 119 | a{ 120 | text-decoration:none; 121 | color: #202020; 122 | } 123 | 124 | .mat-menu-item a mat-icon{ 125 | margin-right: 2px; 126 | margin-top: -3px; 127 | } 128 | 129 | /*dropDown 伪元素*/ 130 | .out,.in{ 131 | position:absolute; 132 | width:0; 133 | height:0px; 134 | } 135 | 136 | .out{ 137 | border:20px solid transparent; 138 | border-bottom-color:#fff; 139 | top:-40px; 140 | left:20%; 141 | } 142 | 143 | 144 | /*************头部input框 -- 点击伸缩功能************/ 145 | span.spacer{ 146 | text-align: center; 147 | } 148 | .search-wrap{ 149 | margin: 0 auto; 150 | width: 200px; 151 | //height: 64px; 152 | } 153 | .search{ 154 | width: 100px; 155 | height: 35px; 156 | border: 1px solid #3f51b5 !important; 157 | padding: 0 10px; 158 | /* float: right; */ /*居中的话就两边伸展,居右就往左边伸展,居左就往右边伸展*/ 159 | border-radius: 20px; 160 | color: #2c2c2c; 161 | transition: all 1s; /*transition: cubic-bezier(0.68, -0.55, 0.27, 1.55) all 1s;-贝塞尔曲线*/ 162 | /* opacity: 0.5; */ /*透明度*/ 163 | } 164 | .search:focus{ 165 | width: 100%; 166 | outline:none; 167 | } 168 | /************* end ************/ 169 | -------------------------------------------------------------------------------- /src/app/auth/auth.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Input, HostListener, ElementRef } from '@angular/core'; 2 | import { MediaChange, ObservableMedia } from '@angular/flex-layout'; 3 | import {McConfirmService} from "../modules/mc-confirm/mc-confirm.service"; 4 | import {ConfigService} from "../services/config.service"; 5 | import {Router} from "@angular/router"; 6 | import { LoginService } from '../services/login.service' 7 | 8 | 9 | @Component({ 10 | selector: 'app-auth', 11 | templateUrl: './auth.component.html', 12 | styleUrls: ['./auth.component.scss'] 13 | 14 | }) 15 | 16 | export class AuthComponent implements OnInit{ 17 | 18 | isOpen: boolean = false; 19 | 20 | @Input() currentUser = null; 21 | @HostListener('document:click', ['$event', '$event.target']) 22 | onClick(event: MouseEvent, targetElement: HTMLElement) { 23 | if (!targetElement) { 24 | return; 25 | } 26 | 27 | const clickedInside = this.elementRef.nativeElement.contains(targetElement); 28 | if (!clickedInside) { 29 | this.isOpen = false; 30 | } 31 | } 32 | 33 | constructor( 34 | private _router: Router, 35 | private _login: LoginService, 36 | private media: ObservableMedia, 37 | private _confirm: McConfirmService, 38 | private _config: ConfigService, 39 | private elementRef: ElementRef 40 | ) { } 41 | 42 | ngOnInit() { 43 | 44 | } 45 | 46 | /*退出-登录页面*/ 47 | loginOut() { 48 | this._login.doLogout(); 49 | } 50 | 51 | } 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/app/auth/config/abci/abci-add.component.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/app/auth/config/abci/abci-add.component.html: -------------------------------------------------------------------------------- 1 |
2 | border_color 3 |

{{isNew?'新增区块链数据服务配置':'修改新增区块链数据服务配置'}}

4 | 7 |
8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 必须输入名称! 16 | 17 | 18 | 19 | {{nameCtrl.getError('name')}} 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
32 | {{singleOption.value.name}} 33 |
34 |
35 |
36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/app/auth/config/abci/abci-add.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Inject } from '@angular/core'; 2 | import {MatDialogRef, MAT_DIALOG_DATA} from '@angular/material'; 3 | import { ABCIConfig } from './abciConfig'; 4 | import { ConfigService } from '../../../services/config.service'; 5 | import {FormArray, FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms'; 6 | @Component({ 7 | selector: 'app-abci-add', 8 | templateUrl: './abci-add.component.html', 9 | styleUrls: ['./abci-add.component.css'] 10 | }) 11 | export class AbciAddComponent implements OnInit { 12 | 13 | /*表单验证*/ 14 | baseForm :FormGroup; 15 | nameValidator(control: FormControl): any{ 16 | /*仅允许英文字母、数字和下划线*/ 17 | const nameReg = /^[\u4E00-\u9FA5a-zA-Z0-9_]{3,20}$/ 18 | const result = nameReg.test(control.value); 19 | return result ? null : { name: '汉字、英文字母、数字、下划线组成,3-20位!' }; 20 | } 21 | 22 | isNew=true; 23 | row:ABCIConfig; 24 | options; 25 | constructor( 26 | private _sheetRef: MatDialogRef, 27 | // /*Inject装饰器*/ 28 | @Inject(MAT_DIALOG_DATA) public data: any, 29 | private _fb: FormBuilder, 30 | private _config: ConfigService 31 | ) { 32 | this.isNew = (data.action==='new'); 33 | if (data.data) { 34 | this.row = new ABCIConfig(data.data); 35 | } else { 36 | this.row = new ABCIConfig(); 37 | } 38 | } 39 | 40 | ngOnInit() { 41 | this.buildForm(); 42 | } 43 | 44 | get nameCtrl():FormControl{ 45 | return this.baseForm.get('name') as FormControl; 46 | } 47 | 48 | 49 | buildForm(){ 50 | this.baseForm = this._fb.group({ 51 | name : [this.row.name,[Validators.required,this.nameValidator]], 52 | sertx: [this.row.sertx], 53 | dbstr: [this.row.dbstr], 54 | multipleOptions : [this._fb.array([])] 55 | }); 56 | 57 | let multipleOptions = ['NOTIFY','TXALL']; 58 | this.setMultipleOptions(multipleOptions, this.row.options); 59 | if(!this.isNew){ 60 | this.nameCtrl.disable(); 61 | } 62 | } 63 | 64 | setMultipleOptions(multipleOptions:string[],values='') { 65 | 66 | const multipleOptionsFGs = multipleOptions.map(singleOption =>{ 67 | let obj={name: singleOption,checked:(values.indexOf(singleOption)>=0)}; 68 | return this._fb.group(obj) 69 | }); 70 | 71 | const singleOptionFormArray = this._fb.array(multipleOptionsFGs); 72 | this.baseForm.setControl('multipleOptions', singleOptionFormArray); 73 | } 74 | 75 | get multipleOptions():FormArray{ 76 | return this.baseForm.get('multipleOptions') as FormArray; 77 | } 78 | 79 | updateModel() { 80 | let val = this.baseForm.getRawValue(); 81 | this.row.name = val.name; 82 | this.row.sertx = val.sertx; 83 | this.row.dbstr = val.dbstr; 84 | let array = []; 85 | val.multipleOptions.forEach(option => { 86 | if( option.checked == true){ 87 | array.push(option.name); 88 | } 89 | }); 90 | if(array.length == 0){ 91 | this.row.options = ''; 92 | }else if(array.length == 1){ 93 | this.row.options = array[0]; 94 | }else if(array.length > 1){ 95 | let str = ''; 96 | for(var i = 0; i < array.length; i++){ 97 | str += array[i] + '|'; 98 | } 99 | if(str.length > 0 ){ 100 | str = str.substr(0,str.length - 1); 101 | } 102 | this.row.options = str; 103 | } 104 | } 105 | 106 | doSave() { 107 | this.updateModel(); 108 | this._config.addConfig('abci',this.row).subscribe(data => { 109 | this._sheetRef.close(this.row); 110 | }); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/app/auth/config/abci/abci.component.css: -------------------------------------------------------------------------------- 1 | tr.example-detail-row { 2 | height: 0; 3 | } 4 | 5 | .example-element-row td { 6 | border-bottom-width: 0; 7 | } 8 | 9 | .example-element-detail { 10 | overflow: hidden; 11 | display: flex; 12 | } 13 | 14 | th.button{ 15 | text-align: right; 16 | } 17 | 18 | button.refresh{ 19 | margin-left: 20px; 20 | } 21 | 22 | table.mat-table th.mat-header-cell{ 23 | background-color: rgba(0,0,0,.04); 24 | } 25 | -------------------------------------------------------------------------------- /src/app/auth/config/abci/abci.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | format_indent_increase 5 |
6 |
7 | MDB配置 8 |
9 |
10 | keyboard_arrow_right 11 |
12 |
13 | 区块链数据服务 14 |
15 |
16 | keyboard_arrow_right 17 |
18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 58 | 78 | 79 | 80 | 88 | 89 |
名称 {{row.name}} 网络服务参数 {{row.sertx}} 数据库连接参数 {{row.dbstr}} 选项 {{row.options}} 状态 {{configStatus(row.name) | status }} 51 | 54 | 57 | 59 | 62 | 65 | 68 | 71 | 74 | 77 | 81 |
82 | 83 | 84 | {{k}}: {{configStatusMap[row.name][k]}} 85 | 86 |
87 |
90 |
91 |
92 |
93 |
94 | -------------------------------------------------------------------------------- /src/app/auth/config/abci/abci.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {MatBottomSheet, MatDialog} from '@angular/material'; 3 | import {animate, state, style, transition, trigger} from '@angular/animations'; 4 | 5 | import { RestfulService } from '../../../services/restful.service'; 6 | import { McConfirmService } from '../../../modules/mc-confirm/mc-confirm.module'; 7 | import { ConfigService } from '../../../services/config.service'; 8 | import { AbciAddComponent } from './abci-add.component'; 9 | 10 | @Component({ 11 | selector: 'app-abci', 12 | templateUrl: './abci.component.html', 13 | styleUrls: ['./abci.component.css'], 14 | animations: [ 15 | trigger('detailExpand', [ 16 | state('collapsed', style({height: '0px', minHeight: '0', display: 'none'})), 17 | state('expanded', style({height: '*'})), 18 | transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')), 19 | ]), 20 | ], 21 | }) 22 | export class ABCIComponent implements OnInit { 23 | columnsToDisplay = ['name', 'sertx', 'dbstr', 'options', 'status', 'action']; 24 | data = []; 25 | expandedRow; 26 | configStatusMap = {}; 27 | constructor( 28 | private _matDialog: MatDialog, 29 | private _restful: RestfulService, 30 | private _config: ConfigService, 31 | private _confirm: McConfirmService 32 | ) { } 33 | 34 | ngOnInit() { 35 | this.getConfigs(); 36 | } 37 | 38 | getConfigs() { 39 | this._config.getConfigs('abci').subscribe(data => { 40 | this.data = data; 41 | this.data.forEach(conf => { 42 | this.getConfigStatus(conf.name); 43 | }); 44 | }); 45 | } 46 | 47 | getConfigStatus(name) { 48 | this._config.getConfigStatus('abci', name).subscribe(data => { 49 | this.configStatusMap[name] = data; 50 | }); 51 | 52 | } 53 | 54 | configStatus(name) { 55 | if (this.configStatusMap[name] == undefined) { return ''; } 56 | return this.configStatusMap[name]['status']; 57 | } 58 | 59 | addConfig() { 60 | const dialogRef = this._matDialog.open(AbciAddComponent, { 61 | width: '600px', 62 | disableClose: true, 63 | data: {action: 'new'} 64 | }); 65 | dialogRef.afterClosed().subscribe(result => { 66 | if (result) { 67 | // this._confirm.alert('新增配置成功!'); 68 | this.getConfigs(); 69 | } 70 | }); 71 | } 72 | 73 | updateConfig(cf) { 74 | const dialogRef = this._matDialog.open(AbciAddComponent, { 75 | width: '600px', 76 | disableClose: true, 77 | data: {action: 'update', data: cf} 78 | }); 79 | dialogRef.afterClosed().subscribe(result => { 80 | if (result) { 81 | // this._confirm.alert('修改配置成功!'); 82 | this.getConfigs(); 83 | } 84 | }); 85 | } 86 | 87 | removeConfig(cf) { 88 | this._confirm.confirm({ 89 | message: '是否真正删除配置项[' + cf.name + ']?', 90 | onAccept: () => { 91 | this._config.removeConfig('abci', cf.name).subscribe(data => { 92 | if (data) { 93 | this._confirm.alert('配置项[' + cf.name + ']已经删除'); 94 | this.getConfigs(); 95 | } else { 96 | this._confirm.alert('配置项[' + cf.name + ']删除出错,请稍后再试', ); 97 | } 98 | }); 99 | } 100 | }); 101 | } 102 | 103 | turnConfigOn(name) { 104 | this._confirm.confirm({ 105 | message: '是否真正启用配置项[' + name + ']?', 106 | onAccept: () => { 107 | this._config.turnConfigOn('abci', name).subscribe(data => { 108 | if (data) { 109 | this._confirm.alert('配置项[' + name + ']已经启用'); 110 | this.getConfigs(); 111 | } else { 112 | this._confirm.alert('配置项[' + name + ']启用出错,请稍后再试', ); 113 | } 114 | }); 115 | } 116 | }); 117 | } 118 | 119 | turnConfigOff(name) { 120 | this._confirm.confirm({ 121 | message: '是否真正停用配置项[' + name + ']?', 122 | onAccept: () => { 123 | this._config.turnConfigOff('abci', name).subscribe(data => { 124 | if (data) { 125 | this._confirm.alert('配置项[' + name + ']已经停用'); 126 | this.getConfigs(); 127 | } else { 128 | this._confirm.alert('配置项[' + name + ']停用出错,请稍后再试', ); 129 | } 130 | }); 131 | } 132 | }); 133 | } 134 | 135 | toggleConfigDetail(cf) { 136 | if (this.expandedRow == cf) { 137 | this.expandedRow = undefined; 138 | } else { 139 | this.expandedRow = cf; 140 | } 141 | } 142 | 143 | } 144 | -------------------------------------------------------------------------------- /src/app/auth/config/abci/abciConfig.ts: -------------------------------------------------------------------------------- 1 | export class ABCIConfig { 2 | name:string; 3 | sertx:string; 4 | dbstr:string; 5 | options:string; //(NOTIFY|TXALL) 6 | statefile:string; 7 | constructor(data=undefined) { 8 | this.name = ''; 9 | this.sertx = ''; 10 | this.dbstr = ''; 11 | this.options = ''; 12 | this.statefile = ''; 13 | if (data!=undefined) { 14 | for (let k in data) { 15 | this[k] = data[k]; 16 | } 17 | } 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /src/app/auth/config/distributednode/chainnodeConfig.ts: -------------------------------------------------------------------------------- 1 | export class chainnodeConfig { 2 | name:string; 3 | nodename:String; 4 | pubkey:String; 5 | nodeid:String; 6 | addr:String; 7 | powerid:String; 8 | constructor(data=undefined) { 9 | this.name = ''; 10 | this.nodename = ''; 11 | this.pubkey = ''; 12 | this.nodeid = ''; 13 | this.addr = ''; 14 | this.powerid =''; 15 | if (data!=undefined) { 16 | 17 | for (let k in data) { 18 | this[k] = data[k]; 19 | } 20 | 21 | } 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /src/app/auth/config/distributednode/chainnodeadd.component.html: -------------------------------------------------------------------------------- 1 |
2 | border_color 3 |

{{isNew?'新增链节点参数配置':'修改链节点参数配置'}}

4 | 7 |
8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 必须输入名称! 16 | 17 | 18 | 19 | {{nameCtrl.getError('name')}} 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
38 |
39 |
40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/app/auth/config/distributednode/chainnodeadd.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Inject } from '@angular/core'; 2 | import {MatDialogRef, MAT_DIALOG_DATA} from '@angular/material'; 3 | import { chainnodeConfig } from './chainnodeConfig'; 4 | import { ConfigService } from '../../../services/config.service'; 5 | import {Form, FormBuilder, FormControl, Validators} from '@angular/forms'; 6 | 7 | @Component({ 8 | selector: 'app-distributednodeadd', 9 | templateUrl: './chainnodeadd.component.html', 10 | styleUrls: ['./distributednodeadd.component.css'] 11 | }) 12 | export class ChainnodeaddComponent implements OnInit { 13 | 14 | /*表单验证*/ 15 | baseForm; 16 | nameValidator(control: FormControl): any{ 17 | 18 | /*仅允许英文字母、数字和下划线*/ 19 | const nameReg = /^[\u4E00-\u9FA5a-zA-Z0-9_]{3,20}$/ 20 | const result = nameReg.test(control.value); 21 | return result ? null : { name: '汉字、英文字母、数字、下划线组成,3-20位!' }; 22 | 23 | } 24 | 25 | isNew=true; 26 | row:chainnodeConfig; 27 | options; 28 | 29 | constructor( 30 | private _sheetRef: MatDialogRef, 31 | // /*Inject装饰器*/ 32 | @Inject(MAT_DIALOG_DATA) public data: any, 33 | private _fb:FormBuilder, 34 | private _config: ConfigService 35 | ) { 36 | 37 | this.isNew = (data.action==='new'); 38 | if (data.data) { 39 | this.row = new chainnodeConfig(data.data); 40 | } else { 41 | this.row = new chainnodeConfig(); 42 | } 43 | 44 | } 45 | 46 | ngOnInit() { 47 | this.buildForm(); 48 | 49 | } 50 | 51 | get nameCtrl():FormControl{ 52 | return this.baseForm.get('name') as FormControl; 53 | } 54 | 55 | buildForm(){ 56 | this.baseForm =this._fb.group({ 57 | name : [this.row.name,[Validators.required,this.nameValidator]], 58 | nodename :[this.row.nodename], 59 | pubkey : [this.row.pubkey], 60 | nodeid : [this.row.nodeid], 61 | addr : [this.row.addr], 62 | powerid : [this.row.powerid] 63 | }); 64 | if(!this.isNew){ 65 | this.nameCtrl.disable(); 66 | } 67 | } 68 | 69 | updateModel() { 70 | let val = this.baseForm.getRawValue(); 71 | this.row = Object.assign(this.row, val); 72 | } 73 | 74 | doSave() { 75 | this.updateModel(); 76 | this._config.addConfig('tmnode',this.row).subscribe(data => { 77 | this._sheetRef.close(this.row); 78 | }) 79 | } 80 | 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/app/auth/config/distributednode/distributednode.component.css: -------------------------------------------------------------------------------- 1 | tr.example-detail-row { 2 | height: 0; 3 | } 4 | 5 | .example-element-row td { 6 | border-bottom-width: 0; 7 | } 8 | 9 | .example-element-detail { 10 | overflow: hidden; 11 | display: flex; 12 | } 13 | 14 | th.button{ 15 | text-align: right; 16 | } 17 | 18 | button.refresh{ 19 | margin-left: 20px; 20 | } 21 | 22 | table.mat-table th.mat-header-cell{ 23 | background-color: rgba(0,0,0,.04); 24 | } 25 | -------------------------------------------------------------------------------- /src/app/auth/config/distributednode/distributednodeConfig.ts: -------------------------------------------------------------------------------- 1 | export class distributednodeConfig { 2 | name:string; 3 | dir:String; 4 | chainid:String; 5 | abcifile:String; 6 | power:String; 7 | abciserv:String; 8 | rpcserv:String; 9 | p2pserv:String; 10 | ipfsserv:String; 11 | ipfsapi:String; 12 | ipfsgw:String; 13 | constructor(data=undefined) { 14 | this.name = ''; 15 | this.dir = ''; 16 | this.chainid = ''; 17 | this.abcifile = ''; 18 | this.power = ''; 19 | this.abciserv = ''; 20 | this.rpcserv = ''; 21 | this.p2pserv = ''; 22 | this.ipfsserv = ''; 23 | this.ipfsapi = ''; 24 | this.ipfsgw = ''; 25 | if (data!=undefined) { 26 | for (let k in data) { 27 | this[k] = data[k]; 28 | } 29 | } 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /src/app/auth/config/distributednode/distributednodeadd.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemo-crypto/angular6-material/e387fd39877dd833a171ba3e9227fb2d5b909957/src/app/auth/config/distributednode/distributednodeadd.component.css -------------------------------------------------------------------------------- /src/app/auth/config/distributednode/distributednodeadd.component.html: -------------------------------------------------------------------------------- 1 |
2 | border_color 3 |

{{isNew?'新增系统参数配置':'修改系统参数配置'}}

4 | 7 |
8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 必须输入名称! 16 | 17 | 18 | 19 | {{nameCtrl.getError('name')}} 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
53 |
54 |
55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/app/auth/config/distributednode/distributednodeadd.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Inject } from '@angular/core'; 2 | import {MatDialogRef, MAT_DIALOG_DATA} from '@angular/material'; 3 | import { distributednodeConfig } from './distributednodeConfig'; 4 | import { ConfigService } from '../../../services/config.service'; 5 | import {Form, FormBuilder, FormControl, Validators} from '@angular/forms'; 6 | 7 | @Component({ 8 | selector: 'app-distributednodeadd', 9 | templateUrl: './distributednodeadd.component.html', 10 | styleUrls: ['./distributednodeadd.component.css'] 11 | }) 12 | export class DistributednodeaddComponent implements OnInit { 13 | 14 | /*表单验证*/ 15 | baseForm; 16 | nameValidator(control: FormControl): any{ 17 | 18 | /*仅允许英文字母、数字和下划线*/ 19 | const nameReg = /^[\u4E00-\u9FA5a-zA-Z0-9_]{3,20}$/ 20 | const result = nameReg.test(control.value); 21 | return result ? null : { name: '汉字、英文字母、数字、下划线组成,3-20位!' }; 22 | 23 | } 24 | 25 | isNew=true; 26 | row:distributednodeConfig; 27 | options; 28 | 29 | constructor( 30 | private _sheetRef: MatDialogRef, 31 | // /*Inject装饰器*/ 32 | @Inject(MAT_DIALOG_DATA) public data: any, 33 | private _fb:FormBuilder, 34 | private _config: ConfigService 35 | ) { 36 | 37 | this.isNew = (data.action==='new'); 38 | if (data.data) { 39 | this.row = new distributednodeConfig(data.data); 40 | } else { 41 | this.row = new distributednodeConfig(); 42 | } 43 | 44 | } 45 | 46 | ngOnInit() { 47 | this.buildForm(); 48 | 49 | } 50 | 51 | get nameCtrl():FormControl{ 52 | return this.baseForm.get('name') as FormControl; 53 | } 54 | 55 | buildForm(){ 56 | this.baseForm =this._fb.group({ 57 | name : [this.row.name,[Validators.required,this.nameValidator]], 58 | dir :[this.row.dir], 59 | chainid : [this.row.chainid], 60 | abcifile : [this.row.abcifile], 61 | power : [this.row.power], 62 | abciserv : [this.row.abciserv], 63 | rpcserv : [this.row.rpcserv], 64 | p2pserv : [this.row.p2pserv], 65 | ipfsserv : [this.row.ipfsserv], 66 | ipfsapi : [this.row.ipfsapi], 67 | ipfsgw : [this.row.ipfsgw] 68 | }); 69 | if(!this.isNew){ 70 | this.nameCtrl.disable(); 71 | } 72 | } 73 | 74 | updateModel() { 75 | let val = this.baseForm.getRawValue(); 76 | this.row = Object.assign(this.row, val); 77 | } 78 | 79 | 80 | doSave() { 81 | this.updateModel(); 82 | this._config.addConfig('tmconf',this.row).subscribe(data => { 83 | this._sheetRef.close(this.row); 84 | }) 85 | } 86 | 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/app/auth/config/mdbserv/mdbserv-edit.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemo-crypto/angular6-material/e387fd39877dd833a171ba3e9227fb2d5b909957/src/app/auth/config/mdbserv/mdbserv-edit.component.css -------------------------------------------------------------------------------- /src/app/auth/config/mdbserv/mdbserv-edit.component.html: -------------------------------------------------------------------------------- 1 |
2 | border_color 3 |

{{isNew?'新增区块链接口服务配置':'修改区块链接口服务配置'}}

4 | 7 |
8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 必须输入名称! 16 | 17 | 18 | 19 | {{nameCtrl.getError('name')}} 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 | 36 |
37 | {{singleOption.value.name}} 38 |
39 |
40 |
41 |
42 |
43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/app/auth/config/mdbserv/mdbserv-edit.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Inject } from '@angular/core'; 2 | import {MatDialogRef, MAT_DIALOG_DATA} from '@angular/material'; 3 | import { MDBSERVConfig } from './mdbservConfig'; 4 | import { ConfigService } from '../../../services/config.service'; 5 | import {Form, FormArray, FormBuilder, FormControl, Validators} from '@angular/forms'; 6 | 7 | @Component({ 8 | selector: 'app-mdbserv-edit', 9 | templateUrl: './mdbserv-edit.component.html', 10 | styleUrls: ['./mdbserv-edit.component.css'] 11 | }) 12 | 13 | export class MdbservEditComponent implements OnInit { 14 | 15 | /*表单验证*/ 16 | baseForm; 17 | nameValidator(control: FormControl): any{ 18 | /*仅允许英文字母、数字和下划线*/ 19 | const nameReg = /^[\u4E00-\u9FA5a-zA-Z0-9_]{3,20}$/ 20 | const result = nameReg.test(control.value); 21 | return result ? null : { name: '汉字、英文字母、数字、下划线组成,3-20位!' }; 22 | } 23 | 24 | isNew=true; 25 | row:MDBSERVConfig; 26 | options; 27 | constructor( 28 | private _sheetRef: MatDialogRef, 29 | // /*Inject装饰器*/ 30 | @Inject(MAT_DIALOG_DATA) public data: any, 31 | private _fb: FormBuilder, 32 | private _config: ConfigService 33 | ) { 34 | this.isNew = (data.action==='new'); 35 | if (data.data) { 36 | this.row = new MDBSERVConfig(data.data); 37 | } else { 38 | this.row = new MDBSERVConfig(); 39 | } 40 | } 41 | 42 | ngOnInit() { 43 | this.buildForm(); 44 | } 45 | 46 | get nameCtrl():FormControl{ 47 | return this.baseForm.get('name') as FormControl; 48 | } 49 | 50 | buildForm(){ 51 | this.baseForm = this._fb.group({ 52 | name : [this.row.name,[Validators.required,this.nameValidator]], 53 | sertx: [this.row.sertx], 54 | clitx: [this.row.clitx], 55 | pwd: [this.row.pwd], 56 | dbstr: [this.row.dbstr], 57 | multipleOptions : [this._fb.array([])] 58 | }); 59 | let multipleOptions = ['USERAUTH']; 60 | this.setMultipleOptions(multipleOptions, this.row.options); 61 | if(!this.isNew){ 62 | this.nameCtrl.disable(); 63 | } 64 | } 65 | 66 | setMultipleOptions(multipleOptions:string[],values='') { 67 | 68 | const multipleOptionsFGs = multipleOptions.map(singleOption =>{ 69 | let obj={name: singleOption,checked:(values.indexOf(singleOption)>=0)}; 70 | return this._fb.group(obj) 71 | }); 72 | 73 | const singleOptionFormArray = this._fb.array(multipleOptionsFGs); 74 | this.baseForm.setControl('multipleOptions', singleOptionFormArray); 75 | } 76 | 77 | get multipleOptions():FormArray{ 78 | return this.baseForm.get('multipleOptions') as FormArray; 79 | } 80 | 81 | updateModel() { 82 | let val = this.baseForm.getRawValue(); 83 | this.row.name = val.name; 84 | this.row.sertx = val.sertx; 85 | this.row.clitx = val.clitx; 86 | this.row.pwd = val.pwd; 87 | this.row.dbstr = val.dbstr; 88 | let array = []; 89 | val.multipleOptions.forEach(option => { 90 | if( option.checked == true){ 91 | array.push(option.name); 92 | } 93 | }); 94 | if(array.length == 0){ 95 | this.row.options = ''; 96 | }else if(array.length == 1){ 97 | this.row.options = array[0]; 98 | }else if(array.length > 1){ 99 | let str = ''; 100 | for(var i = 0; i < array.length; i++){ 101 | str += array[i] + '|'; 102 | } 103 | if(str.length > 0 ){ 104 | str = str.substr(0,str.length - 1); 105 | } 106 | this.row.options = str; 107 | } 108 | } 109 | 110 | doSave() { 111 | this.updateModel(); 112 | this._config.addConfig('mdbserv',this.row).subscribe(data => { 113 | this._sheetRef.close(this.row); 114 | }) 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/app/auth/config/mdbserv/mdbserv.component.css: -------------------------------------------------------------------------------- 1 | tr.example-detail-row { 2 | height: 0; 3 | } 4 | 5 | 6 | .example-element-row td { 7 | border-bottom-width: 0; 8 | } 9 | 10 | .example-element-detail { 11 | overflow: hidden; 12 | display: flex; 13 | } 14 | 15 | th.button{ 16 | text-align: right; 17 | } 18 | 19 | button.refresh{ 20 | margin-left: 20px; 21 | } 22 | 23 | table.mat-table th.mat-header-cell{ 24 | background-color: rgba(0,0,0,.04); 25 | } 26 | -------------------------------------------------------------------------------- /src/app/auth/config/mdbserv/mdbserv.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {MatBottomSheet, MatDialog} from '@angular/material'; 3 | import {animate, state, style, transition, trigger} from '@angular/animations'; 4 | 5 | import { RestfulService } from '../../../services/restful.service'; 6 | import { McConfirmService } from '../../../modules/mc-confirm/mc-confirm.module'; 7 | import { ConfigService } from '../../../services/config.service'; 8 | import { MdbservEditComponent } from './mdbserv-edit.component'; 9 | 10 | @Component({ 11 | selector: 'app-mdbserv', 12 | templateUrl: './mdbserv.component.html', 13 | styleUrls: ['./mdbserv.component.css'], 14 | animations: [ 15 | trigger('detailExpand', [ 16 | state('collapsed', style({height: '0px', minHeight: '0', display: 'none'})), 17 | state('expanded', style({height: '*'})), 18 | transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')), 19 | ]), 20 | ], 21 | }) 22 | export class MdbservComponent implements OnInit { 23 | 24 | columnsToDisplay = ['name', 'sertx', 'clitx', 'pwd', 'dbstr', 'options','status','action']; 25 | data=[]; 26 | expandedRow; 27 | configStatusMap={}; 28 | constructor( 29 | private _matDialog: MatDialog, 30 | private _restful: RestfulService, 31 | private _config: ConfigService, 32 | private _confirm: McConfirmService 33 | ) { } 34 | 35 | ngOnInit() { 36 | this.getConfigs(); 37 | } 38 | 39 | getConfigs() { 40 | this._config.getConfigs('mdbserv').subscribe(data => { 41 | /*临时处理options "NULL"*/ 42 | for(let obj of data){ 43 | if(obj.options == " NULL"){ 44 | obj.options = ''; 45 | } 46 | } 47 | this.data = data; 48 | this.data.forEach(conf => { 49 | this.getConfigStatus(conf.name); 50 | }); 51 | }) 52 | } 53 | 54 | getConfigStatus(name) { 55 | this._config.getConfigStatus('mdbserv',name).subscribe(data => { 56 | this.configStatusMap[name]=data; 57 | console.log(data) 58 | }); 59 | 60 | } 61 | 62 | configStatus(name) { 63 | if (this.configStatusMap[name]==undefined) return ''; 64 | return this.configStatusMap[name]['status']; 65 | } 66 | 67 | addConfig() { 68 | const dialogRef = this._matDialog.open(MdbservEditComponent,{ 69 | width: '600px', 70 | disableClose: true, 71 | data:{action:'new'} 72 | }); 73 | dialogRef.afterClosed().subscribe(result => { 74 | if (result) { 75 | this.getConfigs(); 76 | } 77 | }); 78 | } 79 | 80 | updateConfig(cf) { 81 | const dialogRef = this._matDialog.open(MdbservEditComponent,{ 82 | width: '600px', 83 | disableClose: true, 84 | data:{action:'update',data:cf} 85 | }); 86 | dialogRef.afterClosed().subscribe(result => { 87 | if (result) { 88 | this.getConfigs(); 89 | } 90 | }); 91 | } 92 | 93 | removeConfig(cf) { 94 | this._confirm.confirm({ 95 | message:'是否真正删除配置项['+cf.name+']?', 96 | onAccept:()=>{ 97 | this._config.removeConfig('mdbserv',cf.name).subscribe(data => { 98 | if (data) { 99 | this._confirm.alert('配置项['+cf.name+']已经删除'); 100 | this.getConfigs(); 101 | } else { 102 | this._confirm.alert('配置项['+cf.name+']删除出错,请稍后再试',) 103 | } 104 | }) 105 | } 106 | }) 107 | } 108 | 109 | turnConfigOn(name) { 110 | this._confirm.confirm({ 111 | message:'是否真正启用配置项['+name+']?', 112 | onAccept:()=>{ 113 | this._config.turnConfigOn('mdbserv',name).subscribe(data => { 114 | if (data) { 115 | this._confirm.alert('配置项['+name+']已经启用'); 116 | this.getConfigs(); 117 | } else { 118 | this._confirm.alert('配置项['+name+']启用出错,请稍后再试',) 119 | } 120 | }) 121 | } 122 | }) 123 | } 124 | 125 | turnConfigOff(name) { 126 | this._confirm.confirm({ 127 | message:'是否真正停用配置项['+name+']?', 128 | onAccept:()=>{ 129 | this._config.turnConfigOff('mdbserv',name).subscribe(data => { 130 | if (data) { 131 | this._confirm.alert('配置项['+name+']已经停用'); 132 | this.getConfigs(); 133 | } else { 134 | this._confirm.alert('配置项['+name+']停用出错,请稍后再试',) 135 | } 136 | }) 137 | } 138 | }) 139 | } 140 | 141 | toggleConfigDetail(cf) { 142 | if (this.expandedRow == cf) { 143 | this.expandedRow = undefined; 144 | } else { 145 | this.expandedRow = cf; 146 | } 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /src/app/auth/config/mdbserv/mdbservConfig.ts: -------------------------------------------------------------------------------- 1 | export class MDBSERVConfig { 2 | name:string; 3 | sertx:string; 4 | dbstr:string; 5 | options:string; //(USERAUTHL) 6 | clitx:string; 7 | pwd:string; 8 | constructor(data=undefined) { 9 | this.name = ''; 10 | this.sertx = ''; 11 | this.dbstr = ''; 12 | this.clitx = ''; 13 | this.options = ''; 14 | this.pwd = ''; 15 | if (data!=undefined) { 16 | for (let k in data) { 17 | this[k] = data[k]; 18 | } 19 | } 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /src/app/auth/config/mdbuser/mdbuser-edit.component.css: -------------------------------------------------------------------------------- 1 | button.cancel{ 2 | margin-right: 10px; 3 | } 4 | 5 | div.button-row{ 6 | text-align: right; 7 | } 8 | -------------------------------------------------------------------------------- /src/app/auth/config/mdbuser/mdbuser-edit.component.html: -------------------------------------------------------------------------------- 1 |
2 | border_color 3 |

{{isNew?'新增用户配置':'修改用户配置'}}

4 | 7 |
8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 必须输入名称! 16 | 17 | 18 | 19 | {{nameCtrl.getError('name')}} 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 |
30 |
31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/app/auth/config/mdbuser/mdbuser-edit.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Inject } from '@angular/core'; 2 | import {MatDialogRef, MAT_DIALOG_DATA} from '@angular/material'; 3 | import { MDBUSERConfig } from './mdbuserConfig'; 4 | import { ConfigService } from '../../../services/config.service'; 5 | import {FormBuilder, FormControl, Validators} from "@angular/forms"; 6 | 7 | @Component({ 8 | selector: 'app-mdbuser-edit', 9 | templateUrl: './mdbuser-edit.component.html', 10 | styleUrls: ['./mdbuser-edit.component.css'] 11 | }) 12 | export class MdbuserEditComponent implements OnInit { 13 | 14 | /*表单验证*/ 15 | baseForm; 16 | nameValidator(control: FormControl): any{ 17 | /*仅允许英文字母、数字和下划线*/ 18 | const nameReg = /^[\u4E00-\u9FA5a-zA-Z0-9_]{3,20}$/ 19 | const result = nameReg.test(control.value); 20 | return result ? null : { name: '汉字、英文字母、数字、下划线组成,3-20位!' }; 21 | } 22 | 23 | isNew=true; 24 | row:MDBUSERConfig; 25 | options; 26 | constructor( 27 | private _sheetRef: MatDialogRef, 28 | // /*Inject装饰器*/ 29 | @Inject(MAT_DIALOG_DATA) public data: any, 30 | private _fb: FormBuilder, 31 | private _config: ConfigService 32 | ) { 33 | this.isNew = (data.action==='new'); 34 | if (data.data) { 35 | this.row = new MDBUSERConfig(data.data); 36 | } else { 37 | this.row = new MDBUSERConfig(); 38 | } 39 | } 40 | 41 | ngOnInit() { 42 | this.buildForm(); 43 | } 44 | 45 | get nameCtrl():FormControl{ 46 | return this.baseForm.get('name') as FormControl; 47 | } 48 | 49 | buildForm(){ 50 | this.baseForm = this._fb.group({ 51 | name : [this.row.name,[Validators.required,this.nameValidator]], 52 | pwd: [this.row.pwd], 53 | notify: [this.row.notify] 54 | }); 55 | if(!this.isNew){ 56 | this.nameCtrl.disable(); 57 | } 58 | } 59 | 60 | updateModel() { 61 | let val = this.baseForm.getRawValue(); 62 | this.row = Object.assign(this.row, val); 63 | } 64 | 65 | 66 | doSave() { 67 | this.updateModel(); 68 | this._config.saveOrUpdateManagement('user',this.row).subscribe(data => { 69 | this._sheetRef.close(this.row); 70 | }) 71 | } 72 | 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/app/auth/config/mdbuser/mdbuser.component.css: -------------------------------------------------------------------------------- 1 | tr.example-detail-row { 2 | height: 0; 3 | } 4 | 5 | .example-element-row td { 6 | border-bottom-width: 0; 7 | } 8 | 9 | .example-element-detail { 10 | overflow: hidden; 11 | display: flex; 12 | } 13 | 14 | th.button{ 15 | text-align: right; 16 | } 17 | 18 | button.refresh{ 19 | margin-left: 20px; 20 | } 21 | 22 | button.reset{ 23 | margin-right: 20px; 24 | } 25 | 26 | table.mat-table th.mat-header-cell{ 27 | background-color: rgba(0,0,0,.04); 28 | } 29 | -------------------------------------------------------------------------------- /src/app/auth/config/mdbuser/mdbuserConfig.ts: -------------------------------------------------------------------------------- 1 | export class MDBUSERConfig { 2 | name:string; 3 | pwd:string; 4 | notify:string; 5 | constructor(data=undefined) { 6 | this.name = ''; 7 | this.pwd = ''; 8 | this.notify = ''; 9 | if (data!=undefined) { 10 | for (let k in data) { 11 | this[k] = data[k]; 12 | } 13 | } 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /src/app/auth/lazyloader.routes.ts: -------------------------------------------------------------------------------- 1 | import { RouterModule, Routes } from '@angular/router'; 2 | import { AuthComponent } from './auth.component'; 3 | import { OverviewComponent } from './overview/overview.component'; 4 | import { UsersComponent } from './system/users/users.component'; 5 | import { AboutusComponent } from './system/aboutus/aboutus.component'; 6 | import { ABCIComponent } from './config/abci/abci.component'; 7 | import { MdbservComponent } from './config/mdbserv/mdbserv.component'; 8 | import { MdbuserComponent } from './config/mdbuser/mdbuser.component'; 9 | import {DistributednodeComponent} from './config/distributednode/distributednode.component'; 10 | import { BlockComponent } from './search/block/block.component'; 11 | import { AssetsComponent } from './search/assets/assets.component'; 12 | import {AssetsDealComponent} from './search/assets-deal/assets-deal.component'; 13 | import {BlockDealComponent} from './search/block-deal/block-deal.component'; 14 | import { BlockDealDetailComponent } from './search/block-deal-detail/block-deal-detail.component' 15 | 16 | export const appRoutes: Routes = [{ 17 | path: '', component: AuthComponent, children: [ 18 | { path: 'overview', component: OverviewComponent }, 19 | { path: 'system/users', component: UsersComponent }, 20 | { path: 'system/aboutus', component: AboutusComponent}, 21 | { path: 'config/abci', component: ABCIComponent }, 22 | { path: 'config/mdbserv', component: MdbservComponent}, 23 | { path: 'config/mdbuser', component: MdbuserComponent}, 24 | { path: 'config/distributednode', component: DistributednodeComponent}, 25 | { path: 'search/block', component: BlockComponent }, 26 | { path: 'search/assets', component: AssetsComponent }, 27 | { path: 'search/assets-deal/:id', component: AssetsDealComponent}, 28 | { path: 'search/block-deal/:id', component: BlockDealComponent}, 29 | { path: 'search/block-deal/block-deal-detail', component: BlockDealDetailComponent}, 30 | 31 | /* { path: 'material-widgets', loadChildren: '../material-widgets/material-widgets.module#MaterialWidgetsModule' }, 32 | { path: 'tables', loadChildren: '../tables/tables.module#TablesModule' }, 33 | { path: 'maps', loadChildren: '../maps/maps.module#MapsModule' }, 34 | { path: 'charts', loadChildren: '../charts/charts.module#ChartsModule' }, 35 | // { path: 'chats', loadChildren: '../chats/chat.module#ChatsModule' }, // fix this 36 | //{ path: 'mail', loadChildren: '../mail/mail.module#MailModule' }, // fix this 37 | { path: 'pages', loadChildren: '../pages/pages.module#PagesModule' }, 38 | { path: 'forms', loadChildren: '../forms/forms.module#FormModule' }, //fix this 39 | { path: 'guarded-routes', loadChildren: '../guarded-routes/guarded-routes.module#GuardedRoutesModule' }, 40 | // { path: 'editor', loadChildren: '../editor/editor.module#EditorModule' }, 41 | { path: 'scrumboard', loadChildren: '../scrumboard/scrumboard.module#ScrumboardModule' }, */ 42 | ] 43 | }]; 44 | -------------------------------------------------------------------------------- /src/app/auth/overview/overview-chart1/overview-chart1.component.css: -------------------------------------------------------------------------------- 1 | div.dealNumber{ 2 | margin-bottom: -22px; 3 | margin-left: 44px; 4 | } 5 | -------------------------------------------------------------------------------- /src/app/auth/overview/overview-chart1/overview-chart1.component.html: -------------------------------------------------------------------------------- 1 |
{{curValue}}
2 |
3 | 4 | -------------------------------------------------------------------------------- /src/app/auth/overview/overview-chart1/overview-chart1.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {ConfigService} from "../../../services/config.service"; 3 | 4 | @Component({ 5 | selector: 'app-overview-chart1', 6 | templateUrl: './overview-chart1.component.html', 7 | styleUrls: ['./overview-chart1.component.css'] 8 | }) 9 | export class OverviewChart1Component implements OnInit { 10 | options: any; 11 | updateOptions: any; 12 | curValue: any; 13 | 14 | private data: any; 15 | private timer: any; 16 | 17 | constructor( 18 | private _config: ConfigService, 19 | ) { } 20 | 21 | ngOnInit() { 22 | // 初始化数据赋值 23 | this.data = []; 24 | this.data.push(this.getChartValue(new Date(), 0)); 25 | // initialize chart options: 26 | this.options = { 27 | title: { 28 | text: '' 29 | }, 30 | tooltip: { 31 | trigger: 'axis', 32 | formatter: (params) => { 33 | params = params[0]; 34 | return '时间:' +params.axisValueLabel + '
' + '交易数:' + params.value[1]; 35 | }, 36 | axisPointer: { 37 | animation: false 38 | } 39 | }, 40 | xAxis: { 41 | type: 'time', 42 | splitLine: { 43 | show: true 44 | } 45 | }, 46 | yAxis: { 47 | type: 'value', 48 | boundaryGap: [0, '100%'], 49 | splitLine: { 50 | show: true 51 | } 52 | }, 53 | series: [{ 54 | name: 'Mocking Data', 55 | type: 'line', 56 | showSymbol: false, 57 | hoverAnimation: false, 58 | data: this.data 59 | }] 60 | }; 61 | 62 | // Mock dynamic data: 63 | this.timer = setInterval(() => { 64 | /*4秒钟请求一次,请求20次= 80秒后图平推*/ 65 | if (this.data.length > 20) { 66 | this.data.splice(0, (this.data.length - 20)); 67 | } 68 | this.getDealSecond(); 69 | }, 4000); 70 | 71 | 72 | } 73 | /*******************查询每秒钟交易数量*************/ 74 | /*mdb-cli mdbserv_show*/ 75 | getDealSecond() { 76 | this._config.getDealSecond('').subscribe( value => { 77 | this.curValue = value; 78 | let v = parseFloat(value); 79 | /*当后台返回为空时,图停止*/ 80 | if(value != '') { 81 | this.data.push(this.getChartValue(new Date(), v )); 82 | } 83 | this.updateOptions = { 84 | series: [{ 85 | data: this.data 86 | }] 87 | }; 88 | }) 89 | } 90 | 91 | getChartValue(d, v) { 92 | return { 93 | name: d.toString(), 94 | value: [ 95 | d, 96 | v 97 | ] 98 | } 99 | } 100 | ngOnDestroy() { 101 | clearInterval(this.timer); 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/app/auth/overview/overview.component.css: -------------------------------------------------------------------------------- 1 | div.search_type{ 2 | width: 80%; 3 | } 4 | div.search_type .button{ 5 | text-align: center; 6 | } 7 | div.search_type .button button{ 8 | border-radius: 5px; 9 | } 10 | div.search_type mat-button-toggle-group{ 11 | margin-bottom: 18px; 12 | } 13 | 14 | 15 | mat-button-toggle.active{ 16 | background-color: #e0e0e0; 17 | color: #000000; 18 | } 19 | 20 | div.type{ 21 | /*background: -webkit-gradient(linear, 0% 0%, 0% 100%,from(#61618d), to(#f6f6f8));*/ 22 | border-top: 20px solid #227aac; 23 | background: #fff; 24 | border-radius: 5px; 25 | box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.26); 26 | width: 95%; 27 | height: 74%; 28 | } 29 | 30 | div.type .type_info{ 31 | width: 100%; 32 | text-align: left; 33 | } 34 | 35 | div.type img{ 36 | width: 64px; 37 | } 38 | 39 | div.type_info span{ 40 | font-size: 21px; 41 | font-weight: 600; 42 | } 43 | 44 | div.more_search span.more{ 45 | font-size: 15px; 46 | } 47 | 48 | div.three_list{ 49 | background: #fff; 50 | border-radius: 5px; 51 | box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.26); 52 | width: 96%; 53 | height: 100%; 54 | } 55 | 56 | div.two_list{ 57 | background: #fff; 58 | border-radius: 5px; 59 | box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.26); 60 | width: 97%; 61 | height: 100%; 62 | margin-top: 30px; 63 | } 64 | 65 | mat-card.list{ 66 | width: 100%; 67 | height:100%; 68 | } 69 | 70 | 71 | /*滚动表单css*/ 72 | .example-container { 73 | position: relative; 74 | } 75 | 76 | .example-table-container { 77 | position: relative; 78 | max-height: 300px; 79 | overflow: auto; 80 | } 81 | 82 | table { 83 | width: 100%; 84 | } 85 | 86 | 87 | /*mat-list-最新交易信息*/ 88 | mat-list.deal_obj tr td:nth-child(1){ 89 | width: 115px; 90 | font-size: 14px; 91 | font-weight: 600; 92 | } 93 | 94 | mat-list.deal_obj tr td:nth-child(2){ 95 | font-size: 14px; 96 | word-break: break-all; 97 | } 98 | 99 | mat-list.deal_obj mat-list-item:hover{ 100 | background: #f5e9d6; 101 | } 102 | 103 | div.list_title{ 104 | padding-left: 20px; 105 | margin-top: 20px; 106 | text-align: left; 107 | font-size: 16px; 108 | font-weight: bold; 109 | } 110 | /*Echart-图标-css*/ 111 | .demo-chart { 112 | height: 300px; 113 | } 114 | 115 | /************环绕效果************/ 116 | .ribbon-lanren-green { 117 | height: 88px; 118 | overflow: hidden; 119 | position: absolute; 120 | } 121 | .ribbon-green { 122 | height: 15px; 123 | -webkit-transform: rotate(135deg); 124 | -moz-transform: rotate(135deg); 125 | -ms-transform: rotate(135deg); 126 | -o-transform: rotate(135deg); 127 | position: relative; 128 | left: -43px; 129 | top: 22px; 130 | width: 99px; 131 | background-color: #227aac; 132 | box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3); 133 | } 134 | /************end************/ 135 | -------------------------------------------------------------------------------- /src/app/auth/search/assets-deal/assets-deal.component.css: -------------------------------------------------------------------------------- 1 | /*详情展示*/ 2 | div.blockDetail mat-form-field{ 3 | padding-right: 15px; 4 | } 5 | 6 | mat-grid-tile .two_list{ 7 | width: 100%; 8 | padding-right: 25px; 9 | padding-left: 25px; 10 | } 11 | 12 | /* filter bar */ 13 | .table-filter-bar { 14 | padding: 5px 24px; 15 | margin-top: 10px!important; 16 | } 17 | .table-filter-bar .filter-bar-header { 18 | padding-right: 24px; 19 | border-right: 1px solid rgba(0,0,0,.12); 20 | } 21 | table.mat-table th.mat-header-cell{ 22 | background-color: rgba(0,0,0,.04); 23 | border-top: 1px solid rgba(0, 0, 0, 0.12); 24 | } 25 | 26 | div.jsonShow { 27 | background: #f0f0f0; 28 | border: 1px solid #e0e0e0; 29 | min-height: 200px; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/app/auth/search/assets/assets.component.css: -------------------------------------------------------------------------------- 1 | /* filter bar */ 2 | .table-filter-bar { 3 | padding: 5px 24px; 4 | margin-top: 10px!important; 5 | } 6 | .table-filter-bar .filter-bar-header { 7 | padding-right: 24px; 8 | border-right: 1px solid rgba(0,0,0,.12); 9 | } 10 | .table-filter-bar + table.mat-table th.mat-header-cell{ 11 | background-color: rgba(0,0,0,.04); 12 | border-top: 1px solid rgba(0, 0, 0, 0.12); 13 | } 14 | -------------------------------------------------------------------------------- /src/app/auth/search/assets/assets.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | home 5 |
6 |
7 | 系统概览 8 |
9 |
10 | keyboard_arrow_right 11 |
12 |
13 | 资产信息 14 |
15 |
16 | keyboard_arrow_right 17 |
18 |
19 | 20 | 21 |
22 |
loyalty
23 |
资产列表
24 |
25 | 26 | 27 |
28 |
29 | search 30 |
31 | 51 | 52 |
53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | database 69 | 70 | 71 | 72 | 73 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 102 | 105 | 106 |
资产ID{{row.assetid}}创建资产交易ID{{row.createtx}}创建资产时间{{row.createtm}}资产所在区块ID{{row.firstheigh}}最后一次修改资产时间{{row.lasttm}}最后一笔交易用户数据哈希值{{row.lastrdhash}} 100 | 101 | 103 | 104 |
107 |
108 | 109 | 115 | 116 |
117 | -------------------------------------------------------------------------------- /src/app/auth/search/assets/assets.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {FormBuilder, Validators} from '@angular/forms'; 3 | import {ConfigService} from '../../../services/config.service'; 4 | import {Router} from '@angular/router'; 5 | 6 | @Component({ 7 | selector: 'app-assets', 8 | templateUrl: './assets.component.html', 9 | styleUrls: ['./assets.component.css'] 10 | }) 11 | export class AssetsComponent implements OnInit { 12 | 13 | searchForm; 14 | /*资产data*/ 15 | private assetsData:Array; 16 | /*资产表名*/ 17 | assetsNames = []; 18 | /*当前页面选中的资产表名*/ 19 | assetsName; 20 | /*资产列表--字段模板*/ 21 | displayedColumn_assets = ['assetid', 'createtx', 'createtm','firstheigh','lasttm','lastrdhash','action']; 22 | page = { 23 | totalElements: 0, 24 | pageNum: 0, 25 | pageSize: 10 26 | }; 27 | /*接口查询条件格式-*/ 28 | limitJson = { 29 | limit:10, //取10条 30 | skip:0 //从多少条开始取,初始化默认从1条开始 31 | }; 32 | /*接口查询条件--根据资产id-*/ 33 | limitJsonId = { 34 | assetid: '' 35 | }; 36 | 37 | constructor( 38 | private _fb: FormBuilder, 39 | private _config: ConfigService, 40 | private _router: Router, 41 | ) { 42 | } 43 | 44 | ngOnInit() { 45 | this.buildForm(); 46 | this.getAssetsNames(); 47 | } 48 | 49 | buildForm() { 50 | this.searchForm = this._fb.group({ 51 | assetsTableName:['',[Validators.required]], 52 | assetsId:[''] 53 | }); 54 | } 55 | 56 | /*选择条件点击查询--.*/ 57 | doSearchFor() { 58 | //切换查询时候初始化值 59 | this.page.pageNum = 0; 60 | this.limitJson.limit = 10; 61 | this.limitJson.skip = 0; 62 | this.limitJsonId.assetid = ''; 63 | //获取表单上的查询条件 64 | const query: any = {}; 65 | const val = this.searchForm.getRawValue(); 66 | if(val.assetsTableName != '') { 67 | this.assetsName = val.assetsTableName; 68 | if (val.assetsId != '') { 69 | this.limitJsonId.assetid = val.assetsId; 70 | } 71 | this.getAssetsList(); 72 | } 73 | 74 | return query; 75 | } 76 | 77 | /*查询资产表名*/ 78 | getAssetsNames() { 79 | /*mdb-cli mongotab NULL mdb*/ 80 | this._config.getAssetsNames('NULL mdb').subscribe( data => { 81 | data.forEach( rowData => { 82 | this.assetsNames.push({ 83 | value: rowData 84 | }); 85 | }) 86 | if( this.assetsNames.length > 0) { 87 | /*查询表单赋值*/ 88 | this.searchForm = this._fb.group({ 89 | assetsTableName:[this.assetsNames[0].value,[Validators.required]], 90 | assetsId:[''] 91 | }); 92 | this.assetsName = this.assetsNames[0].value; 93 | this.getAssetsList(); 94 | } 95 | }) 96 | } 97 | 98 | getAssetsList(){ 99 | /* 命令行:mdb-cli mongoget NULL mdb 表名picc_user NULL NULL '{"limit":10,"skip":0}' 100 | * mdb-cli mongoget NULL mdb picc_user '{"assetid":6634805563949581128}' NULL '{"limit":10}' 101 | */ 102 | // limitJson转为字符串 103 | let limitJsons = JSON.stringify(this.limitJson); 104 | if(this.limitJsonId.assetid == '') { 105 | /*初始化查询--默认查第一个表名里的资产列表*/ 106 | this._config.getAssetsList('NULL mdb '+ this.assetsName + ' NULL NULL ' + '\''+limitJsons+'\'').subscribe( data => { 107 | if(data.length == undefined) { 108 | /*只有一条数据时候--是个对象格式*/ 109 | this.page.totalElements = 1; 110 | let arrayData = []; 111 | arrayData.push(data); 112 | this.assetsData = arrayData; 113 | } else { 114 | /*获取当前资产表名里所有资产数量*/ 115 | this._config.getCurAssetsCount('NULL mdb '+this.assetsName+' NULL NULL NULL NULL').subscribe( count => { 116 | this.page.totalElements = count; 117 | }); 118 | this.assetsData = data; 119 | } 120 | }) 121 | } else { 122 | /*根据资产表名+资产id--查询---一个对象*/ 123 | //添加资产id查询条件--处理 124 | let limitJsonIds = JSON.stringify(this.limitJsonId).replace(":\"",":").replace("\"}","}"); 125 | this._config.getAssetsList('NULL mdb '+ this.assetsName +' '+ '\''+limitJsonIds+'\'' + ' NULL ' + '\''+limitJsons+'\'').subscribe( data => { 126 | this.page.totalElements = 1; 127 | let arrayData = []; 128 | arrayData.push(data); 129 | this.assetsData = arrayData; 130 | }) 131 | } 132 | } 133 | 134 | pageChanged($event) { 135 | this.page.pageSize = $event.pageSize; 136 | this.page.pageNum = $event.pageIndex; 137 | this.limitJson.skip = ($event.pageIndex)*10; 138 | this.getAssetsList(); 139 | } 140 | 141 | /*点击跳转--当前资产详情页面*/ 142 | getAssetsDetail(row) { 143 | let param = { 144 | assetsId: row.assetid,//资产ID号 145 | assetsName: this.assetsName 146 | } 147 | let params = JSON.stringify(param); 148 | 149 | this._router.navigate(['/auth/search/assets-deal',params]); 150 | 151 | } 152 | 153 | } 154 | -------------------------------------------------------------------------------- /src/app/auth/search/block-deal-detail/block-deal-detail.component.css: -------------------------------------------------------------------------------- 1 | div.jsonShow { 2 | background: #f0f0f0; 3 | border: 1px solid #e0e0e0; 4 | } 5 | -------------------------------------------------------------------------------- /src/app/auth/search/block-deal-detail/block-deal-detail.component.html: -------------------------------------------------------------------------------- 1 |
2 |
loyalty
3 |
{{title}}
4 | 7 |
8 | 9 | 10 |
11 |
{{dealDetailJson}}
12 |
13 |
14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/app/auth/search/block-deal-detail/block-deal-detail.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Inject } from '@angular/core'; 2 | import {MatDialogRef, MAT_DIALOG_DATA} from '@angular/material'; 3 | 4 | @Component({ 5 | selector: 'app-block-deal-detail', 6 | templateUrl: './block-deal-detail.component.html', 7 | styleUrls: ['./block-deal-detail.component.css'] 8 | }) 9 | export class BlockDealDetailComponent implements OnInit { 10 | 11 | dealDetailJson; 12 | title; 13 | 14 | constructor( 15 | private _sheetRef: MatDialogRef, 16 | // /*Inject装饰器*/ 17 | @Inject(MAT_DIALOG_DATA) public data: any, 18 | ) { 19 | this.dealDetailJson = JSON.stringify(data.data,null,2); 20 | this.title = data.title; 21 | } 22 | 23 | ngOnInit() { 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/app/auth/search/block-deal/block-deal.component.css: -------------------------------------------------------------------------------- 1 | /*详情展示*/ 2 | div.blockDetail mat-form-field{ 3 | padding-right: 15px; 4 | } 5 | 6 | mat-grid-tile .two_list{ 7 | width: 100%; 8 | padding-right: 25px; 9 | padding-left: 25px; 10 | } 11 | 12 | /* filter bar */ 13 | .table-filter-bar { 14 | padding: 5px 24px; 15 | margin-top: 10px!important; 16 | } 17 | .table-filter-bar .filter-bar-header { 18 | padding-right: 24px; 19 | border-right: 1px solid rgba(0,0,0,.12); 20 | } 21 | table.mat-table th.mat-header-cell{ 22 | background-color: rgba(0,0,0,.04); 23 | border-top: 1px solid rgba(0, 0, 0, 0.12); 24 | } 25 | -------------------------------------------------------------------------------- /src/app/auth/search/block-deal/block-deal.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { ActivatedRoute} from '@angular/router'; 3 | import {FormBuilder, Validators} from '@angular/forms'; 4 | import {ConfigService} from '../../../services/config.service'; 5 | import {MatDialog, MatTableDataSource} from '@angular/material'; 6 | import {BlockDealDetailComponent} from '../block-deal-detail/block-deal-detail.component'; 7 | 8 | @Component({ 9 | selector: 'app-block-deal', 10 | templateUrl: './block-deal.component.html', 11 | styleUrls: ['./block-deal.component.css'] 12 | }) 13 | export class BlockDealComponent implements OnInit { 14 | /*区块id--传参跳转到当前块交易列表页面*/ 15 | blockId; 16 | /*当前块详情信息*/ 17 | blockDetailData = { 18 | hash: '',//区块的HASH值 19 | last_block_id: '',//上一个区块的HASH值 20 | height: '',//区块的ID号 21 | txnum: '',//区块内的交易数 22 | tmstamp: '',//创建区块的unix时间戳 23 | datetime: ''//创建区块的时间 24 | }; 25 | /*交易列表*/ 26 | blockDealData; 27 | displayedColumns: string[] = ['id', 'addr', 'operate','tmstamp','action']; 28 | page = { 29 | totalElements: 0, 30 | pageNum: 0, 31 | pageSize: 10, 32 | start:0, 33 | end:10 34 | }; 35 | /*临时存放所有的数据列表*/ 36 | datas_page; 37 | 38 | /*表单字符串匹配查询*/ 39 | applyFilter(filterValue: string) { 40 | this.blockDealData.filter = filterValue.trim().toLowerCase(); 41 | console.log(this.blockDealData.filter); 42 | } 43 | 44 | 45 | constructor( 46 | private _route: ActivatedRoute, 47 | private _fb: FormBuilder, 48 | private _config: ConfigService, 49 | private _matDialog: MatDialog 50 | ) { 51 | this._route.params.subscribe(routeParams => { 52 | this.blockId = routeParams.id; 53 | this.ngOnInit(); 54 | }); 55 | } 56 | 57 | ngOnInit() { 58 | this.getBlockDealList(); 59 | } 60 | 61 | /*查询指定块上的详情信息*/ 62 | getBlockDealList() { 63 | this._config.getTotalDeal('NULL block?height='+this.blockId).subscribe( data => { 64 | //区块详情信息赋值 65 | this.blockDetailData.hash = data.result.block_meta.block_id.hash; 66 | this.blockDetailData.last_block_id = data.result.block.header.last_block_id.hash; 67 | this.blockDetailData.height = data.result.block.header.height; 68 | this.blockDetailData.txnum = data.result.block.header.num_txs; 69 | this.blockDetailData.tmstamp = data.result.block.header.time; 70 | this.blockDetailData.datetime = data.result.block.header.time; 71 | 72 | /*分页*/ 73 | this.page.totalElements = data.result.block.header.num_txs; 74 | if(data.result.block.header.num_txs == '0'){ 75 | this.blockDealData = []; 76 | }else{ 77 | /*交易列表信息*/ 78 | this.datas_page = [];/*清空datas_page--避免数据重复apend*/ 79 | data.result.block.data.txs.forEach( rowData => { 80 | this.datas_page.push(JSON.parse(window.atob(rowData))); 81 | }); 82 | /*交易列表-表单赋值*/ 83 | this.blockDealData = new MatTableDataSource(this.datas_page.slice(this.page.start,this.page.end)); 84 | // /*匹配filter data 是所有的数据,不仅仅是当前分页10条数据*/ 85 | this.blockDealData.data = this.datas_page; 86 | } 87 | }) 88 | } 89 | 90 | getDealList() { 91 | /*交易列表-表单赋值*/ 92 | this.blockDealData = new MatTableDataSource(this.datas_page.slice(this.page.start,this.page.end)); 93 | } 94 | 95 | pageChanged($event) { 96 | this.page.pageSize = $event.pageSize; 97 | this.page.pageNum = $event.pageIndex; 98 | this.page.start = ($event.pageIndex)*10; 99 | this.page.end = ($event.pageIndex +1)*10; 100 | 101 | this.getDealList(); 102 | } 103 | 104 | /*弹框展示--查询交易详情信息*/ 105 | searchForDeal(row) { 106 | console.log(JSON.stringify(row,null,2)); 107 | 108 | const dialogRef = this._matDialog.open(BlockDealDetailComponent, { 109 | width: '800px', 110 | disableClose: true, 111 | data: {data: row,title:'交易详情'} 112 | }); 113 | dialogRef.afterClosed().subscribe(result => { 114 | if (result) { 115 | 116 | } 117 | }); 118 | 119 | 120 | } 121 | 122 | } 123 | -------------------------------------------------------------------------------- /src/app/auth/search/block/block.component.css: -------------------------------------------------------------------------------- 1 | /* filter bar */ 2 | .table-filter-bar { 3 | padding: 5px 24px; 4 | margin-top: 10px!important; 5 | } 6 | .table-filter-bar .filter-bar-header { 7 | padding-right: 24px; 8 | border-right: 1px solid rgba(0,0,0,.12); 9 | } 10 | .table-filter-bar + table.mat-table th.mat-header-cell{ 11 | background-color: rgba(0,0,0,.04); 12 | border-top: 1px solid rgba(0, 0, 0, 0.12); 13 | } 14 | -------------------------------------------------------------------------------- /src/app/auth/search/block/block.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | home 5 |
6 |
7 | 系统概览 8 |
9 |
10 | keyboard_arrow_right 11 |
12 |
13 | 区块信息 14 |
15 |
16 | keyboard_arrow_right 17 |
18 |
19 | 20 | 21 |
22 |
loyalty
23 |
区块列表
24 |
25 | 26 | 27 |
28 |
29 | search 30 |
31 | 56 |
57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 85 | 88 | 89 |
区块ID{{row.height}}区块内交易数{{row.txnum}}区块HASH值{{row.hash}}上个区块HASH值{{row.last_block_id}}区块创建时间{{row.datetime}} 83 | 84 | 86 | 87 |
90 | 91 |
92 | 93 | 99 | 100 |
101 | -------------------------------------------------------------------------------- /src/app/auth/search/block/block.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms"; 3 | import {ConfigService} from "../../../services/config.service"; 4 | import {Router} from "@angular/router"; 5 | import {McConfirmService} from "../../../modules/mc-confirm/mc-confirm.service"; 6 | 7 | @Component({ 8 | selector: 'app-block', 9 | templateUrl: './block.component.html', 10 | styleUrls: ['./block.component.css'] 11 | }) 12 | export class BlockComponent implements OnInit { 13 | 14 | searchForm :FormGroup; 15 | baseForm; 16 | /*区块data*/ 17 | blockData; 18 | /*块的总数数量*/ 19 | blockCount; 20 | /*区块列表--字段模板*/ 21 | displayedColumns = ['height', 'txnum', 'hash','last_block_id','datetime','action']; 22 | /*分页初始化赋值*/ 23 | page = { 24 | totalElements: 0, 25 | pageNum: 0, 26 | pageSize: 10 27 | }; 28 | 29 | constructor( 30 | private _fb: FormBuilder, 31 | private _config: ConfigService, 32 | private _confirm: McConfirmService, 33 | private _router: Router 34 | ) { 35 | this._config.getAllBlock('NULL mdb block NULL NULL NULL NULL').subscribe( dataCount => { 36 | //查询块总数量 37 | this.blockCount = dataCount; 38 | this.page.totalElements = dataCount; 39 | this.ngOnInit(); 40 | }) 41 | } 42 | 43 | ngOnInit() { 44 | this.buildForm(); 45 | this.getBlockList(); 46 | } 47 | 48 | get numberStartCtrl():FormControl{ 49 | return this.searchForm.get('numberStart') as FormControl; 50 | } 51 | get numberEndCtrl():FormControl{ 52 | return this.searchForm.get('numberEnd') as FormControl; 53 | } 54 | 55 | buildForm() { 56 | this.searchForm = this._fb.group({ 57 | numberStart: [''], 58 | numberEnd: [''] 59 | }); 60 | } 61 | 62 | /*点击查询按钮触发*/ 63 | doQuery() { 64 | const query: any = {}; 65 | this.page.pageNum = 0; 66 | this.getBlockList(); 67 | } 68 | 69 | /*获取区块列表*/ 70 | getBlockList(){ 71 | const val = this.searchForm.getRawValue(); 72 | let startNo = 0, endNo = this.blockCount; 73 | let limitJson = {skip: 0, limit: this.page.pageSize}; 74 | if (val.numberStart !== '') { 75 | startNo = parseInt(val.numberStart); 76 | } 77 | if (val.numberEnd !== '') { 78 | endNo = parseInt(val.numberEnd); 79 | } 80 | limitJson.skip = startNo + (this.page.pageNum) * this.page.pageSize - 1; 81 | if (limitJson.skip <0) {limitJson.skip = 0; } 82 | if ((endNo !== -1) && ((limitJson.skip + limitJson.limit) > endNo)) { 83 | limitJson.limit = endNo - limitJson.skip; 84 | } 85 | this.page.totalElements = endNo - startNo + 1; 86 | this._config.getBlockList("NULL mdb block NULL NULL "+'\'' + JSON.stringify(limitJson) + '\'').subscribe( data => { 87 | /*查询块所有列表*/ 88 | if( data.constructor == Object ) { 89 | /*只有一条数据时候--是个对象格式*/ 90 | let arrayData = []; 91 | arrayData.push(data); 92 | this.blockData = arrayData; 93 | } else { 94 | this.blockData = data; 95 | } 96 | }) 97 | 98 | } 99 | 100 | 101 | /*根据区块ID号查询当前区块的详情-跳转详情页面*/ 102 | getBlockDetail(row) { 103 | this._router.navigate(['/auth/search/block-deal',row.height]); 104 | } 105 | 106 | /*分页按钮触发*/ 107 | pageChanged($event) { 108 | this.page.pageSize = $event.pageSize; 109 | this.page.pageNum = $event.pageIndex; 110 | this.getBlockList(); 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /src/app/auth/system/aboutus/aboutus.component.css: -------------------------------------------------------------------------------- 1 | .files-manager-content{ 2 | margin-left: 30px; 3 | margin-top: 15px; 4 | } 5 | a{ 6 | text-decoration: none; 7 | } 8 | .right_td{ 9 | width: 328px; 10 | } 11 | .body{ 12 | padding-right: 40px; 13 | padding-left: 25px; 14 | } 15 | .contentBox{ 16 | box-shadow: 2px 4px 6px #000; 17 | } 18 | table.contentBox{ 19 | border-radius: 5px; 20 | background: #cae1ed; 21 | } 22 | -------------------------------------------------------------------------------- /src/app/auth/system/aboutus/aboutus.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | computer 5 |
6 |
7 | 系统设置 8 |
9 |
10 | keyboard_arrow_right 11 |
12 |
13 | 关于/用户许可协议 14 |
15 |
16 | keyboard_arrow_right 17 |
18 |
19 | 20 | 21 | 22 | 23 |
24 |
25 | 宏链区块链数据库系统 26 |
27 | version: 2.1 28 |
29 |

Copyright © 2017-2023 MaxchainTech Co.,Ltd. All Rights Reserved. 30 |
31 | 32 | 33 | 34 | 37 | 52 | 53 | 54 |
35 | 36 | 38 |

39 |
40 | 北京宏链科技有限公司
41 | MaxchainTech Co.,Ltd.
42 | www.maxchaintech.com 43 |

44 |

 

45 |

46 | 联系信息
47 | 企业网站: http://www.maxchaintech.com
48 | 技术支持: services@maxchaintech.com
49 |
50 |

51 |
55 |

56 |
57 |
58 | 59 |
60 |
61 | 本协议是您(个人或单一实体)与北京宏链科技有限公司关于MaxAttestor可信存证系统产品的法律协议:
62 |         一旦安装、复制或以其他方式使用本软件产品,即表示同意接受协议各项条件的约束。如果您不同意协议的条件,则不能获得使用本软件产品的权力。

63 | 1、版权与著作权

64 |         MaxAttestor可信存证系统的版权归北京宏链科技有限公司所有。本软件产品受中华人民共和国版权法及国际版权条约和其他知识产权法及条约的保护。因此您不得复制本软件和附随之使用手册及其他书面资料,并不得利用任何方法取得、使用本软件之程序代码、文字资料、图片、影像、音乐和音效等电子文档。本软件产品仅系授权使用,而非贩售版权。
65 |         凡与本软件产品及其拷贝有关之所有权与著作权均属北京宏链科技有限公司或其厂商所有,凡与因透过本软件产品而存取之资料内容之所有权以及知识产权,均属各资料之所有权人,并受相关著作权法或其他知识产品法律与条约保护。本协议并不授权您就该资料之内容享有使用之权力。

66 | 2、授权

67 |         北京宏链科技有限公司授权您仅在一台电脑主机上安装使用本软件产品。

68 | 3、限制

69 | 用户不得:
70 |         1) 删除本软件及其他副本上一切关于版权的信息;
71 |         2) 对本软件进行反向工程,如反汇编、反编译等;
72 |         3) 您不得出租,出借或转让本软件产品;
73 |         4) 违犯所有软件产品使用的相关法律.

74 | 4、终止

75 |         如果您未遵守本协议的任何一项条款,北京宏链科技有限公司有权立即终止本协议,并保留通过法律手段追究责任。

76 | 5、不为瑕疵担保

77 |         使用本软件产品由用户自己承担风险,在适用法律允许的最大范围内,北京宏链科技有限公司及其供应商不承担任何瑕疵担保责任与条件,不论其为明示或默示者,其中包括(但不限于)适售性、任何某特定用途以及不侵害他人权益之默示担保责任。
78 | 用户须明白,使用本软件产品涉及到Internet服务,可能会受到各个环节不稳定因素的影响。因此服务存在因不可抗力、计算机病毒或黑客攻击、系统不稳定、用户所在位置、用户关机以及其他任何技术、互联网络、通信线路原因等造成的服务中断或不能满足用户要求的风险。用户须承担以上风险,北京宏链科技有限公司不作担保。

79 | 6、就衍生损害不负赔偿责任

80 |         在适用法律允许的最大范围内,北京宏链科技有限公司及其供应商在任何情况下不就因使用或不能使用本软件产品所发生的特殊的、意外的、非直接或间接的损失承担赔偿责任。即使已事先被告知该损害发生的可能性。

81 | 7、其他规定

82 |         本协议适用中国大陆法律。就本协议涉及的一切诉讼,您同意以中国北京市海淀区人民法院为第一审管辖法院。
83 | 若您就本协议有任何疑问,请接洽北京宏链科技有限公司,或者访问http://www.maxchaintech.com。 84 |

        Copyright© 2017-2023 北京宏链科技有限公司

85 |
86 |
87 |
88 |
89 | 90 |
91 | -------------------------------------------------------------------------------- /src/app/auth/system/aboutus/aboutus.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-aboutus', 5 | templateUrl: './aboutus.component.html', 6 | styleUrls: ['./aboutus.component.css'] 7 | }) 8 | export class AboutusComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/auth/system/users/user-add/user-add.component.css: -------------------------------------------------------------------------------- 1 | mat-radio-button+mat-radio-button { 2 | margin-left: .5rem; 3 | } 4 | mat-dialog-content { 5 | padding-bottom: 2rem; 6 | } 7 | 8 | .mat-form { 9 | margin-bottom: 2rem; 10 | } -------------------------------------------------------------------------------- /src/app/auth/system/users/user-add/user-add.component.html: -------------------------------------------------------------------------------- 1 |
2 | border_color 3 |

{{isNew?'新增用户':'修改用户'}}

4 | 7 |
8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 用户名不能为空! 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 |
31 |
32 | 33 | 34 | 系统管理员 35 | 一般用户 36 | 37 |
38 |
39 |
40 |
41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/app/auth/system/users/user-add/user-add.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { UserAddComponent } from './user-add.component'; 4 | 5 | describe('UserAddComponent', () => { 6 | let component: UserAddComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ UserAddComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(UserAddComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/auth/system/users/user-add/user-add.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Inject } from '@angular/core'; 2 | import {FormBuilder, FormControl, Validators} from '@angular/forms'; 3 | import {MatDialogRef, MAT_DIALOG_DATA} from '@angular/material'; 4 | import { userConfig } from './userConfig'; 5 | import { McConfirmService } from '../../../../modules/mc-confirm/mc-confirm.service'; 6 | 7 | @Component({ 8 | selector: 'app-user-add', 9 | templateUrl: './user-add.component.html', 10 | styleUrls: ['./user-add.component.css'], 11 | }) 12 | export class UserAddComponent implements OnInit { 13 | /*表单验证*/ 14 | baseForm; 15 | isNew = true; 16 | row: userConfig; 17 | 18 | constructor( 19 | private _sheetRef: MatDialogRef, 20 | // /*Inject装饰器*/ 21 | @Inject(MAT_DIALOG_DATA) public data: any, 22 | private _fb: FormBuilder, 23 | private _confirm: McConfirmService 24 | ) { 25 | this.isNew = (data.action==='new'); 26 | if (data.data) { 27 | this.row = new userConfig(data.data) 28 | } else { 29 | this.row = new userConfig(); 30 | } 31 | } 32 | 33 | ngOnInit() { 34 | this.buildForm(); 35 | } 36 | get nameCtrl(): FormControl { 37 | return this.baseForm.get('username') as FormControl; 38 | } 39 | get activeCtrl(): FormControl { 40 | return this.baseForm.get('active') as FormControl; 41 | } 42 | get roleCtrl(): FormControl { 43 | return this.baseForm.get('role') as FormControl; 44 | } 45 | 46 | buildForm() { 47 | this.baseForm = this._fb.group({ 48 | username: [this.row.username, [Validators.required]], 49 | email: [this.row.email], 50 | phone: [this.row.phone], 51 | active: [this.row.active], 52 | role: [this.row.role], 53 | }); 54 | if (!this.isNew) { 55 | // this.nameCtrl.disable(); 56 | } 57 | } 58 | 59 | doSave() { 60 | 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/app/auth/system/users/user-add/userConfig.ts: -------------------------------------------------------------------------------- 1 | export class userConfig { 2 | username: string; 3 | email: string; 4 | phone: string; 5 | role: number; 6 | active: number; 7 | 8 | constructor(data = undefined) { 9 | this.username = ''; 10 | this.email = ''; 11 | this.phone = ''; 12 | this.role = 0; 13 | this.active = 0; 14 | if (data != undefined) { 15 | for (let k in data) { 16 | this[k] = data[k]; 17 | } 18 | } 19 | }; 20 | } 21 | -------------------------------------------------------------------------------- /src/app/auth/system/users/users.component.css: -------------------------------------------------------------------------------- 1 | th.button{ 2 | text-align: right; 3 | } 4 | 5 | button.more_dels{ 6 | margin-left: 20px; 7 | margin-right: 20px; 8 | } 9 | 10 | table.mat-table th.mat-header-cell{ 11 | background-color: rgba(0,0,0,.04); 12 | } 13 | -------------------------------------------------------------------------------- /src/app/auth/system/users/users.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {MatBottomSheet, MatDialog} from '@angular/material'; 3 | 4 | import { UserService } from '../../../services/user.service'; 5 | import { UserAddComponent } from './user-add/user-add.component'; 6 | import { McConfirmService } from '../../../modules/mc-confirm/mc-confirm.service'; 7 | 8 | @Component({ 9 | selector: 'app-users', 10 | templateUrl: './users.component.html', 11 | styleUrls: ['./users.component.css'], 12 | 13 | }) 14 | export class UsersComponent implements OnInit { 15 | 16 | columnsToDisplay = ['select', 'username', 'email', 'phone', 'role', 'active', 'createDate', 'action']; 17 | users; 18 | data = []; 19 | rowSelected = 0; 20 | expandedRow; 21 | baseForm; 22 | 23 | constructor( 24 | private _user: UserService, 25 | private _confirm: McConfirmService, 26 | public dialog: MatDialog 27 | ) { } 28 | 29 | ngOnInit() { 30 | this.getUsers(); 31 | } 32 | 33 | getUsers() { 34 | this._user.getUsers().subscribe(users => { 35 | this.users = users; 36 | console.log(this.users) 37 | }) 38 | } 39 | 40 | /*增加用户*/ 41 | addUser() { 42 | const dialogRef = this.dialog.open(UserAddComponent, { 43 | width: '600px', 44 | disableClose: true, 45 | data: {action: 'new'} 46 | }); 47 | dialogRef.afterClosed().subscribe(result => { 48 | if (result) { 49 | this._confirm.alert('新增用户成功!'); 50 | this.getUsers(); 51 | } 52 | }); 53 | } 54 | 55 | /*修改用户*/ 56 | updateUser(cf) { 57 | const dialogRef = this.dialog.open(UserAddComponent, { 58 | width: '600px', 59 | disableClose: true, 60 | data: {action: 'update', data: cf} 61 | }); 62 | dialogRef.afterClosed().subscribe(result => { 63 | if (result) { 64 | this._confirm.alert('修改用户成功!'); 65 | this.getUsers(); 66 | } 67 | }); 68 | } 69 | 70 | /*单个删除*/ 71 | removeUser(cf) { 72 | const delUserData = []; 73 | delUserData.push(cf.id); 74 | this._confirm.confirm({ 75 | message: '是否真正删除用户[' + cf.username + ']?', 76 | onAccept: () => { 77 | /* this._login.delUser(delUserData).subscribe(data => { 78 | if (data) { 79 | this._confirm.alert('用户[' + cf.username + ']删除成功!'); 80 | this.getUsers(); 81 | } else { 82 | this._confirm.alert('用户[' + cf.username + ']删除出错,请稍后再试', ); 83 | this.getUsers(); 84 | } 85 | });*/ 86 | } 87 | }); 88 | } 89 | 90 | /*批量删除*/ 91 | delsUsers() { 92 | const delUserData = []; 93 | this.users.forEach(row => { 94 | if (row.selected === true) { 95 | delUserData.push(row.id); 96 | } 97 | }); 98 | this._confirm.confirm({ 99 | message: '是否真正批量删除用户?', 100 | onAccept: () => { 101 | /*this._login.delUser(delUserData).subscribe(data => { 102 | if (data) { 103 | this._confirm.alert('批量删除用户出错,请稍后再试', ); 104 | this.getUsers(); 105 | } else { 106 | this._confirm.alert('批量删除用户成功!'); 107 | this.getUsers(); 108 | } 109 | });*/ 110 | } 111 | }); 112 | } 113 | 114 | /*启用用户*/ 115 | turnConfigOn(row) { 116 | this._confirm.confirm({ 117 | message: '是否启用用户[' + row.username + ']?', 118 | onAccept: () => { 119 | row.active = 1; 120 | /*this._login.changeUserStatus(row).subscribe(data => { 121 | if (data) { 122 | this._confirm.alert('用户[' + row.username + ']已经启用'); 123 | this.getUsers(); 124 | } else { 125 | this._confirm.alert('用户[' + row.username + ']启用出错,请稍后再试', ); 126 | this.getUsers(); 127 | } 128 | });*/ 129 | } 130 | }); 131 | } 132 | 133 | /*禁用用户*/ 134 | turnConfigOff(row) { 135 | this._confirm.confirm({ 136 | message: '是否真正停用配置项[' + row.username + ']?', 137 | onAccept: () => { 138 | row.active = 0; 139 | /*this._login.changeUserStatus(row).subscribe(data => { 140 | if (data) { 141 | this._confirm.alert('配置项[' + row.username + ']已经停用'); 142 | this.getUsers(); 143 | } else { 144 | this._confirm.alert('配置项[' + row.username + ']停用出错,请稍后再试', ); 145 | this.getUsers(); 146 | } 147 | });*/ 148 | } 149 | }); 150 | } 151 | 152 | /*单个勾选*/ 153 | onSelectedRow(cf) { 154 | if (cf.selected == undefined) { 155 | cf.selected = false; 156 | } 157 | cf.selected = !cf.selected; 158 | this.rowSelected = this.users.filter(row => row.selected === true).length; 159 | } 160 | 161 | /*表头全部勾选*/ 162 | toggleSelectAllRows($event) { 163 | this.users.forEach(row => row.selected = $event.checked); 164 | this.rowSelected = this.users.filter(row => row.selected === true).length; 165 | } 166 | 167 | } 168 | -------------------------------------------------------------------------------- /src/app/core/breadcrumb/breadcrumb.component.css: -------------------------------------------------------------------------------- 1 | .breadcrumb { 2 | display: flex; 3 | color: #23282c; 4 | font-size: 14px; 5 | justify-self: center; 6 | } 7 | 8 | .breadcrumb-item { 9 | line-height: 24px; 10 | } 11 | .breadcrumb-item+.breadcrumb-item { 12 | padding-left: .5rem; 13 | } 14 | .breadcrumb-item+.breadcrumb-item::before { 15 | display: inline-block; 16 | padding-right: .5rem; 17 | padding-left: .5rem; 18 | color: #73818f; 19 | content: "|"; 20 | } -------------------------------------------------------------------------------- /src/app/core/breadcrumb/breadcrumb.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/core/breadcrumb/breadcrumb.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { BreadcrumbComponent } from './breadcrumb.component'; 4 | 5 | describe('BreadcrumbComponent', () => { 6 | let component: BreadcrumbComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ BreadcrumbComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(BreadcrumbComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/core/breadcrumb/breadcrumb.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Input } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'cdk-breadcrumb', 5 | templateUrl: './breadcrumb.component.html', 6 | styleUrls: ['./breadcrumb.component.css'] 7 | }) 8 | export class BreadcrumbComponent implements OnInit { 9 | @Input() sideMenu; 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/app/core/core.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { SidemenuComponent } from './sidemenu/sidemenu.component'; 4 | import { SidemenuItemComponent } from './sidemenu-item/sidemenu-item.component'; 5 | import { MatListModule } from '@angular/material/list'; 6 | import { MatButtonModule } from '@angular/material/button'; 7 | import { MatInputModule } from '@angular/material/input'; 8 | import { MatIconModule } from '@angular/material/icon'; 9 | import { MatToolbarModule } from '@angular/material/toolbar'; 10 | import { MatChipsModule } from '@angular/material/chips'; 11 | import { MatFormFieldModule } from '@angular/material/form-field'; 12 | import { MatTabsModule } from '@angular/material'; 13 | import { RouterModule } from '@angular/router'; 14 | import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar'; 15 | import { PERFECT_SCROLLBAR_CONFIG } from 'ngx-perfect-scrollbar'; 16 | import { PerfectScrollbarConfigInterface } from 'ngx-perfect-scrollbar'; 17 | import { FlexLayoutModule } from '@angular/flex-layout'; 18 | import { ToolbarNotificationComponent } from './toolbar-notification/toolbar-notification.component'; 19 | import { ToolbarComponent } from './toolbar/toolbar.component'; 20 | import { SearchBarComponent } from './search-bar/search-bar.component'; 21 | import { FullscreenComponent } from './fullscreen/fullscreen.component'; 22 | import { SidebarComponent } from './sidebar/sidebar.component'; 23 | import { UserMenuComponent } from './user-menu/user-menu.component'; 24 | import {MatMenuModule} from '@angular/material/menu'; 25 | import { 26 | MatSidenavModule, 27 | MatSliderModule, 28 | MatProgressBarModule, 29 | } from '@angular/material'; 30 | import { BreadcrumbComponent } from './breadcrumb/breadcrumb.component'; 31 | 32 | 33 | const DEFAULT_PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = { 34 | suppressScrollX: true 35 | }; 36 | 37 | @NgModule({ 38 | 39 | declarations: [ 40 | SidemenuComponent, 41 | SidemenuItemComponent, 42 | ToolbarNotificationComponent, 43 | ToolbarComponent, 44 | SearchBarComponent, 45 | FullscreenComponent, 46 | SidebarComponent, 47 | UserMenuComponent, 48 | BreadcrumbComponent 49 | ], 50 | 51 | imports: [ 52 | CommonModule, 53 | MatListModule, 54 | MatButtonModule, 55 | MatInputModule, 56 | MatIconModule, 57 | MatChipsModule, 58 | RouterModule, 59 | PerfectScrollbarModule, 60 | FlexLayoutModule, 61 | MatToolbarModule, 62 | MatFormFieldModule, 63 | MatSidenavModule, 64 | MatTabsModule, 65 | MatSliderModule, 66 | MatProgressBarModule, 67 | MatMenuModule 68 | ], 69 | 70 | 71 | exports: [ 72 | SidemenuComponent, 73 | SidemenuItemComponent, 74 | ToolbarNotificationComponent, 75 | ToolbarComponent, 76 | SearchBarComponent, 77 | FullscreenComponent, 78 | SidebarComponent, 79 | UserMenuComponent, 80 | BreadcrumbComponent 81 | ], 82 | 83 | providers: [ 84 | { 85 | provide: PERFECT_SCROLLBAR_CONFIG, 86 | useValue: DEFAULT_PERFECT_SCROLLBAR_CONFIG 87 | } 88 | ] 89 | }) 90 | export class CoreModule { } 91 | -------------------------------------------------------------------------------- /src/app/core/fullscreen/fullscreen.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/core/fullscreen/fullscreen.component.scss: -------------------------------------------------------------------------------- 1 | button mat-icon{ 2 | color: #fff; 3 | } 4 | -------------------------------------------------------------------------------- /src/app/core/fullscreen/fullscreen.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { FullscreenComponent } from './fullscreen.component'; 4 | 5 | describe('FullscreenComponent', () => { 6 | let component: FullscreenComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ FullscreenComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(FullscreenComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/core/fullscreen/fullscreen.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import * as screenfull from 'screenfull'; 3 | 4 | @Component({ 5 | selector: 'cdk-fullscreen', 6 | templateUrl: './fullscreen.component.html', 7 | styleUrls: ['./fullscreen.component.scss'] 8 | }) 9 | export class FullscreenComponent implements OnInit { 10 | isFullscreen: boolean = false; 11 | constructor() { } 12 | 13 | ngOnInit() { 14 | } 15 | 16 | toggleFullscreen() { 17 | if (screenfull.enabled) { 18 | screenfull.toggle(); 19 | this.isFullscreen = !this.isFullscreen; 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/app/core/search-bar/search-bar.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/app/core/search-bar/search-bar.component.scss: -------------------------------------------------------------------------------- 1 | .search { 2 | width: 0; 3 | overflow: hidden; 4 | opacity: 0; 5 | visibility: hidden; 6 | transition: all .4s cubic-bezier(.35,0,.25,1); 7 | margin-top: 7px; 8 | } 9 | 10 | .search.search-open { 11 | width: 200px; 12 | visibility: visible; 13 | opacity: 1; 14 | margin-top: 11px; 15 | } -------------------------------------------------------------------------------- /src/app/core/search-bar/search-bar.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { SearchBarComponent } from './search-bar.component'; 4 | 5 | describe('SearchBarComponent', () => { 6 | let component: SearchBarComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ SearchBarComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(SearchBarComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/core/search-bar/search-bar.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Input } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'cdk-search-bar', 5 | templateUrl: './search-bar.component.html', 6 | styleUrls: ['./search-bar.component.scss'] 7 | }) 8 | export class SearchBarComponent implements OnInit { 9 | public bigMenu; 10 | @Input() open; 11 | constructor() { } 12 | 13 | ngOnInit() {} 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/core/sidebar/sidebar.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 52 | 53 | 54 | 55 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
80 |

Server Statistics

81 |
82 | 83 |
CPU Load
84 | > 85 |
86 |
87 | 88 | 89 |
90 | 91 |
RAM Usage
92 | 93 |
94 |
95 | 96 | 97 |
98 | 99 |
CPU Temp
100 | 101 |
102 |
103 | 104 |
105 |
-------------------------------------------------------------------------------- /src/app/core/sidebar/sidebar.component.scss: -------------------------------------------------------------------------------- 1 | .sidebar{ 2 | } 3 | .content{ 4 | margin-top: 2px; 5 | 6 | } 7 | .example-margin { 8 | margin: 0 10px; 9 | } 10 | .today{ 11 | width: 100%; 12 | height: 22%; 13 | position: absolute; 14 | background: '#17161642'; 15 | z-index: 1; 16 | } 17 | .today-bg{ 18 | padding: 30px 0; 19 | // background: url('../../../assets/images/bg/city1.jpg'); 20 | } 21 | .today-time{ 22 | margin: 0; 23 | color: white; 24 | z-index: 2; 25 | } 26 | .today-date{ 27 | margin: 0; 28 | color: white; 29 | z-index: 2; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/app/core/sidebar/sidebar.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { SidebarComponent } from './sidebar.component'; 4 | 5 | describe('SidebarComponent', () => { 6 | let component: SidebarComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ SidebarComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(SidebarComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/core/sidebar/sidebar.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Input } from '@angular/core'; 2 | 3 | 4 | @Component({ 5 | selector: 'cdk-sidebar', 6 | templateUrl: './sidebar.component.html', 7 | styleUrls: ['./sidebar.component.scss'] 8 | }) 9 | export class SidebarComponent implements OnInit { 10 | 11 | constructor() { } 12 | 13 | ngOnInit() { 14 | } 15 | 16 | today: number = Date.now(); 17 | // public bufferValue; 18 | 19 | events = [ 20 | { 21 | id: 'id', 22 | title: 'Business Meeting', 23 | time: '05:00 PM', 24 | state: 'state' 25 | }, 26 | { 27 | id: 'id', 28 | title: 'Ask for a Vacation', 29 | time: '05:00 PM', 30 | state: 'state' 31 | }, 32 | { 33 | id: 'id', 34 | title: 'Dinner with Micheal', 35 | time: '05:00 PM', 36 | state: 'state' 37 | }, 38 | { 39 | id: 'id', 40 | title: 'Deadline for Project ABC', 41 | time: '05:00 PM', 42 | state: 'state' 43 | }, 44 | ]; 45 | 46 | todolists = [ 47 | { 48 | id: 'id', 49 | title: 'Get to know Angular more', 50 | time: 'Added:4 days ago', 51 | }, 52 | { 53 | id: 'id', 54 | title: 'Configure new Router', 55 | time: 'Added:4 days ago', 56 | }, 57 | { 58 | id: 'id', 59 | title: 'Invite Joy to play Carroms', 60 | time: 'Added:4 days ago', 61 | }, 62 | { 63 | id: 'id', 64 | title: 'Check SRS of Project X', 65 | time: 'Added:4 days ago', 66 | }, 67 | ]; 68 | 69 | messages = [ 70 | {from: 'Catherin', subject: 'Shopping', content: 'hi there??'}, 71 | {from: 'Jack', subject: 'Function', content: 'yes'}, 72 | {from: 'Karina', subject: 'Get together', content: 'nice'}, 73 | {from: 'Micheal', subject: 'Trip', content: 'ya.. I will'}, 74 | {from: 'Ashik', subject: 'Meeting', content: 'Time??'}, 75 | {from: 'Joy', subject: 'Party', content: 'Lets enjoy'}, 76 | ]; 77 | } 78 | -------------------------------------------------------------------------------- /src/app/core/sidemenu-item/sidemenu-item.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{menu.icon}} 4 |

{{ menu.name }}

5 | 6 | {{menu?.chip?.value}} 7 | 8 | expand_more 9 |
10 | 11 | {{menu.icon}} 12 |

{{ menu.name }}

13 |
14 | 15 |
16 | -------------------------------------------------------------------------------- /src/app/core/sidemenu-item/sidemenu-item.component.scss: -------------------------------------------------------------------------------- 1 | @mixin mat-list-icon($size: 24px) { 2 | font-size: $size; 3 | height: $size; 4 | width: $size; 5 | } 6 | @mixin mat-chip() { 7 | padding: 1px 7px; 8 | } 9 | 10 | @mixin sidemenu-item($theme,$icon-size) { 11 | .sidenav-dropdown-indicator { 12 | transition: transform .25s; 13 | &.indicateOpen { 14 | transform: rotate(180deg); 15 | } 16 | } 17 | mat-nav-list { 18 | overflow: hidden; 19 | padding-top: 0px; 20 | 21 | } 22 | .primary{ 23 | transition: max-height .4s cubic-bezier(.35, 0, .25, 1); 24 | padding-top: 0px; 25 | } 26 | .secondaryMenu { 27 | // background: mat-color($primary, 500); ; 28 | transition: max-height .4s cubic-bezier(.35, 0, .25, 1); 29 | padding-top: 0px; 30 | } 31 | .active-link { 32 | background: mat-color($primary, 500)!important; 33 | } 34 | .mat-nav-list .mat-list-item .mat-list-icon{ 35 | @include mat-list-icon($icon-size); 36 | } 37 | .mat-chip:not(.mat-basic-chip){ 38 | @include mat-chip() 39 | } 40 | .mat-nav-list .mat-list-item { 41 | font-size: 14px; 42 | } 43 | } 44 | 45 | .mat-nav-list .mat-list-item.mat-list-item-with-avatar { 46 | height:48px!important; 47 | } -------------------------------------------------------------------------------- /src/app/core/sidemenu-item/sidemenu-item.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { SidemenuItemComponent } from './sidemenu-item.component'; 4 | 5 | describe('SidemenuItemComponent', () => { 6 | let component: SidemenuItemComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ SidemenuItemComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(SidemenuItemComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/core/sidemenu-item/sidemenu-item.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, EventEmitter, Input, Output } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | @Component({ 4 | selector: 'cdk-sidemenu-item', 5 | templateUrl: './sidemenu-item.component.html', 6 | styleUrls: ['./sidemenu-item.component.scss'] 7 | }) 8 | export class SidemenuItemComponent implements OnInit { 9 | 10 | @Input() menu; 11 | @Input() iconOnly: boolean; 12 | @Input() secondaryMenu = false; 13 | @Output() onSelected = new EventEmitter() 14 | 15 | constructor( 16 | private _router: Router 17 | ) { } 18 | 19 | ngOnInit() { 20 | if ((this.menu.link) && (this._router.url == this.menu.link)) { 21 | if (this.onSelected) { 22 | this.onSelected.emit([this.menu]); 23 | } 24 | } 25 | } 26 | 27 | openLink() { 28 | this.menu.open = this.menu.open; 29 | } 30 | 31 | onClicked() { 32 | this.menu.open = !this.menu.open; 33 | if ((this.menu.link) && this.onSelected) { 34 | this.onSelected.emit([this.menu]); 35 | } 36 | } 37 | onChildSelected($event) { 38 | if (this.onSelected) { 39 | this.onSelected.emit([].concat(this.menu,$event)); 40 | } 41 | } 42 | chechForChildMenu() { 43 | return (this.menu && this.menu.sub) ? true : false; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/app/core/sidemenu/menu-element.ts: -------------------------------------------------------------------------------- 1 | export const menus = [ 2 | { 3 | 'name': '系统概览', 4 | 'icon': 'dashboard', 5 | 'link': '/auth/overview', 6 | 'open': true, 7 | 'chip': false, 8 | }, 9 | 10 | { 11 | 'name': 'MDB配置', 12 | 'icon': 'settings_ethernet', 13 | 'link': false, 14 | 'open': false, 15 | 'chip': false, 16 | 'sub': [ 17 | { 18 | 'name': '区块链数据服务', 19 | 'icon': 'chevron_right', 20 | 'link': '/auth/config/abci', 21 | 'open': false, 22 | }, 23 | { 24 | 'name': '区块链接口服务', 25 | 'icon': 'chevron_right', 26 | 'link': '/auth/config/mdbserv', 27 | 'open': false, 28 | }, 29 | { 30 | 'name': '区块链系统配置', 31 | 'icon': 'chevron_right', 32 | 'link': '/auth/config/distributednode', 33 | 'open': false, 34 | }, 35 | { 36 | 'name': '区块链用户管理', 37 | 'icon': 'chevron_right', 38 | 'link': '/auth/config/mdbuser', 39 | 'open': false, 40 | }, 41 | ] 42 | 43 | }, 44 | 45 | { 46 | 'name': '系统设置', 47 | 'icon': 'settings', 48 | 'link': false, 49 | 'open': false, 50 | 'sub': [ 51 | { 52 | 'name': '管理用户', 53 | 'link': '/auth/system/users', 54 | 'icon': 'chevron_right', 55 | 'chip': false, 56 | 'open': false, 57 | }, 58 | { 59 | 'name': '关于....', 60 | 'link': '/auth/system/aboutus', 61 | 'icon': 'chevron_right', 62 | 'chip': false, 63 | 'open': false, 64 | }, 65 | { 66 | 'name': '用户许可协议', 67 | 'link': '/auth/system/userlicenseagreement', 68 | 'icon': 'chevron_right', 69 | 'chip': false, 70 | 'open': false, 71 | } 72 | ] 73 | }, 74 | 75 | ]; 76 | -------------------------------------------------------------------------------- /src/app/core/sidemenu/sidemenu.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 |
7 | -------------------------------------------------------------------------------- /src/app/core/sidemenu/sidemenu.component.scss: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/app/core/sidemenu/sidemenu.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { SidemenuComponent } from './sidemenu.component'; 4 | 5 | describe('SidemenuComponent', () => { 6 | let component: SidemenuComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ SidemenuComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(SidemenuComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/core/sidemenu/sidemenu.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Input } from '@angular/core'; 2 | import { menus } from './menu-element'; 3 | 4 | @Component({ 5 | selector: 'cdk-sidemenu', 6 | templateUrl: './sidemenu.component.html', 7 | styleUrls: ['./sidemenu.component.scss'] 8 | }) 9 | export class SidemenuComponent implements OnInit { 10 | 11 | @Input() iconOnly:boolean = false; 12 | public menus = menus; 13 | public menuPath = []; 14 | constructor() { } 15 | 16 | ngOnInit() { 17 | } 18 | 19 | onChildSelected($event) { 20 | this.menuPath = $event; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/app/core/toolbar-notification/toolbar-notification.component.html: -------------------------------------------------------------------------------- 1 |
2 | 6 | 7 | 8 | 28 | 29 |
30 | 31 | 32 | 33 |
34 |
35 | notifications 36 |
37 |
{{ notification.title }}
38 |
{{ notification.lastTime }}
39 |
40 | 41 | 44 |
45 |
46 |
47 |
48 |
49 | 50 | 51 |
暂无通知
52 |
53 | 54 | -------------------------------------------------------------------------------- /src/app/core/toolbar-notification/toolbar-notification.component.scss: -------------------------------------------------------------------------------- 1 | $prefix: 'toolbar-notification'; 2 | 3 | .badge { 4 | position: absolute; 5 | top: 0; 6 | left: 50%; 7 | font-weight: 700; 8 | line-height: 13px; 9 | height: 13px; 10 | padding: 5px; 11 | border-radius: 26%; 12 | width: 30%; 13 | background-color: #f44336; 14 | color: #fff; 15 | border-color:#f44336 16 | } 17 | 18 | .#{$prefix} { 19 | &-container { 20 | position: relative; 21 | display: flex; 22 | align-items: center; 23 | } 24 | 25 | &-btn { 26 | display: flex; 27 | justify-content: center; 28 | margin-right: 10px; 29 | } 30 | } 31 | .dropdown { 32 | background: white; 33 | position: absolute; 34 | top: 42px; 35 | right: 28px; 36 | min-width: 350px; 37 | z-index: 2; 38 | transform: translateY(0) scale(0); 39 | transform-origin: top right; 40 | visibility: hidden; 41 | transition: transform .4s cubic-bezier(.25, .8, .25, 1), visibility .4s cubic-bezier(.25, .8, .25, 1); 42 | 43 | @media screen and (max-width: 599px) { 44 | min-width: 50vw; 45 | right: 5px; 46 | transform: translateY(0); 47 | visibility: hidden; 48 | transition: transform .4s cubic-bezier(.25,.8,.25,1), visibility .4s cubic-bezier(.25,.8,.25,1); 49 | } 50 | 51 | &.open { 52 | transform: translateY(0) scale(1); 53 | visibility: visible; 54 | } 55 | .card { 56 | 57 | .header { 58 | background: #EEEEEE; 59 | min-height: 54px; 60 | padding-left: 16px; 61 | padding-right: 8px; 62 | color: #555; 63 | display: flex; 64 | justify-content: flex-start; 65 | align-items: center; 66 | align-content: center; 67 | border-bottom: 1px solid #e0e0e0; 68 | 69 | .extra { 70 | font-size: 12px; 71 | color: #888; 72 | } 73 | } 74 | } 75 | .content { 76 | overflow: hidden; 77 | max-height: 256px; 78 | 79 | .notification { 80 | min-height: 64px; 81 | padding: 0 16px 0 14px; 82 | position: relative; 83 | color: #666; 84 | cursor: pointer; 85 | 86 | .icon { 87 | height: 28px; 88 | width: 28px; 89 | line-height: 28px; 90 | font-size: 18px; 91 | margin-right: 13px; 92 | text-align: center; 93 | border-radius: 50%; 94 | background: #FFF; 95 | color: #888; 96 | border: 1px solid #EEE; 97 | } 98 | 99 | .title { 100 | font-weight: 500; 101 | font-size: 14px; 102 | } 103 | 104 | .time { 105 | font-size: 12px; 106 | } 107 | 108 | .close { 109 | font-size: 18px; 110 | width: 18px; 111 | height: 18px; 112 | line-height: 18px; 113 | } 114 | 115 | &.primary { 116 | .icon { 117 | background: #ccc; 118 | color: #ddd; 119 | } 120 | } 121 | 122 | &.accent { 123 | .icon { 124 | background: #aaa; 125 | color: #bbb; 126 | } 127 | } 128 | 129 | &.warn { 130 | .icon { 131 | background: #eee; 132 | color: #ddd; 133 | } 134 | } 135 | 136 | &.read { 137 | color: #999; 138 | 139 | .name { 140 | font-weight: normal; 141 | } 142 | } 143 | } 144 | } 145 | 146 | .footer { 147 | min-height: 42px; 148 | border-top: 1px solid #EEE; 149 | 150 | .action { 151 | cursor: pointer; 152 | color: #AAA; 153 | text-align: center; 154 | font-size: 13px; 155 | } 156 | } 157 | 158 | .divider { 159 | width: calc(100% - 30px); 160 | height: 1px; 161 | background: #EEE; 162 | margin: 0 16px 0 14px; 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /src/app/core/toolbar-notification/toolbar-notification.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ToolbarNotificationComponent } from './toolbar-notification.component'; 4 | 5 | describe('ToolbarNotificationComponent', () => { 6 | let component: ToolbarNotificationComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ToolbarNotificationComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ToolbarNotificationComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/core/toolbar-notification/toolbar-notification.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Input, HostListener, ElementRef } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'cdk-toolbar-notification', 5 | templateUrl: './toolbar-notification.component.html', 6 | styleUrls: ['./toolbar-notification.component.scss'] 7 | }) 8 | export class ToolbarNotificationComponent implements OnInit { 9 | cssPrefix = 'toolbar-notification'; 10 | isOpen: boolean = false; 11 | @Input() notifications = []; 12 | 13 | // @HostListener('document:click', ['$event', '$event.target']) 14 | // onClick(event: MouseEvent, targetElement: HTMLElement) { 15 | // if (!targetElement) { 16 | // return; 17 | // } 18 | // const clickedInside = this.elementRef.nativeElement.contains(targetElement); 19 | // if (!clickedInside) { 20 | // this.isOpen = false; 21 | // } 22 | // } 23 | 24 | constructor(private elementRef: ElementRef) { } 25 | 26 | ngOnInit() { 27 | } 28 | 29 | select() { 30 | 31 | } 32 | 33 | delete(notification) { 34 | 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/app/core/toolbar/toolbar.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/app/core/toolbar/toolbar.component.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | z-index: 4; 3 | } 4 | 5 | .main-toolbar { 6 | height: 64px; 7 | padding-left: 16px; 8 | } 9 | 10 | .more-btn { 11 | height: 100%; 12 | min-width: 70px; 13 | } 14 | 15 | .mat-icon-button { 16 | margin-right: 10px; 17 | } 18 | -------------------------------------------------------------------------------- /src/app/core/toolbar/toolbar.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ToolbarComponent } from './toolbar.component'; 4 | 5 | describe('ToolbarComponent', () => { 6 | let component: ToolbarComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ToolbarComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ToolbarComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/core/toolbar/toolbar.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Input } from "@angular/core"; 2 | import { ToolbarHelpers } from "./toolbar.helpers"; 3 | import { ConfigService } from "../../services/service.module"; 4 | import { McConfirmService } from "../../modules/mc-confirm/mc-confirm.module"; 5 | @Component({ 6 | selector: "cdk-toolbar", 7 | templateUrl: "./toolbar.component.html", 8 | styleUrls: ["./toolbar.component.scss"] 9 | }) 10 | export class ToolbarComponent implements OnInit { 11 | 12 | searchOpen: boolean = false; 13 | toolbarHelpers = ToolbarHelpers; 14 | constructor( 15 | private _config: ConfigService, 16 | private _confirm: McConfirmService 17 | ) {} 18 | 19 | ngOnInit() {} 20 | 21 | doSaveConfig() { 22 | this._confirm.confirm({ 23 | message: "保存后所有配置在下次启动时依然生效,是否继续?", 24 | onAccept: () => { 25 | this._config.saveAllConfig().subscribe(data => { 26 | if (data) { 27 | this._confirm.alert("所有配置已经保存"); 28 | } else { 29 | this._confirm.alert("配置保存出错,请稍后再试"); 30 | } 31 | }); 32 | } 33 | }); 34 | } 35 | 36 | 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/app/core/toolbar/toolbar.helpers.ts: -------------------------------------------------------------------------------- 1 | export const ToolbarHelpers = { 2 | notifications: [ 3 | { 4 | id: 'id', 5 | title: 'Mail 5', 6 | lastTime: '23 Minutes ago', 7 | state: 'state' 8 | }, 9 | { 10 | id: 'id', 11 | title: 'Mail 5', 12 | lastTime: '23 Minutes ago', 13 | state: 'state' 14 | }, 15 | { 16 | id: 'id', 17 | title: 'Mail 5', 18 | lastTime: '23 Minutes ago', 19 | state: 'state' 20 | }, 21 | ], 22 | 23 | currentUser: { 24 | photoURL: 'assets/images/avatars/hari.jpg', 25 | currentUserName: 'Admin' 26 | } 27 | }; -------------------------------------------------------------------------------- /src/app/core/user-menu/user-menu.component.html: -------------------------------------------------------------------------------- 1 |
2 | 9 | 10 | 11 | 37 |
38 | -------------------------------------------------------------------------------- /src/app/core/user-menu/user-menu.component.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | height: 100%; 3 | } 4 | 5 | .toolbar-user-container { 6 | height: 100%; 7 | position: relative; 8 | 9 | .toolbar-user-btn { 10 | display: flex; 11 | justify-content: center; 12 | height: 100%; 13 | min-width: 160px; 14 | 15 | .avatar { 16 | width: 30px; 17 | height: 30px; 18 | border-radius: 50%; 19 | } 20 | 21 | .name { 22 | margin: 0 8px 0 10px; 23 | } 24 | 25 | .icon { 26 | width: 16px; 27 | height: 16px; 28 | font-size: 16px; 29 | transform: rotate(0); 30 | transition: transform .25s cubic-bezier(.25,.8,.25,1); 31 | } 32 | 33 | &.open { 34 | background: rgba(0, 0, 0, .05); 35 | 36 | .icon { 37 | transform: rotate(-180deg); 38 | } 39 | } 40 | } 41 | 42 | .dropdown { 43 | background: white; 44 | z-index: 2; 45 | position: absolute; 46 | width: 100%; 47 | min-width: 160px; 48 | opacity: 0; 49 | visibility: hidden; 50 | transition: all .25s linear, max-height .25s linear, opacity .25s linear; 51 | 52 | @media screen and (max-width: 599px) { 53 | min-width: 65px; 54 | } 55 | 56 | &.open { 57 | opacity: 1; 58 | visibility: visible; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/app/core/user-menu/user-menu.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { UserMenuComponent } from './user-menu.component'; 4 | 5 | describe('UserMenuComponent', () => { 6 | let component: UserMenuComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ UserMenuComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(UserMenuComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/core/user-menu/user-menu.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Input, HostListener, ElementRef } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'cdk-user-menu', 5 | templateUrl: './user-menu.component.html', 6 | styleUrls: ['./user-menu.component.scss'] 7 | }) 8 | export class UserMenuComponent implements OnInit { 9 | isOpen: boolean = false; 10 | 11 | //currentUser = null; 12 | Hari; 13 | 14 | 15 | @Input() currentUser = null; 16 | @HostListener('document:click', ['$event', '$event.target']) 17 | onClick(event: MouseEvent, targetElement: HTMLElement) { 18 | if (!targetElement) { 19 | return; 20 | } 21 | 22 | const clickedInside = this.elementRef.nativeElement.contains(targetElement); 23 | if (!clickedInside) { 24 | this.isOpen = false; 25 | } 26 | } 27 | 28 | 29 | constructor(private elementRef: ElementRef) { } 30 | 31 | 32 | ngOnInit() { 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/app/lazy-load/lazy-load.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { Routes,RouterModule } from '@angular/router'; 4 | 5 | import { AuthModule } from '../auth/auth.module'; 6 | 7 | const routes: Routes = [ 8 | {path: '', redirectTo: 'login', pathMatch: 'full'}, /* http://localhost:4201 */ 9 | {path: 'login', loadChildren: '../login/login.module#LoginModule'}, 10 | {path: 'auth', loadChildren: '../auth/auth.module#AuthModule'}, 11 | ] 12 | 13 | 14 | 15 | /* 16 | const routes: Routes = [ 17 | {path: '', redirectTo: 'login', pathMatch: 'full'}, 18 | {path: 'login', loadChildren: '../login/login.module#LoginModule'}, 19 | {path: 'auth', loadChildren: '../auth/auth.module#AuthModule', canActivate: [AuthGuard]}, 20 | ] 21 | */ 22 | 23 | @NgModule({ 24 | imports: [RouterModule.forRoot(routes)], 25 | exports: [RouterModule] 26 | }) 27 | export class LazyLoadModule { } 28 | -------------------------------------------------------------------------------- /src/app/login/login.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 47 | 48 | 49 |
50 | -------------------------------------------------------------------------------- /src/app/login/login.component.scss: -------------------------------------------------------------------------------- 1 | div.mdb_logo img{ 2 | margin-top: 20px; 3 | width: 140px; 4 | margin-bottom: 25px; 5 | } 6 | 7 | ::ng-deep body{ 8 | background: linear-gradient(135deg,#f0f0f0 22px,rgba(0,0,0,.04) 22px,rgba(0,0,0,.04) 24px,transparent 24px,transparent 67px,rgba(0,0,0,.04) 67px,rgba(0,0,0,.04) 69px,transparent 69px),linear-gradient(225deg,#f0f0f0 22px,rgba(0,0,0,.04) 22px,rgba(0,0,0,.04) 24px,transparent 24px,transparent 67px,rgba(0,0,0,.04) 67px,rgba(0,0,0,.04) 69px,transparent 69px) 0 64px; 9 | background-color: #f0f0f0; 10 | background-size: 64px 128px; 11 | } 12 | 13 | div.login_table{ 14 | border-left: 60px solid #227aac; 15 | border-radius: 8px; 16 | width: 380px; 17 | background: white; 18 | box-shadow: 0 2px 10px 2px rgba(0, 0, 0, 0.35); 19 | } 20 | 21 | button.login_buton{ 22 | width: 224px; 23 | margin-bottom: 50px; 24 | } 25 | 26 | div.val_code{ 27 | margin-left: 10px; 28 | line-height: 41px; 29 | width: 90px; 30 | height: 64px; 31 | } 32 | -------------------------------------------------------------------------------- /src/app/login/login.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms"; 3 | import {Router} from "@angular/router"; 4 | 5 | @Component({ 6 | selector: 'cdk-login', 7 | templateUrl: './login.component.html', 8 | styleUrls: ['./login.component.scss'] 9 | }) 10 | 11 | export class LoginComponent implements OnInit { 12 | 13 | loginForm :FormGroup; 14 | loginInfo = { 15 | username:'', 16 | password:'', 17 | valCode:'' 18 | }; 19 | color = 'primary'; 20 | mode = 'determinate'; 21 | value = 50; 22 | type = 'password'; 23 | 24 | constructor( 25 | private _fb: FormBuilder, 26 | private _router: Router 27 | ) { } 28 | 29 | ngOnInit() { 30 | this.buildForm(); 31 | } 32 | 33 | buildForm() { 34 | this.loginForm = this._fb.group({ 35 | username: [ 'Admin' , [Validators.required] ], 36 | password: ['Admin' , [Validators.required]], 37 | valCode: ['1234' , [Validators.required]] 38 | }); 39 | } 40 | 41 | updateModel() { 42 | let val = this.loginForm.getRawValue(); 43 | this.loginInfo.username = val.username; 44 | this.loginInfo.password = val.password; 45 | this.loginInfo.valCode = val.valCode; 46 | } 47 | 48 | login() { 49 | this.updateModel(); 50 | console.log(this.loginInfo); 51 | /*登录成功后跳转到系统概览*/ 52 | this._router.navigate(['/auth/overview']); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/app/login/login.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { LoginComponent } from './login.component'; 4 | import { RouterModule, Routes } from '@angular/router'; 5 | import { MatInputModule } from '@angular/material/input'; 6 | import { MatFormFieldModule } from '@angular/material/form-field'; 7 | import { MatCardModule } from '@angular/material/card'; 8 | import { MatButtonModule } from '@angular/material/button'; 9 | import { FlexLayoutModule } from "@angular/flex-layout"; 10 | import { MatIconModule } from "@angular/material/icon"; 11 | import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 12 | 13 | import {MatProgressSpinnerModule} from '@angular/material/progress-spinner'; 14 | 15 | const appRoutes: Routes = [ 16 | { path: '', component: LoginComponent }, 17 | ] 18 | 19 | @NgModule({ 20 | imports: [ 21 | CommonModule, 22 | MatInputModule, 23 | MatFormFieldModule, 24 | MatCardModule, 25 | MatButtonModule, 26 | FlexLayoutModule, 27 | MatIconModule, 28 | FormsModule, 29 | ReactiveFormsModule, 30 | MatProgressSpinnerModule, 31 | 32 | RouterModule.forChild(appRoutes), 33 | ], 34 | declarations: [LoginComponent] 35 | }) 36 | export class LoginModule { } 37 | -------------------------------------------------------------------------------- /src/app/modules/cdk-icons/cdk-icons.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { SvgIconsService } from './svg-icons.service'; 4 | 5 | @NgModule({ 6 | imports: [ 7 | CommonModule 8 | ], 9 | declarations: [ 10 | 11 | ], 12 | providers: [ 13 | SvgIconsService 14 | ], 15 | exports: [ 16 | ] 17 | }) 18 | export class CdkIconsModule { } 19 | 20 | export { SvgIconsService } from './svg-icons.service'; 21 | -------------------------------------------------------------------------------- /src/app/modules/cdk-icons/svg-icons.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import {MatIconRegistry} from '@angular/material'; 3 | import { DomSanitizer } from '@angular/platform-browser'; 4 | 5 | @Injectable({ 6 | providedIn: 'root' 7 | }) 8 | export class SvgIconsService { 9 | 10 | constructor( 11 | private _matIconRegistry: MatIconRegistry, 12 | private _domSanitizer: DomSanitizer 13 | ) { 14 | } 15 | 16 | init() { 17 | console.log('SVG Icons inited!'); 18 | this._matIconRegistry.addSvgIcon(`password`, this._domSanitizer.bypassSecurityTrustResourceUrl(`./assets/icon/password.svg`)); 19 | this._matIconRegistry.addSvgIcon(`watch`, this._domSanitizer.bypassSecurityTrustResourceUrl(`./assets/icon/watch.svg`)); 20 | this._matIconRegistry.addSvgIcon(`noWatch`, this._domSanitizer.bypassSecurityTrustResourceUrl(`./assets/icon/noWatch.svg`)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/app/modules/mc-confirm/confirm.interface.ts: -------------------------------------------------------------------------------- 1 | export class Confirm { 2 | message: string; 3 | onAccept: Function; 4 | onReject: Function = undefined; 5 | option: any = undefined; 6 | } 7 | -------------------------------------------------------------------------------- /src/app/modules/mc-confirm/mc-confirm.component.css: -------------------------------------------------------------------------------- 1 | .modal { 2 | z-index: 1099; 3 | } 4 | div.yesNo{ 5 | color: red; 6 | } 7 | .icon_error{ 8 | margin-right: 5px; 9 | margin-top: 2px; 10 | } 11 | .mat-dialog-title { 12 | margin: 0px !important; 13 | } 14 | -------------------------------------------------------------------------------- /src/app/modules/mc-confirm/mc-confirm.component.html: -------------------------------------------------------------------------------- 1 |
2 | error 3 |

{{option.title}}

4 |
5 | 6 |
7 | {{confirmValue?.message}} 8 |
9 |
10 | 11 | 12 |
13 | -------------------------------------------------------------------------------- /src/app/modules/mc-confirm/mc-confirm.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Inject } from "@angular/core"; 2 | import { Confirm } from "./confirm.interface"; 3 | import { MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog'; 4 | 5 | @Component({ 6 | selector: "mc-confirm", 7 | templateUrl: "./mc-confirm.component.html", 8 | styleUrls: ["./mc-confirm.component.css"] 9 | }) 10 | export class McConfirmComponent implements OnInit { 11 | confirmValue: Confirm; 12 | 13 | option = { 14 | title: "确认", 15 | okText: "确认", 16 | cancelText: "取消", 17 | modalClass: "modal-nm", 18 | promptOnly: false 19 | }; 20 | 21 | constructor( 22 | public dialogRef: MatDialogRef, 23 | @Inject(MAT_DIALOG_DATA) public data: any 24 | ) { 25 | console.log(data) 26 | this.confirmValue = data; 27 | if (this.confirmValue.option != undefined) { 28 | this.option = Object.assign(this.option, this.confirmValue.option); 29 | }; 30 | } 31 | 32 | ngOnInit() { 33 | } 34 | 35 | accept() { 36 | if (this.confirmValue.onAccept != undefined) { 37 | this.confirmValue.onAccept(); 38 | } 39 | this.dialogRef.close(); 40 | } 41 | 42 | reject() { 43 | if (this.confirmValue.onReject != undefined) { 44 | this.confirmValue.onReject(); 45 | } 46 | this.dialogRef.close(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/app/modules/mc-confirm/mc-confirm.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from "@angular/core"; 2 | import { McConfirmService } from "./mc-confirm.service"; 3 | import { McConfirmComponent } from "./mc-confirm.component"; 4 | import { CommonModule } from "@angular/common"; 5 | import { MatIconModule } from "@angular/material/icon"; 6 | import { FlexLayoutModule } from "@angular/flex-layout"; 7 | import { 8 | MatDialogModule, 9 | MatDialogRef, 10 | MAT_DIALOG_DATA 11 | } from "@angular/material/dialog"; 12 | import { MatButtonModule, MatSnackBarModule } from "@angular/material"; 13 | @NgModule({ 14 | imports: [ 15 | CommonModule, 16 | MatDialogModule, 17 | MatButtonModule, 18 | MatSnackBarModule, 19 | MatIconModule, 20 | FlexLayoutModule 21 | ], 22 | declarations: [McConfirmComponent], 23 | providers: [ 24 | McConfirmService, 25 | { provide: MAT_DIALOG_DATA, useValue: {} }, 26 | { provide: MatDialogRef, useValue: {} } 27 | ], 28 | exports: [McConfirmComponent], 29 | entryComponents: [McConfirmComponent] 30 | }) 31 | export class McConfirmModule {} 32 | 33 | export { McConfirmService } from "./mc-confirm.service"; 34 | -------------------------------------------------------------------------------- /src/app/modules/mc-confirm/mc-confirm.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | import { Observable } from 'rxjs'; 3 | import { Confirm } from "./confirm.interface"; 4 | import { McConfirmComponent } from './mc-confirm.component'; 5 | import { MatDialog } from '@angular/material/dialog'; 6 | import { MatSnackBar } from '@angular/material'; 7 | 8 | @Injectable() 9 | export class McConfirmService { 10 | 11 | constructor( 12 | public _dialog: MatDialog, 13 | public _snackBar: MatSnackBar 14 | ) {} 15 | openDialog(confirmValue) { 16 | const dialogRef = this._dialog.open(McConfirmComponent, { 17 | data: confirmValue, 18 | disableClose:true 19 | }); 20 | 21 | dialogRef.afterClosed().subscribe(result => { 22 | console.log('The dialog was closed'); 23 | }); 24 | 25 | } 26 | confirm(confirmValue: any) { 27 | this.openDialog(confirmValue); 28 | } 29 | prompt (confirmValue: any) { 30 | if (typeof confirmValue == 'string') { 31 | confirmValue = { 32 | message:confirmValue, 33 | option:{ 34 | promptOnly:true,title:'提示' 35 | } 36 | } 37 | } else { 38 | confirmValue.option = Object.assign({},confirmValue.option,{promptOnly:true,title:'提示'}); 39 | } 40 | this.openDialog(confirmValue); 41 | } 42 | alert(message,action='关闭') { 43 | this._snackBar.open(message, action, { 44 | duration: 5000, 45 | }); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/app/modules/pipes/pipes.module.spec.ts: -------------------------------------------------------------------------------- 1 | import { PipesModule } from './pipes.module'; 2 | 3 | describe('PipesModule', () => { 4 | let pipesModule: PipesModule; 5 | 6 | beforeEach(() => { 7 | pipesModule = new PipesModule(); 8 | }); 9 | 10 | it('should create an instance', () => { 11 | expect(pipesModule).toBeTruthy(); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /src/app/modules/pipes/pipes.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { KeysPipe } from './pipes/keys.pipe'; 4 | import { SortPipe } from './pipes/sort.pipe'; 5 | import { StatusPipe } from './pipes/status.pipe'; 6 | import { ValuesPipe } from './pipes/values.pipe'; 7 | 8 | 9 | @NgModule({ 10 | imports: [ 11 | CommonModule, 12 | ], 13 | declarations: [ 14 | KeysPipe, 15 | SortPipe, 16 | StatusPipe, 17 | ValuesPipe 18 | ], 19 | exports: [ 20 | KeysPipe, 21 | SortPipe, 22 | StatusPipe, 23 | ValuesPipe 24 | ], 25 | 26 | }) 27 | 28 | export class PipesModule { 29 | static forRoot() { 30 | return { 31 | ngModule: PipesModule, 32 | providers: [], 33 | }; 34 | } 35 | } 36 | 37 | export {KeysPipe} from './pipes/keys.pipe'; 38 | export {SortPipe} from './pipes/sort.pipe'; 39 | export {ValuesPipe} from './pipes/values.pipe'; 40 | export {StatusPipe} from './pipes/status.pipe'; 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/app/modules/pipes/pipes/keys.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import { KeysPipe } from './keys.pipe'; 2 | 3 | describe('KeysPipe', () => { 4 | it('create an instance', () => { 5 | const pipe = new KeysPipe(); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/app/modules/pipes/pipes/keys.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'keys', 5 | pure: false 6 | }) 7 | export class KeysPipe implements PipeTransform { 8 | 9 | transform(value: any, args?: any): any { 10 | let keys = []; 11 | for (let key in value) { 12 | keys.push(key); 13 | } 14 | return keys.sort((a,b)=>(a { 4 | it('create an instance', () => { 5 | const pipe = new SortPipe(); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/app/modules/pipes/pipes/sort.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'sort' 5 | }) 6 | export class SortPipe implements PipeTransform { 7 | 8 | transform(array: any[], field: string): any { 9 | if (field == undefined) { 10 | array.sort((a: any, b: any) => { 11 | if (a < b) { 12 | return -1; 13 | } else if (a > b) { 14 | return 1; 15 | } else { 16 | return 0; 17 | } 18 | }); 19 | } else { 20 | array.sort((a: any, b: any) => { 21 | if (a[field] < b[field]) { 22 | return -1; 23 | } else if (a[field] > b[field]) { 24 | return 1; 25 | } else { 26 | return 0; 27 | } 28 | }); 29 | } 30 | return array; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/app/modules/pipes/pipes/status.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import { StatusPipe } from './status.pipe'; 2 | 3 | describe('StatusPipe', () => { 4 | it('create an instance', () => { 5 | const pipe = new StatusPipe(); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/app/modules/pipes/pipes/status.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'status' 5 | }) 6 | export class StatusPipe implements PipeTransform { 7 | 8 | transform(value: any, args?: any): any { 9 | /*处理状态值--管道*/ 10 | switch(value){ 11 | case 'OPEN': return '开启'; 12 | case 'CLOSE': return '关闭'; 13 | case 'ON' : return '开启'; 14 | case 'OFF' : return '关闭'; 15 | } 16 | 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/app/modules/pipes/pipes/values.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import { ValuesPipe } from './values.pipe'; 2 | 3 | describe('ValuesPipe', () => { 4 | it('create an instance', () => { 5 | const pipe = new ValuesPipe(); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/app/modules/pipes/pipes/values.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'values' 5 | }) 6 | export class ValuesPipe implements PipeTransform { 7 | 8 | transform(value: any, args?: any): any { 9 | let values = []; 10 | for (let key in value) { 11 | values.push(value[key]); 12 | } 13 | return values; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/app/services/login.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import {Observable} from 'rxjs'; 3 | import {Md5} from 'ts-md5'; 4 | import {Subscription} from 'rxjs'; 5 | import {Router} from '@angular/router'; 6 | 7 | import {RestfulService} from './restful.service'; 8 | import {environment} from '../../environments/environment'; 9 | 10 | @Injectable({ 11 | providedIn: 'root' 12 | }) 13 | export class LoginService { 14 | user; 15 | private _tokenChecker: Subscription; 16 | 17 | constructor( 18 | private _restful: RestfulService, 19 | private _router: Router 20 | ) { 21 | } 22 | 23 | /*退出*/ 24 | public doLogout() { 25 | // this._router.navigate([environment.env.token_err_url]); 26 | this._router.navigate(['/login']); 27 | return; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/app/services/restful.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Observable } from 'rxjs'; 3 | 4 | import { HttpClient, HttpHeaders } from '@angular/common/http'; 5 | import { Router } from '@angular/router'; 6 | 7 | import { Md5 } from 'ts-md5'; 8 | import { AutoUnsubscribe } from 'ngx-auto-unsubscribe'; 9 | import { NgxSpinnerService } from 'ngx-spinner'; 10 | 11 | import { environment } from '../../environments/environment'; 12 | @AutoUnsubscribe() 13 | @Injectable({ 14 | providedIn: 'root' 15 | }) 16 | export class RestfulService { 17 | private _url(path='/mdbcli', service = 'mdbcli') { 18 | let upath = environment.env['mdbcli_server']; 19 | let uport = environment.env['mdbcli_port']; 20 | console.log(window.location.hostname); 21 | if (upath === undefined) { 22 | upath = window.location.hostname; 23 | }; 24 | if (uport === undefined) { 25 | uport = '8080'; 26 | } 27 | return 'http://' + upath + ':' + uport + '/' + path.replace(/^\//, ''); 28 | } 29 | constructor( 30 | private _http: HttpClient, 31 | private _router: Router, 32 | private _spinner: NgxSpinnerService 33 | ) { 34 | } 35 | 36 | private filterLines(data) { 37 | let isValidLine=(line) => { 38 | if (line.startsWith('#') || line.startsWith('==') || line=='') { 39 | return false; 40 | } 41 | return true; 42 | } 43 | let jdata = []; 44 | let lines = data.split(/\n/); 45 | lines.forEach(line => { 46 | if (isValidLine(line)) { 47 | jdata.push(line); 48 | } 49 | }); 50 | return jdata.join('\n'); 51 | } 52 | public mdbcli(cmd,args:any='',multiline=false): Observable { 53 | var url = this._url(); 54 | var token = '';//this._userAccess.getToken(); 55 | let astr = (typeof args === 'string')?args:args.join(' '); 56 | let formModel = { 57 | module:'mdb', 58 | cmd: cmd, 59 | args: astr 60 | } 61 | const httpOptions = { 62 | headers: new HttpHeaders({ 63 | 'Content-Type': 'application/json', 64 | }), 65 | }; 66 | return Observable.create(observer => { 67 | this._http.post(url, formModel, {responseType: 'text'}).subscribe(data => { 68 | if ((data == undefined)|| (data == null)) data = ''; 69 | if (multiline) { 70 | observer.next(this.filterLines(data)); 71 | } else { 72 | observer.next(data); 73 | } 74 | observer.complete(); 75 | }, err => { 76 | if (err.status === 401) { // Token Change ,need re login 77 | this._router.navigate([environment.env.token_err_url]); 78 | } else { 79 | observer.error(err); 80 | } 81 | }); 82 | }); 83 | } 84 | 85 | public post(u, p = {}, opt: any = { service: 'mdbcli', block: true }): Observable { 86 | var s = (opt.service == undefined) ? 'service' : opt.service; 87 | var url = this._url(u, s); 88 | var token = '';//this._userAccess.getToken(); 89 | 90 | return Observable.create(observer => { 91 | if (opt.block !== false) { 92 | this._spinner.show(); 93 | } 94 | this._http.post(url, Object.assign(p, { token: token })).subscribe(data => { 95 | if (opt.block !== false) { 96 | this._spinner.hide(); 97 | } 98 | observer.next(data); 99 | observer.complete(); 100 | }, err => { 101 | if (opt.block !== false) { 102 | this._spinner.hide(); 103 | } 104 | if (err.status === 401) { // Token Change ,need re login 105 | this._router.navigate([environment.env.token_err_url]); 106 | } else { 107 | observer.error(err); 108 | } 109 | }); 110 | }); 111 | } 112 | 113 | public get(u, p = {}): Observable { 114 | var url = this._url(u); 115 | var token = '';//this._userAccess.getToken(); 116 | 117 | //return this._http.post(url,Object.assign(p,{token:token})); 118 | return Observable.create(observer => { 119 | this._spinner.show(); 120 | this._http.get(url, p).subscribe(data => { 121 | this._spinner.hide(); 122 | observer.next(data); 123 | observer.complete(); 124 | }, err => { 125 | this._spinner.hide(); 126 | }); 127 | }); 128 | } 129 | 130 | ngOnDestroy() { } 131 | 132 | } 133 | -------------------------------------------------------------------------------- /src/app/services/service.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule, ModuleWithProviders } from '@angular/core'; 2 | import { RestfulService } from './restful.service'; 3 | import { UserService } from './user.service'; 4 | import { ConfigService } from './config.service'; 5 | @NgModule({ 6 | imports: [ 7 | ], 8 | declarations: [ 9 | ], 10 | providers: [ 11 | UserService, 12 | RestfulService, 13 | ConfigService 14 | ], 15 | }) 16 | export class ServiceModule { 17 | } 18 | 19 | export { RestfulService } from './restful.service'; 20 | export { ConfigService } from './config.service'; -------------------------------------------------------------------------------- /src/app/services/user.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Observable } from 'rxjs'; 3 | 4 | @Injectable({ 5 | providedIn: 'root' 6 | }) 7 | export class UserService { 8 | 9 | constructor() { 10 | console.log('User Service Init...'); 11 | } 12 | 13 | public getUsers(): Observable { 14 | let users=[ 15 | {username:'Admin',email:'Admin@maxchaintech.com',phone:'**********',role:1,active:1,createDate:'2018-10-12'}, 16 | {username:'maxchain_1',email:'Admin@maxchaintech.com',phone:'**********',role:1,active:1,createDate:'2018-10-12'}, 17 | {username:'maxchain_2',email:'Admin@maxchaintech.com',phone:'**********',role:1,active:1,createDate:'2018-10-12'}, 18 | {username:'maxchain_3',email:'Admin@maxchaintech.com',phone:'**********',role:1,active:1,createDate:'2018-10-12'}, 19 | {username:'maxchain_4',email:'Admin@maxchaintech.com',phone:'**********',role:1,active:1,createDate:'2018-10-12'} 20 | ] 21 | return Observable.create(observer => { 22 | observer.next(users); 23 | }); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemo-crypto/angular6-material/e387fd39877dd833a171ba3e9227fb2d5b909957/src/assets/.gitkeep -------------------------------------------------------------------------------- /src/assets/environments/environment.json: -------------------------------------------------------------------------------- 1 | { 2 | "mdbcli_server": "172.16.10.201", 3 | "mdbcli_port": "8078" 4 | } 5 | -------------------------------------------------------------------------------- /src/assets/icon/noWatch.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/icon/password.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/icon/watch.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemo-crypto/angular6-material/e387fd39877dd833a171ba3e9227fb2d5b909957/src/assets/images/banner.png -------------------------------------------------------------------------------- /src/assets/images/cop_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemo-crypto/angular6-material/e387fd39877dd833a171ba3e9227fb2d5b909957/src/assets/images/cop_logo.png -------------------------------------------------------------------------------- /src/assets/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemo-crypto/angular6-material/e387fd39877dd833a171ba3e9227fb2d5b909957/src/assets/images/favicon.png -------------------------------------------------------------------------------- /src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemo-crypto/angular6-material/e387fd39877dd833a171ba3e9227fb2d5b909957/src/assets/images/logo.png -------------------------------------------------------------------------------- /src/assets/images/type_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemo-crypto/angular6-material/e387fd39877dd833a171ba3e9227fb2d5b909957/src/assets/images/type_1.png -------------------------------------------------------------------------------- /src/assets/images/type_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemo-crypto/angular6-material/e387fd39877dd833a171ba3e9227fb2d5b909957/src/assets/images/type_2.png -------------------------------------------------------------------------------- /src/assets/images/type_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemo-crypto/angular6-material/e387fd39877dd833a171ba3e9227fb2d5b909957/src/assets/images/type_3.png -------------------------------------------------------------------------------- /src/assets/images/type_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemo-crypto/angular6-material/e387fd39877dd833a171ba3e9227fb2d5b909957/src/assets/images/type_4.png -------------------------------------------------------------------------------- /src/assets/images/type_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemo-crypto/angular6-material/e387fd39877dd833a171ba3e9227fb2d5b909957/src/assets/images/type_5.png -------------------------------------------------------------------------------- /src/assets/images/type_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemo-crypto/angular6-material/e387fd39877dd833a171ba3e9227fb2d5b909957/src/assets/images/type_6.png -------------------------------------------------------------------------------- /src/browserslist: -------------------------------------------------------------------------------- 1 | # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | # For IE 9-11 support, please uncomment the last line of the file and adjust as needed 5 | > 0.5% 6 | last 2 versions 7 | Firefox ESR 8 | not dead 9 | # IE 9-11 -------------------------------------------------------------------------------- /src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true, 3 | env:{ 4 | base_url_href: "/", 5 | mdbcli_path: 'http://172.16.10.54:/', 6 | token_check:600, 7 | token_err_url:'/login', 8 | session_timeout:1200, 9 | }, 10 | 11 | }; 12 | -------------------------------------------------------------------------------- /src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false, 7 | env: { 8 | base_url_href: '/', 9 | token_check: 600, 10 | token_err_url: '/login', 11 | session_timeout: 1200, 12 | }, 13 | }; 14 | 15 | 16 | /* 17 | * In development mode, to ignore zone related error stack frames such as 18 | * `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can 19 | * import the following file, but please comment it out in production mode 20 | * because it will have performance impact when throw error 21 | */ 22 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 23 | -------------------------------------------------------------------------------- /src/environments/environmentLoader.ts: -------------------------------------------------------------------------------- 1 | import { environment as defaultEnvironment } from './environment'; 2 | 3 | export const environmentLoader = new Promise((resolve, reject) => { 4 | 5 | const xmlhttp = new XMLHttpRequest(), 6 | method = 'GET', 7 | url = './assets/environments/environment.json'; 8 | 9 | xmlhttp.open(method, url, true); 10 | 11 | xmlhttp.onload = function() { 12 | if (xmlhttp.status === 200) { 13 | resolve(JSON.parse(xmlhttp.responseText)); 14 | } else { 15 | resolve(defaultEnvironment.env || {}); 16 | } 17 | }; 18 | 19 | xmlhttp.send(); 20 | }); 21 | -------------------------------------------------------------------------------- /src/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemo-crypto/angular6-material/e387fd39877dd833a171ba3e9227fb2d5b909957/src/favicon.png -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 宏链区块链数据库系统 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, '../coverage'), 20 | reports: ['html', 'lcovonly'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false 30 | }); 31 | }; -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import 'hammerjs'; 2 | 3 | import { enableProdMode } from '@angular/core'; 4 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 5 | 6 | import { AppModule } from './app/app.module'; 7 | import { environment } from './environments/environment'; 8 | import { environmentLoader as environmentLoaderPromise } from './environments/environmentLoader'; 9 | 10 | environmentLoaderPromise.then(env => { 11 | if (env.production) { 12 | enableProdMode(); 13 | } 14 | environment.env = env; 15 | platformBrowserDynamic().bootstrapModule(AppModule); 16 | }); 17 | -------------------------------------------------------------------------------- /src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 22 | // import 'core-js/es6/symbol'; 23 | // import 'core-js/es6/object'; 24 | // import 'core-js/es6/function'; 25 | // import 'core-js/es6/parse-int'; 26 | // import 'core-js/es6/parse-float'; 27 | // import 'core-js/es6/number'; 28 | // import 'core-js/es6/math'; 29 | // import 'core-js/es6/string'; 30 | // import 'core-js/es6/date'; 31 | // import 'core-js/es6/array'; 32 | // import 'core-js/es6/regexp'; 33 | // import 'core-js/es6/map'; 34 | // import 'core-js/es6/weak-map'; 35 | // import 'core-js/es6/set'; 36 | 37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 38 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 39 | 40 | /** IE10 and IE11 requires the following for the Reflect API. */ 41 | // import 'core-js/es6/reflect'; 42 | 43 | 44 | /** Evergreen browsers require these. **/ 45 | // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. 46 | import 'core-js/es7/reflect'; 47 | 48 | 49 | /** 50 | * Web Animations `@angular/platform-browser/animations` 51 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 52 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 53 | **/ 54 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 55 | 56 | /** 57 | * By default, zone.js will patch all possible macroTask and DomEvents 58 | * user can disable parts of macroTask/DomEvents patch by setting following flags 59 | */ 60 | 61 | // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 62 | // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 63 | // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 64 | 65 | /* 66 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 67 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 68 | */ 69 | // (window as any).__Zone_enable_cross_context_check = true; 70 | 71 | /*************************************************************************************************** 72 | * Zone JS is required by default for Angular itself. 73 | */ 74 | import 'zone.js/dist/zone'; // Included with Angular CLI. 75 | 76 | 77 | 78 | /*************************************************************************************************** 79 | * APPLICATION IMPORTS 80 | */ 81 | -------------------------------------------------------------------------------- /src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | @import 'material-design-icons/iconfont/material-icons.css'; 3 | 4 | 5 | .href:hover { 6 | cursor: pointer; 7 | } 8 | .mat-form { 9 | min-width: 150px; 10 | width: 100%; 11 | max-width: 100%; 12 | margin-bottom: 2rem; 13 | } 14 | .mat-full-width { 15 | width: 100% 16 | } 17 | 18 | /*content最小高度*/ 19 | .page-container { 20 | min-height: 80vh; 21 | } 22 | 23 | .dialog-icon { 24 | margin-top:4px; 25 | margin-right: .5rem; 26 | } 27 | h3.mat-headline { 28 | margin-bottom: 0px; 29 | } 30 | 31 | mat-radio-button+mat-radio-button { 32 | margin-left: .5rem; 33 | } 34 | mat-dialog-content { 35 | padding-bottom: 2rem; 36 | } 37 | .mat-table { 38 | width:100%; 39 | } 40 | 41 | 42 | /*menu_top --- css*/ 43 | div.menu_top button.mat-menu-item { 44 | height: 64px; 45 | } 46 | .mat-elevation-z4 button.first_menu a mat-icon{ 47 | color: #fff; 48 | margin-right: 2px; 49 | margin-top: -3px; 50 | } 51 | div.menu_top a{ 52 | text-decoration:none; 53 | color: #fff; 54 | } 55 | /*div.menu_top .cdk-overlay-pane{ 56 | margin-top: 64px; 57 | }*/ 58 | .mat-elevation-z4 .mat-icon-button .mat-icon, .mat-icon-button i { 59 | line-height: 22px; 60 | } 61 | .mat-elevation-z4 .menu_top button.first_menu:hover{ 62 | background: #227aac;; 63 | } 64 | 65 | .mat-elevation-z4 .menu_top button.active{ 66 | background: #227aac; 67 | } 68 | 69 | 70 | /*MDB-body*/ 71 | div.MDB-body{ 72 | background-color: whitesmoke; 73 | } 74 | mat-card.page-container{ 75 | border-radius: 8px; 76 | } 77 | 78 | /*表单字段长度--折行梳处理*/ 79 | td.mat-cell{ 80 | word-break: break-all; 81 | } 82 | 83 | /*当前路径*/ 84 | div.curpath{ 85 | height: 30px; 86 | margin-bottom: 25px; 87 | padding-top: 80px; 88 | } 89 | div.curpath mat-icon{ 90 | font-size: 20px; 91 | } 92 | 93 | /*table-list tr hover-css*/ 94 | tr.example-element-row:not(.example-expanded-row):hover { 95 | background: #f5e9d6; 96 | } 97 | tr.example-element-row:not(.example-expanded-row):active { 98 | background: #efefef; 99 | } 100 | 101 | /*弹出框--css*/ 102 | form.mat-form div.option{ 103 | float: left; 104 | margin-right: 15px; 105 | } 106 | form.mat-form label.options{ 107 | float: left; 108 | margin-right: 15px; 109 | } 110 | mat-radio-button+mat-radio-button { 111 | margin-left: .5rem; 112 | } 113 | mat-dialog-content { 114 | padding-bottom: 2rem; 115 | } 116 | .mat-form { 117 | margin-bottom: 2rem; 118 | } 119 | mat-dialog-container.mat-dialog-container{ 120 | border-radius:10px; 121 | } 122 | mat-card.page-container tr.mat-header-row th{ 123 | font-size: 14px; 124 | color: #04131f; 125 | } 126 | 127 | /*mat-chip*/ 128 | mat-chip{ 129 | border-radius: 5px; 130 | padding: 5px; 131 | } 132 | 133 | div.titleTab{ 134 | padding-top: 20px; 135 | } 136 | -------------------------------------------------------------------------------- /src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /src/theme/theme.scss: -------------------------------------------------------------------------------- 1 | @import '~@angular/material/theming'; 2 | @import '../app/auth/auth.component.scss'; 3 | @import '../app/core/sidemenu/sidemenu.component.scss'; 4 | @import '../app/core/sidemenu-item/sidemenu-item.component.scss'; 5 | 6 | $mat-light-theme-background: ( 7 | status-bar: map_get($mat-grey, 300), 8 | app-bar: map_get($mat-grey, 100), 9 | 10 | background: map_get($mat-indigo, 50), 11 | hover: rgba(black, 0.04), // TODO(kara): check style with Material Design UX 12 | card: white, 13 | dialog: white, 14 | disabled-button: $black-12-opacity, 15 | raised-button: white, 16 | focused-button: $black-6-opacity, 17 | selected-button: map_get($mat-grey, 300), 18 | selected-disabled-button: map_get($mat-grey, 400), 19 | disabled-button-toggle: map_get($mat-grey, 200), 20 | unselected-chip: map_get($mat-grey, 300), 21 | disabled-list-option: map_get($mat-grey, 200), 22 | ); 23 | 24 | @include mat-core(); 25 | 26 | $primary : $mat-light-blue; 27 | // $primary : $mat-blue-grey; 28 | $accent : $mat-orange; 29 | $warn : $mat-red; 30 | 31 | 32 | 33 | $primary-app-primary: mat-palette($primary , 600); 34 | $primary-app-accent: mat-palette($accent , 900); 35 | $primary-app-warn: mat-palette($warn ); 36 | $cdk-theme: mat-light-theme($primary-app-primary, $primary-app-accent,$primary-app-warn); 37 | 38 | cdk-sidemenu{ 39 | $sidemenu-app-primary: mat-palette($primary , 400); 40 | $sidemenu-app-accent: mat-palette($accent , 900); 41 | $sidemenu-app-warn: mat-palette($warn ); 42 | $cdk-sidemenu-theme: mat-dark-theme($sidemenu-app-primary, $sidemenu-app-accent,$sidemenu-app-warn); 43 | @include mat-list-theme($cdk-sidemenu-theme); 44 | } 45 | 46 | 47 | cdk-sidemenu-item{ 48 | @include sidemenu-item($cdk-theme,20px) 49 | } 50 | 51 | @include angular-material-theme($cdk-theme); 52 | @include auth($cdk-theme); 53 | 54 | html { 55 | height:100%; 56 | } 57 | body{ 58 | padding: 0px !important; 59 | margin: 0px !important; 60 | height:100%; 61 | } 62 | .components-container-gt-xs { 63 | padding: 20px; 64 | // background-color: #fdfdfd; 65 | } 66 | .components-container-xs { 67 | padding: 5px !important; 68 | // background-color: #fdfdfd; 69 | } 70 | .component-preview { 71 | padding: 20px; 72 | } 73 | .ps-content { 74 | height: 100%; 75 | } 76 | 77 | .loader-container { 78 | background-color: white; 79 | width: 100vw; 80 | height: 100vh; 81 | z-index: 2000; 82 | position: absolute; 83 | 84 | -moz-animation: cssAnimation 1s ease-in 3s forwards; 85 | /* Firefox */ 86 | animation: cssAnimation 1s ease-in 3s forwards; 87 | /* Safari and Chrome */ 88 | -o-animation: cssAnimation 1s ease-in 3s forwards; 89 | /* Opera */ 90 | animation: cssAnimation 1s ease-in 3s forwards; 91 | animation-fill-mode: forwards; 92 | animation-fill-mode: forwards; 93 | } 94 | 95 | @keyframes cssAnimation { 96 | to { 97 | opacity:0; 98 | display: none; 99 | visibility:hidden; 100 | } 101 | } 102 | @keyframes cssAnimation { 103 | to { 104 | visibility:hidden; 105 | opacity:0; 106 | display: none; 107 | } 108 | } 109 | 110 | 111 | 112 | .spinner { 113 | margin: 50vh auto 0; 114 | width: 70px; 115 | text-align: center; 116 | } 117 | 118 | .spinner > div { 119 | width: 18px; 120 | height: 18px; 121 | 122 | 123 | border-radius: 100%; 124 | display: inline-block; 125 | animation: sk-bouncedelay 1.4s infinite ease-in-out both; 126 | animation: sk-bouncedelay 1.4s infinite ease-in-out both; 127 | } 128 | 129 | .bounce3 { 130 | background-color: orange; 131 | } 132 | 133 | .spinner .bounce1 { 134 | background-color: blue; 135 | animation-delay: -0.32s; 136 | animation-delay: -0.32s; 137 | } 138 | 139 | .spinner .bounce2 { 140 | background-color: red; 141 | animation-delay: -0.16s; 142 | animation-delay: -0.16s; 143 | } 144 | 145 | 146 | 147 | @keyframes sk-bouncedelay { 148 | 0%, 80%, 100% { transform: scale(0) } 149 | 40% { transform: scale(1.0) } 150 | } 151 | 152 | @keyframes sk-bouncedelay { 153 | 0%, 80%, 100% { 154 | transform: scale(0); 155 | transform: scale(0); 156 | } 40% { 157 | transform: scale(1.0); 158 | transform: scale(1.0); 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /src/theme/typography.scss: -------------------------------------------------------------------------------- 1 | @import '~@angular/material/theming'; 2 | 3 | $custom-typography: mat-typography-config( 4 | $font-family: 'Roboto, "Helvetica Neue", sans-serif', 5 | $display-4: mat-typography-level(112px, 112px, 300), 6 | $display-3: mat-typography-level(56px, 56px, 300), 7 | $display-2: mat-typography-level(45px, 48px, 300), 8 | $display-1: mat-typography-level(34px, 40px, 300), 9 | $headline: mat-typography-level(14px, 32px, 300), 10 | $title: mat-typography-level(20px, 32px, 300), 11 | $subheading-2: mat-typography-level(16px, 20px, 300), 12 | $subheading-1: mat-typography-level(15px, 24px, 300), 13 | $body-2: mat-typography-level(14px, 24px, 300), 14 | $body-1: mat-typography-level(14px, 20px, 300), 15 | $caption: mat-typography-level(12px, 20px, 300), 16 | $button: mat-typography-level(14px, 14px, 300), 17 | $input: mat-typography-level(16px, 1.125, 300) 18 | ); 19 | -------------------------------------------------------------------------------- /src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "es2015", 6 | "types": [] 7 | }, 8 | "exclude": [ 9 | "src/test.ts", 10 | "**/*.spec.ts" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "module": "commonjs", 6 | "types": [ 7 | "jasmine", 8 | "node" 9 | ] 10 | }, 11 | "files": [ 12 | "test.ts", 13 | "polyfills.ts" 14 | ], 15 | "include": [ 16 | "**/*.spec.ts", 17 | "**/*.d.ts" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /src/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "app", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "app", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "moduleResolution": "node", 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "target": "es5", 12 | "typeRoots": [ 13 | "node_modules/@types" 14 | ], 15 | "lib": [ 16 | "es2017", 17 | "dom" 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "arrow-return-shorthand": true, 7 | "callable-types": true, 8 | "class-name": true, 9 | "comment-format": [ 10 | true, 11 | "check-space" 12 | ], 13 | "curly": true, 14 | "deprecation": { 15 | "severity": "warn" 16 | }, 17 | "eofline": true, 18 | "forin": true, 19 | "import-blacklist": [ 20 | true, 21 | "rxjs/Rx" 22 | ], 23 | "import-spacing": true, 24 | "indent": [ 25 | true, 26 | "spaces" 27 | ], 28 | "interface-over-type-literal": true, 29 | "label-position": true, 30 | "max-line-length": [ 31 | true, 32 | 140 33 | ], 34 | "member-access": false, 35 | "member-ordering": [ 36 | true, 37 | { 38 | "order": [ 39 | "static-field", 40 | "instance-field", 41 | "static-method", 42 | "instance-method" 43 | ] 44 | } 45 | ], 46 | "no-arg": true, 47 | "no-bitwise": true, 48 | "no-console": [ 49 | true, 50 | "debug", 51 | "info", 52 | "time", 53 | "timeEnd", 54 | "trace" 55 | ], 56 | "no-construct": true, 57 | "no-debugger": true, 58 | "no-duplicate-super": true, 59 | "no-empty": false, 60 | "no-empty-interface": true, 61 | "no-eval": true, 62 | "no-inferrable-types": [ 63 | true, 64 | "ignore-params" 65 | ], 66 | "no-misused-new": true, 67 | "no-non-null-assertion": true, 68 | "no-shadowed-variable": true, 69 | "no-string-literal": false, 70 | "no-string-throw": true, 71 | "no-switch-case-fall-through": true, 72 | "no-trailing-whitespace": true, 73 | "no-unnecessary-initializer": true, 74 | "no-unused-expression": true, 75 | "no-use-before-declare": true, 76 | "no-var-keyword": true, 77 | "object-literal-sort-keys": false, 78 | "one-line": [ 79 | true, 80 | "check-open-brace", 81 | "check-catch", 82 | "check-else", 83 | "check-whitespace" 84 | ], 85 | "prefer-const": true, 86 | "quotemark": [ 87 | true, 88 | "single" 89 | ], 90 | "radix": true, 91 | "semicolon": [ 92 | true, 93 | "always" 94 | ], 95 | "triple-equals": [ 96 | false, 97 | "allow-null-check" 98 | ], 99 | "typedef-whitespace": [ 100 | true, 101 | { 102 | "call-signature": "nospace", 103 | "index-signature": "nospace", 104 | "parameter": "nospace", 105 | "property-declaration": "nospace", 106 | "variable-declaration": "nospace" 107 | } 108 | ], 109 | "unified-signatures": true, 110 | "variable-name": false, 111 | "whitespace": [ 112 | true, 113 | "check-branch", 114 | "check-decl", 115 | "check-operator", 116 | "check-separator", 117 | "check-type" 118 | ], 119 | "no-output-on-prefix": true, 120 | "use-input-property-decorator": true, 121 | "use-output-property-decorator": true, 122 | "use-host-property-decorator": true, 123 | "no-input-rename": true, 124 | "no-output-rename": true, 125 | "use-life-cycle-interface": true, 126 | "use-pipe-transform-interface": true, 127 | "component-class-suffix": true, 128 | "directive-class-suffix": true 129 | } 130 | } 131 | --------------------------------------------------------------------------------