Merge pull request #7884 from gabrielbazan7/feat/loggerfilter

[V4] FEAT: filter options and options filter
This commit is contained in:
Gustavo Maximiliano Cortez 2018-01-18 12:43:12 -03:00 committed by GitHub
commit 5f66c1c311
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 111 additions and 47 deletions

View File

@ -371,7 +371,7 @@ export class ConfirmPage {
tx.txp[wallet.id] = txp; tx.txp[wallet.id] = txp;
this.tx = tx; this.tx = tx;
this.logger.debug('Confirm. TX Fully Updated for wallet:' + wallet.id, tx); this.logger.debug('Confirm. TX Fully Updated for wallet:' + wallet.id, JSON.stringify(tx));
return resolve(); return resolve();
}).catch((err: any) => { }).catch((err: any) => {
return reject(err); return reject(err);

View File

@ -2,7 +2,7 @@
<ion-navbar> <ion-navbar>
<ion-title>{{'Session Log' | translate}}</ion-title> <ion-title>{{'Session Log' | translate}}</ion-title>
<ion-buttons start> <ion-buttons end>
<button (click)="showOptionsMenu()" ion-button icon-only> <button (click)="showOptionsMenu()" ion-button icon-only>
<ion-icon name="more"></ion-icon> <ion-icon name="more"></ion-icon>
</button> </button>
@ -11,23 +11,27 @@
</ion-header> </ion-header>
<ion-content> <ion-content>
<ion-list> <div *ngIf="filteredLogs && filteredLogs.length == 0" class="no-entries-message">
<span translate>No entries for this log level</span>.
</div>
<ion-list text-wrap>
<ion-item class="log-entry"> <ion-item class="log-entry">
<div *ngIf="filteredLogs && filteredLogs.length == 0">
<span translate>No entries for this log level</span>.
<a (click)="showOptionsMenu()" translate>Filter setting</a>.
</div>
<div *ngIf="filteredLogs && filteredLogs.length > 0"> <div *ngIf="filteredLogs && filteredLogs.length > 0">
<div *ngFor="let l of filteredLogs"> <div *ngFor="let l of filteredLogs">
<span [ngClass]="{'energized': l.level=='warn', 'dark': l.level=='debug', 'positive': l.level=='info', 'assertive': l.level=='error'}"> <span [ngClass]="{'energized': l.level=='warn', 'dark': l.level=='debug', 'positive': l.level=='info', 'assertive': l.level=='error'}">
<span class="log-timestamp">[{{l.timestamp}}]</span> <span class="log-timestamp">[{{l.timestamp}}]</span>
<span class="log-level">[{{l.level}}]</span> {{l.msg}} <span class="log-level">[{{l.level}}]</span> {{l.msg}}
</span> </span>
</div> </div>
</div> </div>
</ion-item> </ion-item>
</ion-list> </ion-list>
<!-- <log-options log-options-show="showOptions" log-options="logOptions" log-options-fill-class="fillClass" log-options-on-select="setOptionSelected" </ion-content>
log-options-on-copy="prepareLogs" log-options-on-send="sendLogs"> <ion-footer>
</log-options> --> <div class="filter-container">
</ion-content> <div class="labels">
<div *ngFor="let option of logOptions | keys" [ngClass]="{'info-label': option.value.weight==3}" translate>{{option.value.label}}</div>
</div>
<ion-range min="1" max="4" step="1" snaps="true" color="secondary" [(ngModel)]="filterValue" (ionChange)="setOptionSelected(filterValue)"></ion-range>
</div>
</ion-footer>

View File

@ -22,4 +22,22 @@ page-session-log {
.assertive { .assertive {
color: color($colors,danger); color: color($colors,danger);
} }
.filter-container {
padding: 20px;
.labels {
display: flex;
justify-content: space-between;
.info-label {
margin-right: -10px;
}
}
}
.no-entries-message {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
}
} }

View File

@ -1,4 +1,7 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { DOCUMENT } from "@angular/platform-browser";
import { Inject } from '@angular/core';
import { ActionSheetController, ToastController } from 'ionic-angular';
//native //native
import { SocialSharing } from '@ionic-native/social-sharing'; import { SocialSharing } from '@ionic-native/social-sharing';
@ -6,6 +9,7 @@ import { SocialSharing } from '@ionic-native/social-sharing';
//providers //providers
import { ConfigProvider } from '../../../../providers/config/config'; import { ConfigProvider } from '../../../../providers/config/config';
import { Logger } from '../../../../providers/logger/logger'; import { Logger } from '../../../../providers/logger/logger';
import { PlatformProvider } from '../../../../providers/platform/platform';
import * as _ from 'lodash'; import * as _ from 'lodash';
@ -16,22 +20,27 @@ import * as _ from 'lodash';
export class SessionLogPage { export class SessionLogPage {
private config: any; private config: any;
private logLevels: any; private dom: Document;
private selectedLevel: any;
public logOptions: any; public logOptions: any;
public filteredLogs: Array<any>; public filteredLogs: Array<any>;
public fillClass: any; public filterValue: number;
public showOptions: boolean; public isCordova: boolean;
constructor( constructor(
@Inject(DOCUMENT) dom: Document,
private configProvider: ConfigProvider, private configProvider: ConfigProvider,
private logger: Logger, private logger: Logger,
private socialSharing: SocialSharing private socialSharing: SocialSharing,
private actionSheetCtrl: ActionSheetController,
private toastCtrl: ToastController,
private platformProvider: PlatformProvider
) { ) {
this.dom = dom;
this.config = this.configProvider.get(); this.config = this.configProvider.get();
this.logLevels = this.logger.getLevels(); this.isCordova = this.platformProvider.isCordova;
this.logOptions = _.keyBy(this.logLevels, 'level'); let logLevels: any = this.logger.getLevels();
this.logOptions = _.keyBy(logLevels, 'weight');
} }
ionViewDidLoad() { ionViewDidLoad() {
@ -39,28 +48,21 @@ export class SessionLogPage {
} }
ionViewWillEnter() { ionViewWillEnter() {
this.selectedLevel = _.has(this.config, 'log.filter') ? this.logger.getLevel(this.config.log.filter) : this.logger.getDefaultLevel(); let selectedLevel: any = _.has(this.config, 'log.filter') ? this.logger.getWeight(this.config.log.filter) : this.logger.getDefaultWeight();
this.setOptionSelected(this.selectedLevel.level); this.filterValue = selectedLevel.weight;
this.filterLogs(this.selectedLevel.weight); this.setOptionSelected(selectedLevel.weight);
this.filterLogs(selectedLevel.weight);
} }
private filterLogs(weight: number): void { private filterLogs(weight: number): void {
this.filteredLogs = this.logger.get(weight); this.filteredLogs = this.logger.get(weight);
} }
public setOptionSelected(level: string): void { public setOptionSelected(weight: number): void {
let weight = this.logOptions[level].weight;
this.fillClass = 'fill-bar-' + level;
this.filterLogs(weight); this.filterLogs(weight);
_.each(this.logOptions, (opt) => {
opt.selected = opt.weight <= weight ? true : false;
opt.head = opt.weight == weight;
});
// Save the setting.
let opts = { let opts = {
log: { log: {
filter: level filter: weight
} }
}; };
this.configProvider.set(opts); this.configProvider.set(opts);
@ -76,6 +78,20 @@ export class SessionLogPage {
return log; return log;
} }
private copyToClipboard() {
let textarea = this.dom.createElement('textarea');
this.dom.body.appendChild(textarea);
textarea.value = this.prepareLogs();
textarea.select();
this.dom.execCommand('copy');
let message = 'Copied to clipboard' //TODO gettextcatalog
let showSuccess = this.toastCtrl.create({
message: message,
duration: 1000,
});
showSuccess.present();
}
public sendLogs(): void { public sendLogs(): void {
let body = this.prepareLogs(); let body = this.prepareLogs();
@ -90,8 +106,32 @@ export class SessionLogPage {
} }
public showOptionsMenu(): void { public showOptionsMenu(): void {
this.showOptions = true;
//TODO show filter menu
}
let copyText = 'Copy to clipboard' //TODO gettextcatalog
let emailText = 'Send by email' //TODO gettextcatalog
let button = [];
if (this.isCordova) {
button = [{
text: emailText,
handler: () => {
this.sendLogs()
}
}];
}
else {
button = [{
text: copyText,
handler: () => {
this.copyToClipboard();
}
}];
}
let actionSheet = this.actionSheetCtrl.create({
title: '',
buttons: button
});
actionSheet.present();
}
} }

View File

@ -226,8 +226,9 @@ export class WalletExportPage {
var ew = backup; var ew = backup;
if (!ew) return; if (!ew) return;
this.clipboard.copy(ew); this.clipboard.copy(ew);
let copyMessage = 'Copied to clipboard' //TODO gettextcatalog
let showSuccess = this.toastCtrl.create({ let showSuccess = this.toastCtrl.create({
message: 'Copied to clipboard', message: copyMessage,
duration: 1000, duration: 1000,
}); });
showSuccess.present(); showSuccess.present();
@ -235,8 +236,9 @@ export class WalletExportPage {
}; };
public sendWalletBackup(): void { public sendWalletBackup(): void {
let preparingMessage = 'Preparing backup...' //TODO gettextcatalog
let showSuccess = this.toastCtrl.create({ let showSuccess = this.toastCtrl.create({
message: 'Preparing backup...', message: preparingMessage,
duration: 1000, duration: 1000,
}); });
showSuccess.present(); showSuccess.present();

View File

@ -20,10 +20,10 @@ export class Logger {
this.logger.info('Logger initialized.'); this.logger.info('Logger initialized.');
this.logs = []; this.logs = [];
this.levels = [ this.levels = [
{ level: 'error', weight: 0, label: 'Error' }, { level: 'error', weight: 1, label: 'Error' },
{ level: 'warn', weight: 1, label: 'Warning' }, { level: 'warn', weight: 2, label: 'Warning' },
{ level: 'info', weight: 2, label: 'Info', default: true }, { level: 'info', weight: 3, label: 'Info', default: true },
{ level: 'debug', weight: 3, label: 'Debug' } { level: 'debug', weight: 4, label: 'Debug' }
]; ];
// Create an array of level weights for performant filtering. // Create an array of level weights for performant filtering.
@ -62,13 +62,13 @@ export class Logger {
return this.levels; return this.levels;
}; };
public getLevel(level): any { public getWeight(weight): any {
return _.find(this.levels, (l) => { return _.find(this.levels, (l) => {
return l.level == level; return l.weight == weight;
}); });
}; };
public getDefaultLevel(): any { public getDefaultWeight(): any {
return _.find(this.levels, (l) => { return _.find(this.levels, (l) => {
return l.default; return l.default;
}); });

View File

@ -146,7 +146,7 @@ export class ProfileProvider {
}); });
wallet.on('notification', (n: any) => { wallet.on('notification', (n: any) => {
this.logger.debug('BWC Notification:', n); this.logger.debug('BWC Notification:', JSON.stringify(n));
if (n.type == "NewBlock" && n.data.network == "testnet") { if (n.type == "NewBlock" && n.data.network == "testnet") {
this.throttledBwsEvent(n, wallet); this.throttledBwsEvent(n, wallet);
@ -707,7 +707,7 @@ export class ProfileProvider {
if (showOpts.extendedPrivateKey) showOpts.extendedPrivateKey = '[hidden]'; if (showOpts.extendedPrivateKey) showOpts.extendedPrivateKey = '[hidden]';
if (showOpts.mnemonic) showOpts.mnemonic = '[hidden]'; if (showOpts.mnemonic) showOpts.mnemonic = '[hidden]';
this.logger.debug('Creating Wallet:', showOpts); this.logger.debug('Creating Wallet:', JSON.stringify(showOpts));
setTimeout(() => { setTimeout(() => {
this.seedWallet(opts).then((walletClient: any) => { this.seedWallet(opts).then((walletClient: any) => {