FIxing a lot of issues and adding org data

This commit is contained in:
Finn 2019-07-11 16:12:46 +01:00
parent bd33f79067
commit c5f6cb2750
No known key found for this signature in database
GPG key ID: 7455B4B17685B598
12 changed files with 327 additions and 11 deletions

View file

@ -27,6 +27,7 @@ import { CustGraphsService } from './providers/cust-graphs.service';
import { OrgSnippetsService } from './providers/org-snippets.service'; import { OrgSnippetsService } from './providers/org-snippets.service';
import { CustSnippetsService } from './providers/cust-snippets.service'; import { CustSnippetsService } from './providers/cust-snippets.service';
import { CustPiesService } from './providers/cust-pies.service'; import { CustPiesService } from './providers/cust-pies.service';
import { OrgPiesService } from './providers/org-pies.service';
// Layouts // Layouts
import { FullLayoutComponent } from './layouts/full-layout.component'; import { FullLayoutComponent } from './layouts/full-layout.component';
@ -84,6 +85,7 @@ import { MoreStuffComponent } from './dashboard/more-graphs-and-tables.component
CustGraphsService, CustGraphsService,
CustSnippetsService, CustSnippetsService,
CustPiesService, CustPiesService,
OrgPiesService,
{ {
provide: LocationStrategy, provide: LocationStrategy,
useClass: HashLocationStrategy useClass: HashLocationStrategy

View file

@ -18,7 +18,7 @@
<h4 class="card-title float-left mb-0">Spend by company and Industrial sector</h4> <h4 class="card-title float-left mb-0">Spend by company and Industrial sector</h4>
</div><!--/.col--> </div><!--/.col-->
</div><!--/.row--> </div><!--/.row-->
<div class="chart-wrapper"> <!-- <div class="chart-wrapper">
<canvas baseChart class="chart" <canvas baseChart class="chart"
[datasets]="lineChartData" [datasets]="lineChartData"
[labels]="lineChartLabels" [labels]="lineChartLabels"
@ -27,7 +27,7 @@
[chartType]="lineChartType" [chartType]="lineChartType"
(chartHover)="chartHovered($event)" (chartHover)="chartHovered($event)"
(chartClick)="chartClicked($event)"></canvas> (chartClick)="chartClicked($event)"></canvas>
</div> </div> -->
</div> </div>
</div> </div>
<div class=row> <div class=row>
@ -94,6 +94,6 @@
</div> </div>
</div> </div>
<div class="col-xl-6"> <div class="col-xl-6">
<panel-pie></panel-pie> <org-pie-panel></org-pie-panel>
</div> </div>
</div> </div>

View file

@ -1,11 +1,14 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import {Router, NavigationEnd} from "@angular/router"; import { Router, NavigationEnd } from "@angular/router";
import { CurrencyPipe } from '@angular/common';
import { GraphWidget } from '../widgets/graph-widget.component'; import { GraphWidget } from '../widgets/graph-widget.component';
import { OrgBarSnippetComponent } from '../snippets/org-snippet-bar.component'; import { OrgBarSnippetComponent } from '../snippets/org-snippet-bar.component';
import { GraphPanel } from '../panels/graph-panel.component'; import { GraphPanel } from '../panels/graph-panel.component';
import { PiePanel } from '../panels/pie-panel.component'; import { OrgPiePanel } from '../panels/org-pie-panel.component';
import { DataType } from '../shared/data-types.enum'; import { DataType } from '../shared/data-types.enum';
import { ApiService } from '../providers/api-service';
import { environment } from '../../environments/environment'; import { environment } from '../../environments/environment';
import * as moment from 'moment';
@Component({ @Component({
templateUrl: 'dashboard.component.html' templateUrl: 'dashboard.component.html'
@ -52,7 +55,98 @@ export class DashboardComponent {
dataType: DataType.currency, dataType: DataType.currency,
}, },
]; ];
constructor(private router: Router) {
disableCategoryButton: boolean = false;
public bootstrapColours: string[] = ['bg-primary', 'bg-secondary', 'bg-success',
'bg-danger', 'bg-warning', 'bg-info'];
public chartType = 'doughnut';
public chartLegend = true;
public doughnutChartDataCategory: any[] = [];
public doughnutChartLabelsCategory: string[] = [];
public doughnutChartOptionsCategory:any = {
tooltips: {
callbacks: {
label: (tooltip, data) => {
return this.tooltipLabelCallback(tooltip, data);
},
},
},
}
myWeek1: any;
weekList1 = [];
public purchaseNotEssential: number;
public purchaseEssential: number;
public showEssentialBarChart = false;
public showCategoryBarChart = false;
public showCategoryDoughnutChart = false;
public barChartDataEssential:any[]=[
{data: 0, label: 'Essential', stack: '1'},
{data: 0, label: 'Non-Essential', stack: '1'},
];
public barChartLabelsEssential:string[] = ['All Purchases'];
public barChartOptionsEssential:any = {
responsive: true,
scales:{
xAxes:[{
stacked:true
}],
yAxes:[{
stacked:true
}]
}
};
public barChartTypeEssential:string = 'horizontalBar';
public barChartOptionsCategory:any = {
scaleShowVerticalLines: false,
responsive: true,
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
callback: label => `£${label}`
}
}]
},
tooltips: {
callbacks: {
label: (tooltip, data) => {
return this.tooltipLabelCallback(tooltip, data);
},
},
},
};
public barChartTypeCategory:string = 'bar';
public barChartLegendCategory:boolean = false;
public barChartDataCategory:any[]=[];
public barChartLabelsCategory:string[] = [];
weekPurchaseList = {
first: 0,
second: 0,
max: 0,
sum: 0,
count: 0,
};
showTotalCategoryList: boolean = false;
totalCategoryLimit: number = 10;
totalCategoryList: any[]=[];
constructor(
private router: Router,
private api: ApiService,
private currencyPipe: CurrencyPipe,
) {
if (environment.enableAnalytics) { if (environment.enableAnalytics) {
this.router.events.subscribe(event => { this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) { if (event instanceof NavigationEnd) {
@ -61,6 +155,102 @@ export class DashboardComponent {
} }
}); });
} }
this.setDate();
this.api.orgStats().subscribe(
result => {
this.setWeekPurchaseList(result.weeks);
this.setWeekData(result);
this.setChartData(result.data.cat_total);
this.totalCategoryList = result.data.cat_list;
if (this.totalCategoryList) {
this.showTotalCategoryList = true;
}
this.purchaseEssential = result.data.essentials.purchase_no_essential_total;
this.purchaseNotEssential = result.data.essentials.purchase_no_total - this.purchaseEssential;
this.barChartDataEssential = [
{data: [this.purchaseEssential], label: 'Essential', stack: '1'},
{data: [this.purchaseNotEssential], label: 'Non-Essential', stack: '1'},
];
this.showEssentialBarChart = true;
},
error => {
console.log('Retrieval Error');
console.log( error._body );
}
);
} }
private setChartData(dataCat: any) {
this.barChartLabelsCategory = Object.keys(dataCat);
let barChartDataCategoryInitial = Object.keys(dataCat).map(key => dataCat[key]);
this.barChartDataCategory = [
{data: barChartDataCategoryInitial, label: 'Series A'},
];
this.showCategoryBarChart = true;
if (this.weekList1) {
let doughnutChartDataCategoryInitial = this.weekList1.map(function(a) {return a.value;});
this.doughnutChartDataCategory = [
{data: doughnutChartDataCategoryInitial, label: 'Series A'},
];
// setTimeout is currently a workaround for ng2-charts labels
setTimeout(() => this.doughnutChartLabelsCategory = this.weekList1.map(function(a) {return a.category;}), 0);
this.showCategoryDoughnutChart = true;
}
}
private setDate () {
this.myWeek1 = moment().startOf('isoWeek').format('YYYY-MM-DD');
}
private setWeekData (data: any) {
function prop<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
this.weekList1 = prop(data.data.categories, this.myWeek1);
}
public setWeekPurchaseList (data: any) {
this.weekPurchaseList = {
first: data.first,
second: data.second,
max: data.max,
sum: data.sum,
count: data.count,
};
}
private categoryLoadMore () {
this.disableCategoryButton = true;
this.totalCategoryLimit = 30;
}
public getBootstrapColour(index: number) {
return this.bootstrapColours[index % this.bootstrapColours.length];
}
public convertHex(hex: string, opacity: number) {
hex = hex.replace('#', '');
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
const rgba = 'rgba(' + r + ', ' + g + ', ' + b + ', ' + opacity / 100 + ')';
return rgba;
}
private tooltipLabelCallback(tooltipItem: any, data: any) {
var dataset = data.datasets[tooltipItem.datasetIndex];
var value = dataset.data[tooltipItem.index];
return this.currencyPipe.transform(value, 'GBP', 'symbol', '1.2-2');
}
// events
public chartClicked(e: any): void {
}
public chartHovered(e: any): void {
}
ngOnInit(): void {
}
} }

View file

@ -27,6 +27,7 @@ import { OrgBarSnippetComponent } from '../snippets/org-snippet-bar.component';
import { CustBarSnippetComponent } from '../snippets/cust-snippet-bar.component'; import { CustBarSnippetComponent } from '../snippets/cust-snippet-bar.component';
import { GraphPanel } from '../panels/graph-panel.component'; import { GraphPanel } from '../panels/graph-panel.component';
import { PiePanel } from '../panels/pie-panel.component'; import { PiePanel } from '../panels/pie-panel.component';
import { OrgPiePanel } from '../panels/org-pie-panel.component';
import { DashboardRoutingModule } from './dashboard.routing'; import { DashboardRoutingModule } from './dashboard.routing';
import { OrgResultComponent } from '../shared/org-result.component'; import { OrgResultComponent } from '../shared/org-result.component';
@ -80,6 +81,7 @@ import { environment } from '../../environments/environment';
CustBarSnippetComponent, CustBarSnippetComponent,
GraphPanel, GraphPanel,
PiePanel, PiePanel,
OrgPiePanel,
], ],
providers: [ providers: [
CurrencyPipe, CurrencyPipe,

View file

@ -0,0 +1,18 @@
<div class="card">
<div class="card-block">
<div class="row">
<div class="col-12">
<h4 class="card-title mb-0">All Purchases</h4>
</div>
</div>
<div class="chart-wrapper">
<canvas baseChart class="chart"
[data]="doughnutChartDataLocal"
[labels]="doughnutChartLabelsLocal"
[legend]="chartLegend"
[chartType]="chartType"
(chartHover)="chartHovered($event)"
(chartClick)="chartClicked($event)"></canvas>
</div>
</div>
</div>

View file

@ -0,0 +1,63 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { ApiService } from '../providers/api-service';
import { OrgPiesService } from '../providers/org-pies.service';
import { DataType } from '../shared/data-types.enum';
import { ChartData } from '../_interfaces/chart-data';
@Component({
selector: 'org-pie-panel',
templateUrl: 'org-pie-panel.component.html',
})
export class OrgPiePanel implements OnInit {
public chartType = 'doughnut';
public chartLegend = true;
public doughnutChartDataLocal: number[] = [];
public doughnutChartLabelsLocal: string[] = [];
constructor(
private api: ApiService,
private pieService: OrgPiesService,
) {
this.pieService.getOrgPie().subscribe(
result => {
this.setChartData(result.local_all);
},
error => {
console.log('Retrieval Error');
console.log( error._body );
}
);
}
public ngOnInit(): void {
}
private setChartData(dataLocal: any) {
this.doughnutChartDataLocal = Object.keys(dataLocal).map(key => dataLocal[key]);
// setTimeout is currently a workaround for ng2-charts labels
setTimeout(() => this.doughnutChartLabelsLocal = Object.keys(dataLocal), 0);
}
// convert Hex to RGBA
public convertHex(hex: string, opacity: number) {
hex = hex.replace('#', '');
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
const rgba = 'rgba(' + r + ', ' + g + ', ' + b + ', ' + opacity / 100 + ')';
return rgba;
}
// events
public chartClicked(e: any): void {
}
public chartHovered(e: any): void {
}
}

View file

@ -345,4 +345,15 @@ export class ApiService {
} }
); );
} }
// Basic Customer User stats API
public orgStats() {
const key = this.sessionKey;
return this.http.post<any>(
this.apiUrl + '/stats/organisation',
{
session_key : key,
}
);
}
} }

View file

@ -0,0 +1,14 @@
import { Injectable } from '@angular/core';
import { ApiService } from './api-service';
import { Observable } from 'rxjs';
@Injectable()
export class OrgPiesService {
private orgPieUrl = '/v1/organisation/pies';
constructor(private api: ApiService) { }
public getOrgPie(): Observable<any> {
return this.api.post(this.orgPieUrl);
}
}

View file

@ -2,7 +2,15 @@
<div class="card-footer"> <div class="card-footer">
<ul> <ul>
<li class="hidden-sm-down"> <li class="hidden-sm-down">
<div class="text-muted">Customers This Month</div> <div class="text-muted">Sales Total</div>
<strong>{{ allSalesCount }}</strong>
</li>
<li class="hidden-sm-down">
<div class="text-muted">Money Spent Total</div>
<strong>{{ allPurchasesTotal | currency:'GBP':'symbol':'1.2-2'}}</strong>
</li>
<li class="hidden-sm-down">
<div class="text-muted">Sales This Month</div>
<strong>{{ thisMonthSalesCount }}</strong> <strong>{{ thisMonthSalesCount }}</strong>
</li> </li>
<li class="hidden-sm-down"> <li class="hidden-sm-down">
@ -10,7 +18,7 @@
<strong>{{ thisMonthPurchasesTotal | currency:'GBP':'symbol':'1.2-2'}}</strong> <strong>{{ thisMonthPurchasesTotal | currency:'GBP':'symbol':'1.2-2'}}</strong>
</li> </li>
<li class="hidden-sm-down"> <li class="hidden-sm-down">
<div class="text-muted">Customers Today</div> <div class="text-muted">Sales Today</div>
<strong>{{ todaySalesCount }}</strong> <strong>{{ todaySalesCount }}</strong>
</li> </li>
<li class="hidden-sm-down"> <li class="hidden-sm-down">

View file

@ -7,6 +7,8 @@ import { OrgSnippetsService } from '../providers/org-snippets.service';
}) })
export class OrgBarSnippetComponent implements OnInit { export class OrgBarSnippetComponent implements OnInit {
public allSalesCount = 0;
public allSalesTotal = 0;
public thisMonthSalesCount = 0; public thisMonthSalesCount = 0;
public thisMonthSalesTotal = 0; public thisMonthSalesTotal = 0;
public thisWeekSalesCount = 0; public thisWeekSalesCount = 0;
@ -14,6 +16,8 @@ export class OrgBarSnippetComponent implements OnInit {
public todaySalesCount = 0; public todaySalesCount = 0;
public todaySalesTotal = 0; public todaySalesTotal = 0;
public allPurchasesCount = 0;
public allPurchasesTotal = 0;
public thisMonthPurchasesCount = 0; public thisMonthPurchasesCount = 0;
public thisMonthPurchasesTotal = 0; public thisMonthPurchasesTotal = 0;
public thisWeekPurchasesCount = 0; public thisWeekPurchasesCount = 0;
@ -29,6 +33,8 @@ export class OrgBarSnippetComponent implements OnInit {
this.snippetsService.getData() this.snippetsService.getData()
.subscribe( .subscribe(
result => { result => {
this.allSalesCount = result.snippets.all_sales_count;
this.allSalesTotal = result.snippets.all_sales_total;
this.thisMonthSalesCount = result.snippets.this_month_sales_count; this.thisMonthSalesCount = result.snippets.this_month_sales_count;
this.thisMonthSalesTotal = result.snippets.this_month_sales_total; this.thisMonthSalesTotal = result.snippets.this_month_sales_total;
this.thisWeekSalesCount = result.snippets.this_week_sales_count; this.thisWeekSalesCount = result.snippets.this_week_sales_count;
@ -36,6 +42,8 @@ export class OrgBarSnippetComponent implements OnInit {
this.todaySalesCount = result.snippets.today_sales_count; this.todaySalesCount = result.snippets.today_sales_count;
this.todaySalesTotal = result.snippets.today_sales_total; this.todaySalesTotal = result.snippets.today_sales_total;
this.allPurchasesCount = result.snippets.all_purchases_count;
this.allPurchasesTotal = result.snippets.all_purchases_total;
this.thisMonthPurchasesCount = result.snippets.this_week_purchases_count; this.thisMonthPurchasesCount = result.snippets.this_week_purchases_count;
this.thisMonthPurchasesTotal = result.snippets.this_week_purchases_total; this.thisMonthPurchasesTotal = result.snippets.this_week_purchases_total;
this.thisWeekPurchasesCount = result.snippets.this_month_purchases_count; this.thisWeekPurchasesCount = result.snippets.this_month_purchases_count;

View file

@ -10,7 +10,7 @@
<div class="chart-wrapper px-3" style="height:70px;"> <div class="chart-wrapper px-3" style="height:70px;">
<canvas baseChart <canvas baseChart
class="chart" class="chart"
[datasets]="lineChartData" [datasets]="lineGraphChartData"
[labels]="lineChartLabels" [labels]="lineChartLabels"
[options]="lineChartOptions" [options]="lineChartOptions"
[colors]="lineChartColours" [colors]="lineChartColours"

View file

@ -25,7 +25,7 @@ export class GraphWidget implements OnInit {
public graphSum: Number = 0; public graphSum: Number = 0;
public availableDataTypes = DataType; public availableDataTypes = DataType;
public lineChartData: Array<ChartData> = [ public lineGraphChartData: Array<ChartData> = [
{ {
data: [], data: [],
label: 'Series A' label: 'Series A'
@ -125,7 +125,7 @@ export class GraphWidget implements OnInit {
} }
private setChartData(data: Array<number>) { private setChartData(data: Array<number>) {
this.lineChartData[0].data = data; this.lineGraphChartData[0].data = data;
this.graphSum = data.reduce((a, b) => a + b, 0); this.graphSum = data.reduce((a, b) => a + b, 0);
// Set point size based on data // Set point size based on data
if ( data.length < 15 ) { if ( data.length < 15 ) {