merchant dashboard incomplete

merchant dashboard incomplete
This commit is contained in:
Shahana Farooqui 2019-12-10 11:15:35 -05:00
parent 5b5a0428bd
commit c0dd171873
27 changed files with 240 additions and 27 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -9,8 +9,8 @@
<link rel="icon" type="image/png" sizes="32x32" href="assets/images/favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="assets/images/favicon/favicon-16x16.png">
<link rel="manifest" href="assets/images/favicon/site.webmanifest">
<link rel="stylesheet" href="styles.b99cd8a685fbb10e0d1c.css"></head>
<link rel="stylesheet" href="styles.299bd849df2ee75dd3f7.css"></head>
<body>
<rtl-app></rtl-app>
<script src="runtime.97d50eae24ff822dc543.js"></script><script src="polyfills-es5.92f4069201c83f4833ef.js" nomodule></script><script src="polyfills.5ddcccdb990eb395f306.js"></script><script src="main.33f3f158c10ca59b7ee4.js"></script></body>
<script src="runtime.2e0b6727a990b37572f4.js"></script><script src="polyfills-es5.92f4069201c83f4833ef.js" nomodule></script><script src="polyfills.5ddcccdb990eb395f306.js"></script><script src="main.045a6cef456c662edb82.js"></script></body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
!function(e){function r(r){for(var n,i,a=r[0],c=r[1],f=r[2],p=0,s=[];p<a.length;p++)o[i=a[p]]&&s.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(l&&l(r);s.length;)s.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,a=1;a<t.length;a++)0!==o[t[a]]&&(n=!1);n&&(u.splice(r--,1),e=i(i.s=t[0]))}return e}var n={},o={0:0},u=[];function i(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,i),t.l=!0,t.exports}i.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+""+({}[e]||e)+"."+{1:"9e71a210a8bdc5ba9df9",6:"1df8cc6666448eb1b667",7:"cee151d78befebb72c4b"}[e]+".js"}(e);var c=new Error;u=function(r){a.onerror=a.onload=null,clearTimeout(f);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var f=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(r)},i.m=e,i.c=n,i.d=function(e,r,t){i.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,r){if(1&r&&(e=i(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(i.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)i.d(t,n,(function(r){return e[r]}).bind(null,n));return t},i.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(r,"a",r),r},i.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},i.p="",i.oe=function(e){throw console.error(e),e};var a=window.webpackJsonp=window.webpackJsonp||[],c=a.push.bind(a);a.push=r,a=a.slice();for(var f=0;f<a.length;f++)r(a[f]);var l=c;t()}([]);

View File

@ -1 +0,0 @@
!function(e){function r(r){for(var n,a,i=r[0],c=r[1],f=r[2],p=0,s=[];p<i.length;p++)o[a=i[p]]&&s.push(o[a][0]),o[a]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(l&&l(r);s.length;)s.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++)0!==o[t[i]]&&(n=!1);n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={0:0},u=[];function a(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,i=document.createElement("script");i.charset="utf-8",i.timeout=120,a.nc&&i.setAttribute("nonce",a.nc),i.src=function(e){return a.p+""+({}[e]||e)+"."+{1:"9e71a210a8bdc5ba9df9",6:"f8549065015b340da576",7:"bb13bd7e7c6fc23f4ea7"}[e]+".js"}(e);var c=new Error;u=function(r){i.onerror=i.onload=null,clearTimeout(f);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var f=setTimeout((function(){u({type:"timeout",target:i})}),12e4);i.onerror=i.onload=u,document.head.appendChild(i)}return Promise.all(r)},a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,(function(r){return e[r]}).bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="",a.oe=function(e){throw console.error(e),e};var i=window.webpackJsonp=window.webpackJsonp||[],c=i.push.bind(i);i.push=r,i=i.slice();for(var f=0;f<i.length;f++)r(i[f]);var l=c;t()}([]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -23,3 +23,26 @@
<ng-template #noChannelBlock>
<div fxLayout="column" fxFlex="100" class="w-100 mt-2">No channels available.</div>
</ng-template>
<!-- <div fxLayout="column" fxLayoutAlign="space-between start" fxFlex="100">
<div fxLayout="column" fxFlex="5" fxLayoutAlign="start start" class="w-100">
<div fxLayout="row" fxLayoutAlign="space-between start" class="w-100">
<mat-hint fxFlex="50" fxLayoutAlign="start center" class="font-size-80"><strong class="font-weight-900">Local:</strong>{{channelBalances.localBalance || 0 | number}} Sats</mat-hint>
<mat-hint fxFlex="50" fxLayoutAlign="end center" class="font-size-80"><strong class="font-weight-900">Remote:</strong>{{channelBalances.remoteBalance || 0 | number}} Sats</mat-hint>
</div>
<mat-progress-bar class="dashboard-progress-bar" mode="determinate" value="{{channelBalances.localBalance && channelBalances.localBalance > 0 ? ((+channelBalances.localBalance/((+channelBalances.localBalance)+(+channelBalances.remoteBalance)))*100) : 0}}"></mat-progress-bar>
<mat-divider class="w-100 dashboard-divider"></mat-divider>
</div>
<div fxLayout="column" fxFlex="92" fxFlex.lt-md="85" fxLayoutAlign="start start" class="channels-capacity-scroll" perfectScrollbar>
<div fxLayout="column" fxFlex="100" class="w-100" *ngIf="allChannels && allChannels.length > 0; else noChannelBlock">
<ngx-charts-bar-horizontal-stacked
[xAxis]="true"
[yAxis]="true"
[noBarWhenZero]="false"
[showDataLabel]="true"
[results]="allChannelBalances"></ngx-charts-bar-horizontal-stacked>
</div>
</div>
</div>
<ng-template #noChannelBlock>
<div fxLayout="column" fxFlex="100" class="w-100 mt-2">No channels available.</div>
</ng-template> -->

View File

@ -9,9 +9,17 @@ import { Channel } from '../../../shared/models/lndModels';
export class ChannelCapacityInfoComponent implements OnChanges {
@Input() channelBalances: {localBalance: number, remoteBalance: number};
@Input() allChannels: Channel[];
allChannelBalances = [];
constructor() {}
ngOnChanges() {}
ngOnChanges() {
// this.allChannelBalances = [];
// this.allChannels.forEach((channel, idx) => {
// if(idx < 20) {
// this.allChannelBalances.push({"name": ((idx + 1) + ' ' + channel.remote_alias), "series": [{ "name": "Local Balance", "value": -channel.local_balance}, {"name": "Remote Balance","value": +channel.remote_balance}]});
// }
// });
}
}

View File

@ -0,0 +1,23 @@
<div fxLayout="column" fxLayoutAlign="space-between start" fxFlex="100">
<div fxLayout="column" fxFlex="8" fxLayoutAlign="end start" class="w-100">
<h2>{{totalLiquidity | number}} Sats</h2>
<h4>Max Transaction Amount: {{maxTransactionAmount | number}} Sats</h4>
<mat-divider class="w-100 dashboard-divider mt-2"></mat-divider>
</div>
<div fxLayout="column" fxFlex="90" fxFlex.lt-md="85" fxLayoutAlign="start start" class="channels-capacity-scroll w-100" perfectScrollbar>
<div fxLayout="column" fxFlex="100" class="w-100" *ngIf="allChannels && allChannels.length > 0; else noChannelBlock">
<div *ngFor="let channel of allChannels" class="mt-2">
<h4>{{(channel.remote_alias || channel.remote_pubkey) | slice:0:24}}{{(channel.remote_alias || channel.remote_pubkey).length > 25 ? '...' : ''}}</h4>
<div fxLayout="row" fxLayoutAlign="space-between start" class="w-100">
<mat-hint *ngIf="direction === 'In'" fxFlex="100" fxLayoutAlign="start center" class="font-size-80"><strong class="font-weight-900">{{channel.remote_balance || 0 | number}} Sats</strong></mat-hint>
<mat-hint *ngIf="direction === 'Out'" fxFlex="100" fxLayoutAlign="start center" class="font-size-80"><strong class="font-weight-900">{{channel.local_balance || 0 | number}} Sats</strong></mat-hint>
</div>
<mat-progress-bar *ngIf="direction === 'In'" class="dashboard-progress-bar" mode="determinate" value="{{(+channel.remote_balance || 0)/(+channel.remote_balance + +channel.local_balance) * 100}}"></mat-progress-bar>
<mat-progress-bar *ngIf="direction === 'Out'" class="dashboard-progress-bar" mode="determinate" value="{{(+channel.local_balance || 0)/(+channel.remote_balance + +channel.local_balance) * 100}}"></mat-progress-bar>
</div>
</div>
</div>
</div>
<ng-template #noChannelBlock>
<div fxLayout="column" fxFlex="100" class="w-100 mt-2">No channels available.</div>
</ng-template>

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ChannelLiquidityInfoComponent } from './channel-liquidity-info.component';
describe('ChannelLiquidityInfoComponent', () => {
let component: ChannelLiquidityInfoComponent;
let fixture: ComponentFixture<ChannelLiquidityInfoComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ChannelLiquidityInfoComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ChannelLiquidityInfoComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,21 @@
import { Component, OnChanges, Input } from '@angular/core';
import { Channel } from '../../../shared/models/lndModels';
@Component({
selector: 'rtl-channel-liquidity-info',
templateUrl: './channel-liquidity-info.component.html',
styleUrls: ['./channel-liquidity-info.component.scss']
})
export class ChannelLiquidityInfoComponent implements OnChanges {
@Input() direction: string;
@Input() totalLiquidity: number;
@Input() allChannels: Channel[];
public maxTransactionAmount = 0;
constructor() {}
ngOnChanges() {
this.maxTransactionAmount = this.allChannels && this.allChannels.length > 0 ? (this.direction === 'In' ? this.allChannels[0].remote_balance : this.allChannels[0].local_balance) : 0;
}
}

View File

@ -0,0 +1 @@
<p>dashboard-transactions works!</p>

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { DashboardTransactionsComponent } from './dashboard-transactions.component';
describe('DashboardTransactionsComponent', () => {
let component: DashboardTransactionsComponent;
let fixture: ComponentFixture<DashboardTransactionsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ DashboardTransactionsComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DashboardTransactionsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'rtl-dashboard-transactions',
templateUrl: './dashboard-transactions.component.html',
styleUrls: ['./dashboard-transactions.component.scss']
})
export class DashboardTransactionsComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}

View File

@ -1,21 +1,14 @@
<div fxLayout="column">
<div fxLayout="column" *ngIf="userPersona === userPersonaEnum.OPERATOR; else merchantDashboard">
<div fxLayout="row" fxLayoutAlign="start end" class="padding-gap-x page-title-container mb-0">
<fa-icon [icon]="faSmile" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Welcome! Your node is up and running.</span>
</div>
<mat-grid-list cols="10" rowHeight="330px">
<mat-grid-tile *ngFor="let card of cards | async" [colspan]="card.cols" [rowspan]="card.rows">
<mat-grid-tile *ngFor="let card of operatorCards | async" [colspan]="card.cols" [rowspan]="card.rows">
<mat-card fxLayout="column" fxLayoutAlign="start start" class="dashboard-card p-16">
<mat-card-header>
<mat-card-title>
{{card.title}}
<button mat-icon-button class="more-button" [matMenuTriggerFor]="menu" aria-label="Toggle menu">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #menu="matMenu" xPosition="before">
<button mat-menu-item>Expand</button>
<button mat-menu-item>Remove</button>
</mat-menu>
</mat-card-title>
</mat-card-header>
<mat-card-content class="dashboard-card-content w-100" fxFlex="95">
@ -32,3 +25,25 @@
</mat-grid-tile>
</mat-grid-list>
</div>
<ng-template #merchantDashboard>
<div fxLayout="row" fxLayoutAlign="start end" class="padding-gap-x page-title-container mb-0">
<fa-icon [icon]="faSmile" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Welcome! Your node is up and running.</span>
</div>
<mat-grid-list cols="3" rowHeight="220px">
<mat-grid-tile *ngFor="let card of merchantCards | async" [colspan]="card.cols" [rowspan]="card.rows">
<mat-card fxLayout="column" fxLayoutAlign="start start" class="dashboard-card p-16">
<mat-card-header><mat-card-title>{{card.title}}</mat-card-title></mat-card-header>
<mat-card-content class="dashboard-card-content w-100" fxFlex="95">
<div [ngSwitch]="card.id" fxLayout="column" fxFlex="100">
<rtl-balances-info fxFlex="100" *ngSwitchCase="'balance'" [flgInfoUpdate]="flgChildInfoUpdated" [balances]="balances" [ngClass]="{'error-border': flgLoading[2]==='error' || flgLoading[5]==='error'}"></rtl-balances-info>
<rtl-channel-liquidity-info fxFlex="100" *ngSwitchCase="'inboundLiq'" [direction]="'In'" [totalLiquidity]="totalInboundLiquidity" [allChannels]="allChannels" [ngClass]="{'error-border': flgLoading[5]==='error'}"></rtl-channel-liquidity-info>
<rtl-channel-liquidity-info fxFlex="100" *ngSwitchCase="'outboundLiq'" [direction]="'Out'" [totalLiquidity]="totalOutboundLiquidity" [allChannels]="allChannels" [ngClass]="{'error-border': flgLoading[5]==='error'}"></rtl-channel-liquidity-info>
<rtl-dashboard-transactions fxFlex="100" *ngSwitchCase="'transactions'"></rtl-dashboard-transactions>
<h3 *ngSwitchDefault>Error! Unable to find information!</h3>
</div>
</mat-card-content>
</mat-card>
</mat-grid-tile>
</mat-grid-list>
</ng-template>

View File

@ -1,4 +1,5 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router } from '@angular/router';
import { map } from 'rxjs/operators';
import { Breakpoints, BreakpointObserver } from '@angular/cdk/layout';
import { Subject } from 'rxjs';
@ -8,7 +9,8 @@ import { Actions } from '@ngrx/effects';
import { faSmile } from '@fortawesome/free-regular-svg-icons';
import { LoggerService } from '../../shared/services/logger.service';
import { ChannelsStatus, GetInfo, Fees, Peer } from '../../shared/models/lndModels';
import { UserPersonaEnum } from '../../shared/services/consts-enums-functions';
import { ChannelsStatus, GetInfo, Fees, Channel } from '../../shared/models/lndModels';
import { SelNodeChild } from '../../shared/models/RTLconfig';
import * as fromRTLReducer from '../../store/rtl.reducers';
import * as RTLActions from '../../store/rtl.actions';
@ -21,6 +23,8 @@ import * as RTLActions from '../../store/rtl.actions';
export class HomeComponent implements OnInit, OnDestroy {
public faSmile = faSmile;
public flgChildInfoUpdated = false;
public userPersonaEnum = UserPersonaEnum;
public userPersona = UserPersonaEnum.OPERATOR;
public activeChannels = 0;
public inactiveChannels = 0;
public pendingChannels = 0;
@ -29,12 +33,15 @@ export class HomeComponent implements OnInit, OnDestroy {
public fees: Fees;
public information: GetInfo = {};
public balances = { onchain: -1, lightning: -1 };
public allChannels = [];
public allChannels: Channel[] = [];
public channelsStatus: ChannelsStatus = {};
public allInboundChannels: Channel[] = [];
public allOutboundChannels: Channel[] = [];
public totalInboundLiquidity = 0;
public totalOutboundLiquidity = 0;
public flgLoading: Array<Boolean | 'error'> = [true, true, true, true, true, true, true, true]; // 0: Info, 1: Fee, 2: Wallet, 3: Channel, 4: Network
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
public channelsStatus: ChannelsStatus = {};
public peers: Peer[] = [];
public cards = this.breakpointObserver.observe(Breakpoints.Handset).pipe(
public operatorCards = this.breakpointObserver.observe(Breakpoints.Handset).pipe(
map(({ matches }) => {
if (matches) {
return [
@ -54,9 +61,29 @@ export class HomeComponent implements OnInit, OnDestroy {
{ id: 'status', title: 'Channel Status', cols: 3, rows: 1 }
];
})
);
);
constructor(private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private actions$: Actions, private breakpointObserver: BreakpointObserver) {}
public merchantCards = this.breakpointObserver.observe(Breakpoints.Handset).pipe(
map(({ matches }) => {
if (matches) {
return [
{ id: 'balance', title: 'Balances', cols: 3, rows: 1 },
{ id: 'transactions', title: 'Transactions', cols: 3, rows: 1 },
{ id: 'inboundLiq', title: 'In-Bound Liquidity', cols: 3, rows: 1 },
{ id: 'outboundLiq', title: 'Out-Bound Liquidity', cols: 3, rows: 1 }
];
}
return [
{ id: 'balance', title: 'Balances', cols: 1, rows: 1 },
{ id: 'inboundLiq', title: 'In-Bound Liquidity', cols: 1, rows: 3 },
{ id: 'outboundLiq', title: 'Out-Bound Liquidity', cols: 1, rows: 3 },
{ id: 'transactions', title: 'Transactions', cols: 1, rows: 2 }
];
})
);
constructor(private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private actions$: Actions, private breakpointObserver: BreakpointObserver, private router: Router) {}
ngOnInit() {
this.store.select('lnd')
@ -119,7 +146,13 @@ export class HomeComponent implements OnInit, OnDestroy {
if (rtlStore.totalLocalBalance >= 0 && rtlStore.totalRemoteBalance >= 0 && this.flgLoading[5] !== 'error') {
this.flgLoading[5] = false;
}
this.totalInboundLiquidity = 0;
this.totalOutboundLiquidity = 0;
this.allChannels = rtlStore.allChannels.filter(channel => channel.active === true);
this.allChannels.forEach(channel => {
this.totalInboundLiquidity = this.totalInboundLiquidity + +channel.remote_balance;
this.totalOutboundLiquidity = this.totalOutboundLiquidity + +channel.local_balance;
});
if (this.balances.lightning >= 0 && this.balances.onchain >= 0 && this.fees.month_fee_sum >= 0) {
this.flgChildInfoUpdated = true;
} else {

View File

@ -46,6 +46,8 @@ import { MatMenuModule } from '@angular/material/menu';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
import { LayoutModule } from '@angular/cdk/layout';
import { ChannelLiquidityInfoComponent } from './home/channel-liquidity-info/channel-liquidity-info.component';
import { DashboardTransactionsComponent } from './home/dashboard-transactions/dashboard-transactions.component';
@NgModule({
imports: [
@ -92,7 +94,9 @@ import { LayoutModule } from '@angular/cdk/layout';
BalancesInfoComponent,
FeeInfoComponent,
ChannelStatusInfoComponent,
ChannelCapacityInfoComponent
ChannelCapacityInfoComponent,
ChannelLiquidityInfoComponent,
DashboardTransactionsComponent
],
providers: [
{ provide: LoggerService, useClass: ConsoleLoggerService },

View File

@ -20,8 +20,8 @@ export class CommonService implements OnInit, OnDestroy {
sortDescByKey(array, key) {
return array.sort(function (a, b) {
const x = a[key];
const y = b[key];
const x = +a[key];
const y = +b[key];
return ((x > y) ? -1 : ((x < y) ? 1 : 0));
});
}

View File

@ -25,6 +25,11 @@ export const TRANS_TYPES = [
{id: '2', name: 'Fee'}
];
export enum UserPersonaEnum {
OPERATOR = 'OPERATOR',
MERCHANT = 'MERCHANT'
}
export enum AlertTypeEnum {
INFORMATION = 'Information',
WARNING = 'Warning',

View File

@ -83,7 +83,14 @@
.rtl-snack-bar {
background: $primary-color;
}
.mat-progress-bar-fill::after {
background-color: mat-color($primary, 600);
}
.chart-legend .legend-label:hover, .chart-legend .legend-label .active .legend-label-text {
color: $foreground-text !important;
}
}
&.day {
.rtl-top-toolbar {
border-bottom: 1px solid white;
@ -142,8 +149,15 @@
.rtl-snack-bar {
background: $primary-color;
}
.mat-progress-bar-fill::after {
background-color: mat-color($primary, 900);
}
}
.mat-progress-bar-buffer {
background-color: mat-color($primary, 100);
}
.foreground-secondary-text {
color: $foreground-secondary-text !important;
white-space: pre-line;
@ -409,4 +423,5 @@
}
}
}
}

View File

@ -802,7 +802,7 @@ table {
width: $dot-size;
height: $dot-size;
border-radius: $dot-size;
margin-right: 1rem;
margin: 0.4rem 1rem 0 0;
&.tiny-dot {
width: $tiny-dot-size;
height: $tiny-dot-size;