Updated Hero Points Page with latest work
This commit is contained in:
parent
e1bf569f37
commit
ab0ba52b6f
12 changed files with 404 additions and 231 deletions
|
@ -26,8 +26,8 @@ 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 { MedalsService } from './providers/medals.service';
|
import { MedalsService } from './providers/medals.service';
|
||||||
//import { HeroPointsSnippetsService } from './providers/hero-points-snippets.service';
|
import { HeroPointsSnippetsService } from './providers/hero-points-snippets.service';
|
||||||
//import { HeroPointsStatsService } from './providers/hero-points-stats.service';
|
import { HeroPointsGraphService } from './providers/hero-points-graph.service';
|
||||||
|
|
||||||
// Layouts
|
// Layouts
|
||||||
import { FullLayoutComponent } from './layouts/full-layout.component';
|
import { FullLayoutComponent } from './layouts/full-layout.component';
|
||||||
|
@ -77,10 +77,10 @@ import { NgPipesModule } from 'ngx-pipes';
|
||||||
OrgSnippetsService,
|
OrgSnippetsService,
|
||||||
CustGraphsService,
|
CustGraphsService,
|
||||||
CustSnippetsService,
|
CustSnippetsService,
|
||||||
//HeroPointsSnippetsService,
|
HeroPointsSnippetsService,
|
||||||
//HeroPointsStatsService,
|
|
||||||
MedalsService,
|
MedalsService,
|
||||||
CustPiesService,
|
CustPiesService,
|
||||||
|
HeroPointsGraphService,
|
||||||
{
|
{
|
||||||
provide: LocationStrategy,
|
provide: LocationStrategy,
|
||||||
useClass: HashLocationStrategy
|
useClass: HashLocationStrategy
|
||||||
|
|
|
@ -26,7 +26,8 @@ import { HeroPointsComponent } from './hero-points.component';
|
||||||
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 { CustBarSnippetComponent } from '../snippets/cust-snippet-bar.component';
|
import { CustBarSnippetComponent } from '../snippets/cust-snippet-bar.component';
|
||||||
//import { HeroPointsSnippetBarComponent } from '../snippets/hero-points-snippet-bar.component';
|
import { HeroPointsSnippetBarComponent } from '../snippets/hero-points-snippet-bar.component';
|
||||||
|
import { HeroPointsGraphWidget } from '../widgets/hero-points-graph-widget.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';
|
||||||
|
|
||||||
|
@ -80,7 +81,8 @@ import { NgPipesModule } from 'ngx-pipes';
|
||||||
GraphWidget,
|
GraphWidget,
|
||||||
OrgBarSnippetComponent,
|
OrgBarSnippetComponent,
|
||||||
CustBarSnippetComponent,
|
CustBarSnippetComponent,
|
||||||
//HeroPointsSnippetBarComponent,
|
HeroPointsSnippetBarComponent,
|
||||||
|
HeroPointsGraphWidget,
|
||||||
GraphPanel,
|
GraphPanel,
|
||||||
PiePanel,
|
PiePanel,
|
||||||
HeroPointsComponent,
|
HeroPointsComponent,
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
<div class="animated fadeIn">
|
<div class="animated fadeIn">
|
||||||
<!--<snippet-bar-hero-points></snippet-bar-hero-points>--><!-- Snippet for hero points (four circles) -->
|
<snippet-bar-hero-points></snippet-bar-hero-points><!-- Snippet for hero points (four circles) -->
|
||||||
<div class="row"> <!-- second row -->
|
<div class="row"> <!-- second row -->
|
||||||
<div class="col-md-6 col-xl-3"> <!-- Hero points gain charts -->
|
<div class="col-md-6 col-xl-3"> <!-- Hero points gain charts -->
|
||||||
<div *ngFor="let widget of widgetList"> <!-- Points gain line graph -->
|
<div *ngFor="let widget of widgetList"> <!-- Points gain line graph -->
|
||||||
<!--<widget-graph *ngIf="widget.type == 'graph'"
|
<hero-points-widget-graph *ngIf="widget.type == 'graph'"
|
||||||
[graphName]="widget.name"
|
[graphName]="widget.name"
|
||||||
[graphTitle]="widget.title"
|
[graphTitle]="widget.title"
|
||||||
[graphIcon]="widget.icon"
|
[graphIcon]="widget.icon"
|
||||||
[dataType]="widget.dataType">
|
[dataType]="widget.dataType">
|
||||||
</widget-graph>-->
|
</hero-points-widget-graph>
|
||||||
</div> <!-- let widget of widgetList -->
|
</div> <!-- let widget of widgetList -->
|
||||||
<div class="card"> <!-- Points gain by week charts -->
|
<div class="card"> <!-- Points gain by week charts -->
|
||||||
<div class="card-block">
|
<div class="card-block">
|
||||||
|
@ -21,41 +21,41 @@
|
||||||
<ul class="horizontal-bars type-2">
|
<ul class="horizontal-bars type-2">
|
||||||
<li> <!-- This Week -->
|
<li> <!-- This Week -->
|
||||||
<span class="title">This Week</span>
|
<span class="title">This Week</span>
|
||||||
<span class="value">{{ transactionListWeek | filterBy: ['weekId']: (transactionListWeek | pluck: 'weekId' | max) | pluck: 'pointsEarned' }}<span class="text-muted small"> ({{( transactionListWeek | filterBy: ['weekId']: (transactionListWeek | pluck: 'weekId' | max) | pluck: 'pointsEarned' ) / ( transactionListWeek | pluck: 'pointsEarned' | max ) | percent:'1.0-0' }})</span></span>
|
<span class="value">{{ heroPointsStats.this_week }}<span class="text-muted small"> ({{ heroPointsStats.this_week / heroPointsStats.max | percent:'1.0-0' }})</span></span>
|
||||||
<div class="bars">
|
<div class="bars">
|
||||||
<div class="progress" style="height: 6px;">
|
<div class="progress" style="height: 6px;">
|
||||||
<div class="progress-bar bg-success" role="progressbar"
|
<div class="progress-bar bg-success" role="progressbar"
|
||||||
style="width: 39%" aria-valuemin="0" aria-valuemax="100"></div>
|
[style.width]="heroPointsStats.this_week / heroPointsStats.max | percent:'1.0-0'" aria-valuemin="0" aria-valuemax="100"></div>
|
||||||
</div> <!-- progress -->
|
</div> <!-- progress -->
|
||||||
</div> <!-- bars -->
|
</div> <!-- bars -->
|
||||||
</li>
|
</li>
|
||||||
<li> <!-- Last Week -->
|
<li> <!-- Last Week -->
|
||||||
<span class="title">Last Week</span>
|
<span class="title">Last Week</span>
|
||||||
<span class="value">{{ transactionListWeek | filterBy: ['weekId']: (transactionListWeek | pluck: 'weekId' | max) - 1 | pluck: 'pointsEarned' }}<span class="text-muted small"> ({{( transactionListWeek | filterBy: ['weekId']: (transactionListWeek | pluck: 'weekId' | max) - 1 | pluck: 'pointsEarned' ) / ( transactionListWeek | pluck: 'pointsEarned' | max ) | percent:'1.0-0' }})</span></span>
|
<span class="value">{{ heroPointsStats.last_week }}<span class="text-muted small"> ({{ heroPointsStats.last_week / heroPointsStats.max | percent:'1.0-0' }})</span></span>
|
||||||
<div class="bars">
|
<div class="bars">
|
||||||
<div class="progress" style="height: 6px;">
|
<div class="progress" style="height: 6px;">
|
||||||
<div class="progress-bar bg-success" role="progressbar"
|
<div class="progress-bar bg-success" role="progressbar"
|
||||||
style="width: 100%" aria-valuemin="0" aria-valuemax="100"></div>
|
[style.width]="heroPointsStats.last_week / heroPointsStats.max | percent:'1.0-0'" aria-valuemin="0" aria-valuemax="100"></div>
|
||||||
</div> <!-- progress -->
|
</div> <!-- progress -->
|
||||||
</div> <!-- bars -->
|
</div> <!-- bars -->
|
||||||
</li>
|
</li>
|
||||||
<li> <!-- Week Maximum -->
|
<li> <!-- Week Maximum -->
|
||||||
<span class="title">Week Maximum</span>
|
<span class="title">Week Maximum</span>
|
||||||
<span class="value">{{ transactionListWeek | pluck: 'pointsEarned' | max }}<span class="text-muted small"> (100%)</span></span>
|
<span class="value">{{ heroPointsStats.max }}<span class="text-muted small"> ({{ heroPointsStats.max / heroPointsStats.max | percent:'1.0-0' }})</span></span>
|
||||||
<div class="bars">
|
<div class="bars">
|
||||||
<div class="progress" style="height: 6px;">
|
<div class="progress" style="height: 6px;">
|
||||||
<div class="progress-bar bg-success" role="progressbar"
|
<div class="progress-bar bg-success" role="progressbar"
|
||||||
style="width: 100%" aria-valuemin="0" aria-valuemax="100"></div>
|
[style.width]="heroPointsStats.max / heroPointsStats.max | percent:'1.0-0'" aria-valuemin="0" aria-valuemax="100"></div>
|
||||||
</div> <!-- progress -->
|
</div> <!-- progress -->
|
||||||
</div> <!-- bars -->
|
</div> <!-- bars -->
|
||||||
</li>
|
</li>
|
||||||
<li> <!-- Weekly Average -->
|
<li> <!-- Weekly Average -->
|
||||||
<span class="title">Weekly Average</span>
|
<span class="title">Weekly Average</span>
|
||||||
<span class="value">{{ ((transactionListWeek | pluck: 'pointsEarned' | sum) / (transactionListWeek.length)) | round }}<span class="text-muted small"> ({{ (((transactionListWeek | pluck: 'pointsEarned' | sum) / (transactionListWeek.length)) | round ) / ( transactionListWeek | pluck: 'pointsEarned' | max ) | percent:'1.0-0' }})</span></span>
|
<span class="value">{{ heroPointsStats.avg }}<span class="text-muted small"> ({{ heroPointsStats.avg / heroPointsStats.max | percent:'1.0-0' }})</span></span>
|
||||||
<div class="bars">
|
<div class="bars">
|
||||||
<div class="progress" style="height: 6px;">
|
<div class="progress" style="height: 6px;">
|
||||||
<div class="progress-bar bg-success" role="progressbar"
|
<div class="progress-bar bg-success" role="progressbar"
|
||||||
style="width: 51%" aria-valuemin="0" aria-valuemax="100"></div>
|
[style.width]="heroPointsStats.avg / heroPointsStats.max | percent:'1.0-0'" aria-valuemin="0" aria-valuemax="100"></div>
|
||||||
</div> <!-- progess -->
|
</div> <!-- progess -->
|
||||||
</div> <!-- bars -->
|
</div> <!-- bars -->
|
||||||
</li>
|
</li>
|
||||||
|
@ -106,7 +106,7 @@
|
||||||
</div> <!-- if noUserList -->
|
</div> <!-- if noUserList -->
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 col-xl-6"> <!-- Medal Table -->
|
<div class="col-md-6 col-xl-6"> <!-- Medal Table -->
|
||||||
<div *ngIf="!noMedalList">
|
<div *ngIf="!noGlobalMedalList && !noOrganisationMedalList">
|
||||||
<table class="table header-fixed">
|
<table class="table header-fixed">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -115,110 +115,140 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<ng-container *ngFor="let groupNo of medalList | unique: 'medalGroupId'; let i = index"> <!-- ngFor each group of medals (global) -->
|
<ng-container *ngFor="let medals of globalMedalList"> <!-- ngFor each group of medals (global) -->
|
||||||
<ng-container *ngIf="(medalList | filterBy: ['title']: groupNo.title: search: true).length > 1"> <!-- if the group is longer than 1 -->
|
<ng-container *ngFor="let group of medals | values; let groupIndex = index">
|
||||||
|
<ng-container *ngIf="(group[0] | values).length - 1 > 1"> <!-- if the group is longer than 1 -->
|
||||||
<!-- *ngIf 'global' medal and is/isn't expanded (headers)-->
|
<!-- *ngIf 'global' medal and is/isn't expanded (headers)-->
|
||||||
<tr *ngIf="groupNo.expanded && groupNo.medalType == 'global'" (click)="groupNo.expanded = false" [ngStyle]="{'background-color': '#20A8D8', 'color': '#ffffff' }">
|
<tr *ngIf="group.expanded" (click)="group.expanded = false" [ngStyle]="{'background-color':(group[0] | values | filterBy: ['awarded']: 'true' | pluck: 'awarded').length === (group[0] | values | filterBy: ['awarded']).length ? '#5FBC47' : '#20A8D8', 'color': '#ffffff' }">
|
||||||
<td class="col-3">{{groupNo.title}}</td>
|
<td class="col-3">{{(medals | keys)[groupIndex]}}</td>
|
||||||
<td class="col-6">Click to collapse</td>
|
<td class="col-6">Click to collapse</td>
|
||||||
<td class="col-1">-</td>
|
<td class="col-1">-</td>
|
||||||
<td class="col-2" [ngStyle]="{'text-align': 'right'}">{{ ((medalList | filterBy: ['medalType']: 'global' | filterBy: ['title']: groupNo.title: search: true) | filterBy: ['unlocked']: true).length }}/{{ (medalList | filterBy: ['medalType']: 'global'| filterBy: ['title']: groupNo.title: search: true).length }}</td>
|
<td class="col-2" [ngStyle]="{'text-align': 'right'}">{{(group[0] | values | filterBy: ['awarded']: 'true' | pluck: 'awarded').length}}/{{(group[0] | values | filterBy: ['awarded']).length}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr *ngIf="!groupNo.expanded && groupNo.medalType == 'global'" (click)="groupNo.expanded = true" [ngStyle]="{'background-color': '#20A8D8', 'color': '#ffffff' }">
|
<tr *ngIf="!group.expanded" (click)="group.expanded = true" [ngStyle]="{'background-color':(group[0] | values | filterBy: ['awarded']: 'true' | pluck: 'awarded').length === (group[0] | values | filterBy: ['awarded']).length ? '#5FBC47' : '#20A8D8', 'color': '#ffffff' }">
|
||||||
<td class="col-3">{{groupNo.title}}</td>
|
<td class="col-3">{{(medals | keys)[groupIndex]}}</td>
|
||||||
<td class="col-6">Click to expand</td>
|
<td class="col-6">Click to expand</td>
|
||||||
<td class="col-1">+</td>
|
<td class="col-1">+</td>
|
||||||
<td class="col-2" [ngStyle]="{'text-align': 'right'}"> {{ ((medalList | filterBy: ['medalType']: 'global' | filterBy: ['title']: groupNo.title: search: true) | filterBy: ['unlocked']: true).length }}/{{ (medalList | filterBy: ['medalType']: 'global'| filterBy: ['title']: groupNo.title: search: true).length }}</td>
|
<td class="col-2" [ngStyle]="{'text-align': 'right'}">{{(group[0] | values | filterBy: ['awarded']: 'true' | pluck: 'awarded').length}}/{{(group[0] | values | filterBy: ['awarded']).length}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- display actual medals -->
|
<!-- display actual medals -->
|
||||||
<ng-container *ngFor="let medal of medalList | orderBy: ['+medalGroupId', '+reward']"> <!-- list each medal in each group, ordered by rewards, ascending order -->
|
<ng-container *ngFor="let threshold of group[0] | values | orderBy: '+threshold'; let thresholdIndex = index"> <!-- list each medal in each group, ordered by threshold, ascending order -->
|
||||||
<tr *ngIf="groupNo.expanded && medal.medalGroupId == i && groupNo.medalType == 'global'" [ngStyle]="{'background-color':medal.unlocked === true ? '#89DD73' : '#F25F5F', 'color': '#ffffff' }">
|
<ng-container *ngIf="threshold | isObject">
|
||||||
<td class="col-3">{{ medal.title }}</td>
|
<ng-container *ngIf="threshold.awarded">
|
||||||
<td class="col-7">{{ medal.description }}</td>
|
<tr *ngIf="group.expanded" [ngStyle]="{'background-color': '#5FBC47', 'color': '#ffffff' }">
|
||||||
<td class="col-2" [ngStyle]="{'text-align': 'right'}">0/{{ medal.valueRequired }}</td> <!-- progress -->
|
<ng-container *ngIf="">
|
||||||
|
</ng-container>
|
||||||
|
<td class="col-3">{{(medals | keys)[groupIndex]}} {{thresholdIndex + 1}}</td>
|
||||||
|
<td class="col-7">DESCRIPTION</td>
|
||||||
|
<ng-container *ngIf="thresholdIndex + 1 != (group[0] | values | orderBy: '+threshold').length - 1">
|
||||||
|
<td class="col-2" [ngStyle]="{'text-align': 'right'}">{{threshold.threshold}}/{{threshold.threshold}}</td> <!-- progress -->
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="thresholdIndex + 1 == (group[0] | values | orderBy: '+threshold').length - 1">
|
||||||
|
<td class="col-2" [ngStyle]="{'text-align': 'right'}">{{group[0].total}}/{{threshold.threshold}}</td> <!-- progress -->
|
||||||
|
</ng-container>
|
||||||
|
</tr>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="!threshold.awarded">
|
||||||
|
<tr *ngIf="group.expanded" [ngStyle]="{'background-color': '#F25F5F', 'color': '#ffffff' }">
|
||||||
|
<td class="col-3">{{(medals | keys)[groupIndex]}} {{thresholdIndex + 1}}</td>
|
||||||
|
<td class="col-7">DESCRIPTION</td>
|
||||||
|
<td class="col-2" [ngStyle]="{'text-align': 'right'}">{{group[0].total}}/{{threshold.threshold}}</td> <!-- progress -->
|
||||||
</tr>
|
</tr>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngIf="(medalList | filterBy: ['title']: groupNo.title: search: true).length == 1"> <!-- if there is only one medal in the group, just display medal, no header -->
|
</ng-container>
|
||||||
<ng-container *ngFor="let medal of medalList | orderBy: ['+medalGroupId', '+reward']"> <!-- Unnecessary loop because there is only one medal in each group -->
|
</ng-container>
|
||||||
<tr *ngIf="medal.medalGroupId == i && groupNo.medalType == 'global'" [ngStyle]="{'background-color':medal.unlocked === true ? '#89DD73' : '#F25F5F', 'color': '#ffffff' }">
|
<ng-container *ngIf="(group[0] | values).length - 1 == 1"> <!-- if there is only one medal in the group, just display medal, no header -->
|
||||||
<td class="col-3">{{ medal.title }}</td> <!-- medal name -->
|
<ng-container *ngFor="let threshold of group[0] | values | orderBy: '+threshold'; let thresholdIndex = index">
|
||||||
<td class="col-7">{{ medal.description }}</td> <!-- medal description -->
|
<ng-container *ngIf="threshold | isObject">
|
||||||
<td class="col-2" [ngStyle]="{'text-align': 'right'}">0/{{ medal.valueRequired }}</td> <!-- progress -->
|
<tr [ngStyle]="{'background-color':threshold.awarded === true ? '#5FBC47' : '#F25F5F', 'color': '#ffffff' }">
|
||||||
|
<td class="col-3">{{(medals | keys)[groupIndex]}}</td>
|
||||||
|
<td class="col-7">DESCRIPTION</td>
|
||||||
|
<td class="col-2" [ngStyle]="{'text-align': 'right'}">{{group[0].total}}/{{threshold.threshold}}</td> <!-- progress -->
|
||||||
</tr>
|
</tr>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
</ng-container> <!-- ngFor each group of medals (global) -->
|
</ng-container> <!-- ngFor each group of medals (global) -->
|
||||||
<ng-container *ngFor="let organisation of organisationList | orderBy: '+name'; let orgI = index"> <!-- ngFor organisation of organisationList -->
|
<ng-container *ngFor="let medals of organisationMedalList">
|
||||||
<!-- ngIf organisation is/isn't expanded display correct header -->
|
<ng-container *ngFor="let orgs of medals | values">
|
||||||
<tr *ngIf="organisation.expanded" (click)="organisation.expanded = false" [ngStyle]="{'background-color': '#F39C12', 'color': '#ffffff' }">
|
<ng-container *ngFor="let org of orgs; let orgIndex = index">
|
||||||
<td class="col-3">{{organisation.name}}</td>
|
<tr *ngIf="org.expanded" (click)="org.expanded = false" [ngStyle]="{'background-color': '#F39C12', 'color': '#ffffff' }">
|
||||||
|
<td class="col-3">{{org.name}}</td>
|
||||||
<td class="col-6">Click to collapse</td>
|
<td class="col-6">Click to collapse</td>
|
||||||
<td class="col-1">-</td>
|
<td class="col-1">-</td>
|
||||||
<td class="col-2" [ngStyle]="{'text-align': 'right'}">{{ (medalList | filterBy: ['medalType']: 'organisation' | filterBy: ['unlocked']: true).length }}/{{ (medalList | filterBy: ['medalType']: 'organisation').length }}</td>
|
<td class="col-2" [ngStyle]="{'text-align': 'right'}">{{org.count}}/{{org.threshold}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr *ngIf="!organisation.expanded" (click)="organisation.expanded = true" [ngStyle]="{'background-color': '#F39C12', 'color': '#ffffff' }">
|
<tr *ngIf="!org.expanded" (click)="org.expanded = true" [ngStyle]="{'background-color': '#F39C12', 'color': '#ffffff' }">
|
||||||
<td class="col-3">{{organisation.name}}</td>
|
<td class="col-3">{{org.name}}</td>
|
||||||
<td class="col-6">Click to expand</td>
|
<td class="col-6">Click to expand</td>
|
||||||
<td class="col-1">+</td>
|
<td class="col-1">+</td>
|
||||||
<td class="col-2" [ngStyle]="{'text-align': 'right'}">{{ (medalList | filterBy: ['medalType']: 'organisation' | filterBy: ['unlocked']: true).length }}/{{ (medalList | filterBy: ['medalType']: 'organisation').length }}</td>
|
<td class="col-2" [ngStyle]="{'text-align': 'right'}">{{org.count}}/{{org.threshold}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<ng-container *ngFor="let groupNo of medalList | unique: 'medalGroupId'; let i = index"> <!-- ngFor each group of medals (organisation) -->
|
<ng-container *ngFor="let group of org | values; let groupIndex = index">
|
||||||
<ng-container *ngIf="(medalList | filterBy: ['title']: groupNo.title: search: true).length > 1"> <!-- ngIf length of group is more than 1 -->
|
<ng-container *ngIf="group | isObject">
|
||||||
<!-- ngIf organisation is/isn't expanded -->
|
<ng-container *ngIf="(group[0] | keys).length - 1 > 1">
|
||||||
<tr *ngIf="organisation.expanded && groupNo.expanded && groupNo.medalType == 'organisation'" (click)="groupNo.expanded = false" [ngStyle]="{'background-color': '#20A8D8', 'color': '#ffffff' }">
|
<tr *ngIf="group.expanded && org.expanded" (click)="group.expanded = false" [ngStyle]="{'background-color': '#20A8D8', 'color': '#ffffff' }">
|
||||||
<td class="col-3">{{groupNo.title}}</td>
|
<td class="col-3">{{(org | keys)[groupIndex]}}</td>
|
||||||
<td class="col-6">Click to collapse</td>
|
<td class="col-6">Click to collapse</td>
|
||||||
<td class="col-1">-</td>
|
<td class="col-1">-</td>
|
||||||
<td class="col-2" [ngStyle]="{'text-align': 'right'}">{{ ((medalList | filterBy: ['medalType']: 'organisation' | filterBy: ['title']: groupNo.title: search: true) | filterBy: ['unlocked']: true).length }}/{{ (medalList | filterBy: ['medalType']: 'organisation'| filterBy: ['title']: groupNo.title: search: true).length }}</td>
|
<td class="col-2" [ngStyle]="{'text-align': 'right'}">{{(group[0] | values | filterBy: ['awarded']: 'true' | pluck: 'awarded').length}}/{{(group[0] | values | filterBy: ['awarded']).length}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr *ngIf="organisation.expanded && !groupNo.expanded && groupNo.medalType == 'organisation'" (click)="groupNo.expanded = true" [ngStyle]="{'background-color': '#20A8D8', 'color': '#ffffff' }">
|
<tr *ngIf="!group.expanded && org.expanded" (click)="group.expanded = true" [ngStyle]="{'background-color': '#20A8D8', 'color': '#ffffff' }">
|
||||||
<td class="col-3">{{groupNo.title}}</td>
|
<td class="col-3">{{(org | keys)[groupIndex]}}</td>
|
||||||
<td class="col-6">Click to expand</td>
|
<td class="col-6">Click to expand</td>
|
||||||
<td class="col-1">+</td>
|
<td class="col-1">+</td>
|
||||||
<td class="col-2" [ngStyle]="{'text-align': 'right'}">{{ ((medalList | filterBy: ['medalType']: 'organisation' | filterBy: ['title']: groupNo.title: search: true) | filterBy: ['unlocked']: true).length }}/{{ (medalList | filterBy: ['medalType']: 'organisation'| filterBy: ['title']: groupNo.title: search: true).length }}</td>
|
<td class="col-2" [ngStyle]="{'text-align': 'right'}">{{(group[0] | values | filterBy: ['awarded']: 'true' | pluck: 'awarded').length}}/{{(group[0] | values | filterBy: ['awarded']).length}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<ng-container *ngFor="let medal of medalList | orderBy: ['+medalGroupId', '+reward']">
|
<ng-container *ngFor="let threshold of group[0] | values | orderBy: '+threshold'; let thresholdIndex = index">
|
||||||
<tr *ngIf="organisation.expanded && groupNo.expanded && medal.medalGroupId == i && groupNo.medalType == 'organisation'" [ngStyle]="{'background-color':medal.unlocked === true ? '#89DD73' : '#F25F5F', 'color': '#ffffff' }">
|
<ng-container *ngIf="threshold | isObject">
|
||||||
<td class="col-3">{{ medal.title }}</td>
|
<ng-container *ngIf="threshold.awarded">
|
||||||
<td class="col-7">{{ medal.description }}</td>
|
<tr *ngIf="group.expanded && org.expanded" [ngStyle]="{'background-color': '#5FBC47', 'color': '#ffffff' }">
|
||||||
<td class="col-2" [ngStyle]="{'text-align': 'right'}">0/{{ medal.valueRequired }}</td>
|
<td class="col-3">{{(org | keys)[groupIndex]}} {{thresholdIndex + 1}}</td>
|
||||||
|
<td class="col-7">DESCRIPTION</td>
|
||||||
|
<ng-container *ngIf="thresholdIndex + 1 != (group[0] | values | orderBy: '+threshold').length - 1">
|
||||||
|
<td class="col-2" [ngStyle]="{'text-align': 'right'}">{{threshold.threshold}}/{{threshold.threshold}}</td>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="thresholdIndex + 1 == (group[0] | values | orderBy: '+threshold').length - 1">
|
||||||
|
<td class="col-2" [ngStyle]="{'text-align': 'right'}">{{group[0].total}}/{{threshold.threshold}}</td>
|
||||||
|
</ng-container>
|
||||||
|
</tr>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="!threshold.awarded">
|
||||||
|
<tr *ngIf="group.expanded && org.expanded" [ngStyle]="{'background-color': '#F25F5F', 'color': '#ffffff' }">
|
||||||
|
<td class="col-3">{{(org | keys)[groupIndex]}} {{thresholdIndex + 1}}</td>
|
||||||
|
<td class="col-7">DESCRIPTION</td>
|
||||||
|
<td class="col-2" [ngStyle]="{'text-align': 'right'}">{{group[0].total}}/{{threshold.threshold}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngIf="(medalList | filterBy: ['title']: groupNo.title: search: true).length <= 1"> <!-- ngIf length or group is <= 1 -->
|
</ng-container>
|
||||||
<ng-container *ngFor="let medal of medalList | orderBy: ['+medalGroupId', '+reward']">
|
</ng-container>
|
||||||
<tr *ngIf="organisation.expanded && medal.medalGroupId == i && groupNo.medalType == 'organisation'" [ngStyle]="{'background-color':medal.unlocked === true ? '#89DD73' : '#F25F5F', 'color': '#ffffff' }">
|
<ng-container *ngIf="(group[0] | keys).length - 1 == 1">
|
||||||
<td class="col-3">{{ medal.title }}</td>
|
<ng-container *ngFor="let threshold of group[0] | values | orderBy: '+threshold'; let thresholdIndex = index">
|
||||||
<td class="col-7">{{ medal.description }}</td>
|
<ng-container *ngIf="threshold | isObject">
|
||||||
<td class="col-2" [ngStyle]="{'text-align': 'right'}">0/{{ medal.valueRequired }}</td>
|
<ng-container *ngIf="org.expanded">
|
||||||
|
<tr [ngStyle]="{'background-color':threshold.awarded === true ? '#5FBC47' : '#F25F5F', 'color': '#ffffff' }">
|
||||||
|
<td class="col-3">{{(org | keys)[groupIndex]}}</td>
|
||||||
|
<td class="col-7">DESCRIPTION</td>
|
||||||
|
<td class="col-2" [ngStyle]="{'text-align': 'right'}">{{group[0].total}}/{{threshold.threshold}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container> <!-- ngFor each group of medals (organisation) -->
|
</ng-container>
|
||||||
</ng-container> <!-- ngFor organisation of organisationList -->
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div> <!-- if !noMedalList -->
|
</div> <!-- if !noMedalList -->
|
||||||
<div *ngIf="noMedalList" class="card-block">
|
<div *ngIf="noGlobalMedalList && noOrganisationMedalList" class="card-block">
|
||||||
No Leaderboard available.
|
No Leaderboard available.
|
||||||
</div> <!-- if noMedalList -->
|
</div> <!-- if noMedalList -->
|
||||||
</div>
|
|
||||||
</div><!-- Row -->
|
</div><!-- Row -->
|
||||||
<div *ngFor="let group of globalMedalList">
|
|
||||||
<div *ngFor="let threshold of group.group_name | pluck: 'threshold'">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div *ngFor="let medals of testList">
|
|
||||||
<div *ngFor="let group of medals | values; let groupIndex = index">
|
|
||||||
<div>threshold length - total {{(group[0] | values).length - 1}}</div>
|
|
||||||
<div>group_title {{(medals | keys)[groupIndex]}}</div>
|
|
||||||
<div>All awarded values for group {{group[0] | values | filterBy: ['awarded']: 'true' | pluck: 'awarded' | json}}</div>
|
|
||||||
<div *ngFor="let thresholds of group[0] | values">
|
|
||||||
<div *ngIf="thresholds | isObject">
|
|
||||||
<div>9 {{thresholds | json}}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,53 +13,34 @@ import 'rxjs/add/operator/map';
|
||||||
// import Services
|
// import Services
|
||||||
import { CustSnippetsService } from '../providers/cust-snippets.service';
|
import { CustSnippetsService } from '../providers/cust-snippets.service';
|
||||||
import { MedalsService } from '../providers/medals.service';
|
import { MedalsService } from '../providers/medals.service';
|
||||||
//import { HeroPointsStatsService } from '../providers/hero-points-stats.service';
|
import { HeroPointsSnippetsService } from '../providers/hero-points-snippets.service';
|
||||||
|
|
||||||
|
// Pipes
|
||||||
|
import { KeysPipe } from 'ngx-pipes';
|
||||||
|
import { FilterByPipe} from 'ngx-pipes';
|
||||||
|
import { ValuesPipe } from 'ngx-pipes';
|
||||||
|
import { PluckPipe } from 'ngx-pipes';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: './hero-points.component.html',
|
templateUrl: './hero-points.component.html',
|
||||||
|
|
||||||
|
//ngx Pipes
|
||||||
|
providers: [
|
||||||
|
KeysPipe,
|
||||||
|
FilterByPipe,
|
||||||
|
ValuesPipe,
|
||||||
|
PluckPipe,
|
||||||
|
HeroPointsSnippetsService,
|
||||||
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export class HeroPointsComponent implements OnInit {
|
export class HeroPointsComponent implements OnInit {
|
||||||
|
|
||||||
order: string = 'heroPoints';
|
order: string = 'heroPoints';
|
||||||
|
|
||||||
public testList = [
|
public globalMedalList = [{
|
||||||
{
|
|
||||||
group_name: [{
|
|
||||||
5: {
|
|
||||||
awarded: true,
|
|
||||||
awarded_at: null,
|
|
||||||
points: 0,
|
|
||||||
threshold: 5,
|
|
||||||
},
|
|
||||||
10: {
|
|
||||||
awarded: true,
|
|
||||||
awarded_at: null,
|
|
||||||
points: 0,
|
|
||||||
threshold: 10,
|
|
||||||
},
|
|
||||||
25: {
|
|
||||||
awarded: false,
|
|
||||||
awarded_at: null,
|
|
||||||
points: 0,
|
|
||||||
threshold: 25,
|
|
||||||
},
|
|
||||||
total: 11,
|
|
||||||
}],
|
|
||||||
group_name2: [{
|
|
||||||
10: {
|
|
||||||
awarded: false,
|
|
||||||
awarded_at: null,
|
|
||||||
points: 0,
|
|
||||||
threshold: 10,
|
|
||||||
},
|
|
||||||
total: 3,
|
|
||||||
}],
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
public globalMedalList = [
|
|
||||||
{
|
|
||||||
group_name: [{
|
group_name: [{
|
||||||
threshold: {
|
threshold: {
|
||||||
awarded: false,
|
awarded: false,
|
||||||
|
@ -69,8 +50,7 @@ export class HeroPointsComponent implements OnInit {
|
||||||
},
|
},
|
||||||
total: 0,
|
total: 0,
|
||||||
}],
|
}],
|
||||||
}
|
}];
|
||||||
]
|
|
||||||
|
|
||||||
public organisationMedalList = [{
|
public organisationMedalList = [{
|
||||||
org_id: [{
|
org_id: [{
|
||||||
|
@ -84,45 +64,20 @@ export class HeroPointsComponent implements OnInit {
|
||||||
total: 0,
|
total: 0,
|
||||||
}],
|
}],
|
||||||
name: '',
|
name: '',
|
||||||
|
count: null,
|
||||||
|
threshold: null,
|
||||||
}],
|
}],
|
||||||
}]
|
}];
|
||||||
|
|
||||||
public medals = {
|
|
||||||
global: {
|
|
||||||
group_name: {
|
|
||||||
threshold: {
|
|
||||||
awarded: false,
|
|
||||||
awarded_at: "2017-01-01-T00:00:00Z",
|
|
||||||
points: 0,
|
|
||||||
threshold: 0,
|
|
||||||
},
|
|
||||||
total: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
organisation: {
|
|
||||||
org_id: {
|
|
||||||
group_name: {
|
|
||||||
threshold: {
|
|
||||||
awarded: false,
|
|
||||||
awarded_at: "2017-01-01-T00:00:00Z",
|
|
||||||
multiplier: 0,
|
|
||||||
points: 0,
|
|
||||||
threshold: 0,
|
|
||||||
},
|
|
||||||
total: 0,
|
|
||||||
},
|
|
||||||
name: "Placeholder",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Hero points stats
|
// Hero points stats
|
||||||
public statsThisWeek = 0;
|
public heroPointsStats = {
|
||||||
public statsLastWeek = 0;
|
this_week: 0,
|
||||||
public statsMax = 0;
|
last_week: 0,
|
||||||
public statsSum = 0;
|
max: 0,
|
||||||
public statsCount = 0;
|
sum: 0,
|
||||||
|
count: 0,
|
||||||
|
avg: 0,
|
||||||
|
};
|
||||||
|
|
||||||
// Gets list of transactions
|
// Gets list of transactions
|
||||||
public paginateConfig: PaginationInstance = {
|
public paginateConfig: PaginationInstance = {
|
||||||
|
@ -145,7 +100,11 @@ export class HeroPointsComponent implements OnInit {
|
||||||
constructor(
|
constructor(
|
||||||
private api: ApiService,
|
private api: ApiService,
|
||||||
private medalsService: MedalsService,
|
private medalsService: MedalsService,
|
||||||
//private heroPointsStatsService: HeroPointsStatsService,
|
private keysPipe: KeysPipe,
|
||||||
|
private filterByPipe: FilterByPipe,
|
||||||
|
private valuesPipe: ValuesPipe,
|
||||||
|
private pluckPipe: PluckPipe,
|
||||||
|
private heroPointsSnippetsService: HeroPointsSnippetsService,
|
||||||
) {
|
) {
|
||||||
this.api.customerStats().subscribe(
|
this.api.customerStats().subscribe(
|
||||||
result => {
|
result => {
|
||||||
|
@ -173,19 +132,19 @@ export class HeroPointsComponent implements OnInit {
|
||||||
this.setGlobalMedalList(result.global),
|
this.setGlobalMedalList(result.global),
|
||||||
this.setOrganisationMedalList(result.organisation)
|
this.setOrganisationMedalList(result.organisation)
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
/*
|
|
||||||
this.heroPointsStatsService.getHeroPointsStats()
|
this.heroPointsSnippetsService.getHeroPointsSnippets()
|
||||||
.subscribe(
|
.subscribe(
|
||||||
result => {
|
result => {
|
||||||
this.statsThisWeek = result.points.stats.this_week;
|
this.heroPointsStats.this_week = result.widget_progress.this_week;
|
||||||
this.statsLastWeek = result.points.stats.last_week;
|
this.heroPointsStats.last_week = result.widget_progress.last_week;
|
||||||
this.statsMax = result.points.stats.max;
|
this.heroPointsStats.max = result.widget_progress.max;
|
||||||
this.statsSum = result.points.stats.sum;
|
this.heroPointsStats.sum = result.widget_progress.sum;
|
||||||
this.statsCount = result.points.stats.count;
|
this.heroPointsStats.count = result.widget_progress.count;
|
||||||
|
this.heroPointsStats.avg = result.widget_progress.sum / result.widget_progress.count;
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public setGlobalMedalList( data:any ){
|
public setGlobalMedalList( data:any ){
|
||||||
|
@ -216,6 +175,8 @@ export class HeroPointsComponent implements OnInit {
|
||||||
total: data.org_id.group_name.total,
|
total: data.org_id.group_name.total,
|
||||||
}],
|
}],
|
||||||
name: data.org_id.name,
|
name: data.org_id.name,
|
||||||
|
count: (this.pluckPipe.transform(this.filterByPipe.transform(this.valuesPipe.transform(data.org_id.group_name), ['awarded'], true), 'awarded')).length,
|
||||||
|
threshold: (this.filterByPipe.transform(this.valuesPipe.transform(data.org_id.group_name), ['awarded'], true)).length,
|
||||||
}],
|
}],
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
|
|
15
src/app/providers/hero-points-graph.service.ts
Normal file
15
src/app/providers/hero-points-graph.service.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { ApiService } from './api-service';
|
||||||
|
import { Observable } from 'rxjs/Rx';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class HeroPointsGraphService {
|
||||||
|
private heroPointsGraphUrl = '/v1/user/points';
|
||||||
|
|
||||||
|
constructor(private api: ApiService) { }
|
||||||
|
|
||||||
|
// This endpoint should mimic basicStats
|
||||||
|
public getHeroPointsGraph(): Observable<any> {
|
||||||
|
return this.api.post(this.heroPointsGraphUrl);
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ export class HeroPointsSnippetsService {
|
||||||
constructor(private api: ApiService) { }
|
constructor(private api: ApiService) { }
|
||||||
|
|
||||||
// This endpoint should mimic basicStats
|
// This endpoint should mimic basicStats
|
||||||
public getPointsData(): Observable<any> {
|
public getHeroPointsSnippets(): Observable<any> {
|
||||||
return this.api.post(this.heroPointsSnippetsUrl);
|
return this.api.post(this.heroPointsSnippetsUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { ApiService } from './api-service';
|
|
||||||
import { Observable } from 'rxjs/Rx';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class HeroPointsStatsService {
|
|
||||||
private heroPointsStatsUrl = '/v1/user/points';
|
|
||||||
|
|
||||||
constructor(private api: ApiService) { }
|
|
||||||
|
|
||||||
public getHeroPointsStats(): Observable<any> {
|
|
||||||
return this.api.post(this.heroPointsStatsUrl);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,6 +10,7 @@ export class MedalsService {
|
||||||
|
|
||||||
public getMedals(): Observable<any> {
|
public getMedals(): Observable<any> {
|
||||||
return this.api.post(this.medalsUrl);
|
return this.api.post(this.medalsUrl);
|
||||||
|
//return Observable.of()
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<ul style="list-style: none; padding-left: 0;">
|
<ul style="list-style: none; padding-left: 0;">
|
||||||
<li class="hidden-sm-down">
|
<li class="hidden-sm-down">
|
||||||
<div><h5 class="text-orange">My Hero Points</h5></div>
|
<div><h5 class="text-orange">My Hero Points</h5></div>
|
||||||
<div class="number-circle-hero mx-auto"><strong>{{ pointTotal | number:'1.0-0' }}</strong></div>
|
<div class="number-circle-hero mx-auto"><strong>{{ heroPointsSnippets.points_total | number:'1.0-0' }}</strong></div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
<ul style="list-style: none; padding-left: 0;">
|
<ul style="list-style: none; padding-left: 0;">
|
||||||
<li class="hidden-sm-down">
|
<li class="hidden-sm-down">
|
||||||
<div><h5 class="text-dark-green">Last Transaction Points</h5></div>
|
<div><h5 class="text-dark-green">Last Transaction Points</h5></div>
|
||||||
<div class="number-circle mx-auto"><strong>{{pointLast | number:'1.0-0' }}</strong></div>
|
<div class="number-circle mx-auto"><strong>{{ heroPointsSnippets.point_last | number:'1.0-0' }}</strong></div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
<ul style="list-style: none; padding-left: 0;">
|
<ul style="list-style: none; padding-left: 0;">
|
||||||
<li class="hidden-sm-down">
|
<li class="hidden-sm-down">
|
||||||
<div><h5 class="text-dark-green">Total Transactions</h5></div>
|
<div><h5 class="text-dark-green">Total Transactions</h5></div>
|
||||||
<div class="number-circle mx-auto"><strong>{{ transCount | number:'1.0-0' }}</strong></div>
|
<div class="number-circle mx-auto"><strong>{{ heroPointsSnippets.trans_count | number:'1.0-0' }}</strong></div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
<ul style="list-style: none; padding-left: 0;">
|
<ul style="list-style: none; padding-left: 0;">
|
||||||
<li class="hidden-sm-down">
|
<li class="hidden-sm-down">
|
||||||
<div><h5 class="text-dark-green">Average Multiplier</h5></div>
|
<div><h5 class="text-dark-green">Average Multiplier</h5></div>
|
||||||
<div class="number-circle mx-auto"><strong>{{ avgMulti | number:'1.0-0' }}</strong></div>
|
<div class="number-circle mx-auto"><strong>{{ heroPointsSnippets.avg_multi | number:'1.0-0' }}</strong></div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,24 +8,27 @@ import { HeroPointsSnippetsService } from '../providers/hero-points-snippets.ser
|
||||||
|
|
||||||
export class HeroPointsSnippetBarComponent implements OnInit {
|
export class HeroPointsSnippetBarComponent implements OnInit {
|
||||||
|
|
||||||
public pointTotal = 0;
|
// Hero Points snippets
|
||||||
public pointLast = 0;
|
public heroPointsSnippets = {
|
||||||
public transCount = 0;
|
avg_multi: 0,
|
||||||
public avgMulti = 0;
|
point_last: 0,
|
||||||
|
points_total: 0,
|
||||||
|
trans_count: 0,
|
||||||
|
};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private snippetsService: HeroPointsSnippetsService,
|
private heroPointsSnippetsService: HeroPointsSnippetsService,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
this.snippetsService.getPointsData()
|
this.heroPointsSnippetsService.getHeroPointsSnippets()
|
||||||
.subscribe(
|
.subscribe(
|
||||||
result => {
|
result => {
|
||||||
this.pointTotal = result.snippets.point_total;
|
this.heroPointsSnippets.avg_multi = result.snippets.avg_multi;
|
||||||
this.pointLast = result.snippets.point_last;
|
this.heroPointsSnippets.point_last = result.snippets.point_last;
|
||||||
this.transCount = result.snippets.trans_count;
|
this.heroPointsSnippets.points_total = result.snippets.points_total;
|
||||||
this.avgMulti = result.snippets.avg_multi;
|
this.heroPointsSnippets.trans_count = result.snippets.trans_count;
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
21
src/app/widgets/hero-points-graph-widget.component.html
Normal file
21
src/app/widgets/hero-points-graph-widget.component.html
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<div class="card card-inverse card-primary">
|
||||||
|
<div class="card-block pb-0">
|
||||||
|
<button type="button" class="btn btn-transparent p-0 float-right">
|
||||||
|
<i [ngClass]="graphIcon"></i>
|
||||||
|
</button>
|
||||||
|
<h4 *ngIf="dataType == availableDataTypes.number" class="mb-0">{{ graphSum }}</h4>
|
||||||
|
<p>{{ graphTitle }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="chart-wrapper px-3" style="height:70px;">
|
||||||
|
<canvas baseChart
|
||||||
|
class="chart"
|
||||||
|
[datasets]="lineChartData"
|
||||||
|
[labels]="lineChartLabels"
|
||||||
|
[options]="lineChartOptions"
|
||||||
|
[colors]="lineChartColours"
|
||||||
|
[legend]="lineChartLegend"
|
||||||
|
[chartType]="lineChartType"
|
||||||
|
(chartHover)="chartHovered($event)"
|
||||||
|
(chartClick)="chartClicked($event)"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
154
src/app/widgets/hero-points-graph-widget.component.ts
Normal file
154
src/app/widgets/hero-points-graph-widget.component.ts
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||||
|
import { OrgGraphsService } from '../providers/org-graphs.service';
|
||||||
|
import { DataType } from '../shared/data-types.enum';
|
||||||
|
|
||||||
|
interface ChartData {
|
||||||
|
data: Array<number>;
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'hero-points-widget-graph',
|
||||||
|
templateUrl: 'hero-points-graph-widget.component.html',
|
||||||
|
})
|
||||||
|
export class HeroPointsGraphWidget implements OnInit {
|
||||||
|
@Input() public graphName: string;
|
||||||
|
@Input() public graphTitle = 'Graph';
|
||||||
|
@Input() public graphIcon = 'icon-graph';
|
||||||
|
@Input() public dataType: DataType = DataType.number;
|
||||||
|
|
||||||
|
@Output() public graphHover = new EventEmitter();
|
||||||
|
@Output() public graphClick = new EventEmitter();
|
||||||
|
|
||||||
|
public graphSum: Number = 0;
|
||||||
|
public availableDataTypes = DataType;
|
||||||
|
|
||||||
|
public lineChartData: Array<ChartData> = [
|
||||||
|
{
|
||||||
|
data: [],
|
||||||
|
label: 'Series A'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
public lineChartLabels: Array<string>;
|
||||||
|
public lineChartOptions: any = {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
scales: {
|
||||||
|
xAxes: [{
|
||||||
|
type: 'time',
|
||||||
|
time: {
|
||||||
|
unit: 'day',
|
||||||
|
displayFormats: {
|
||||||
|
day: 'MMM D',
|
||||||
|
},
|
||||||
|
tooltipFormat: 'MMM D',
|
||||||
|
},
|
||||||
|
gridLines: {
|
||||||
|
color: 'transparent',
|
||||||
|
zeroLineColor: 'transparent'
|
||||||
|
},
|
||||||
|
ticks: {
|
||||||
|
fontSize: 2,
|
||||||
|
source: 'data',
|
||||||
|
fontColor: 'transparent',
|
||||||
|
}
|
||||||
|
|
||||||
|
}],
|
||||||
|
yAxes: [{
|
||||||
|
display: false,
|
||||||
|
ticks: {
|
||||||
|
display: false,
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
elements: {
|
||||||
|
line: {
|
||||||
|
borderWidth: 1
|
||||||
|
},
|
||||||
|
point: {
|
||||||
|
radius: 4,
|
||||||
|
hitRadius: 10,
|
||||||
|
hoverRadius: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
callbacks: {
|
||||||
|
label: (tooltip, data) => {
|
||||||
|
return this.tooltipLabelCallback(tooltip, data);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
public lineChartColours: Array<any> = [
|
||||||
|
{
|
||||||
|
backgroundColor: '#20a8d8',
|
||||||
|
borderColor: 'rgba(255,255,255,.55)'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
public lineChartLegend = false;
|
||||||
|
public lineChartType = 'line';
|
||||||
|
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private graphService: OrgGraphsService,
|
||||||
|
) { }
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
if ( this.graphName == null ) {
|
||||||
|
throw new Error('Attribute \'graphName\' is required on component \'widget-graph\'');
|
||||||
|
}
|
||||||
|
if ( this.dataType === undefined ) {
|
||||||
|
// Need to do this as it may be passed in a loop with an undefined value
|
||||||
|
this.dataType = DataType.number;
|
||||||
|
}
|
||||||
|
if ( !( this.dataType in DataType ) ) {
|
||||||
|
console.warn('Unknown DataType for graph \'' + this.graphName + '\' - defaulting to number');
|
||||||
|
}
|
||||||
|
this.graphService.getGraph(this.graphName)
|
||||||
|
.subscribe( result => this.setData(result.graph) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private setData(data: any) {
|
||||||
|
this.setChartData(data.data);
|
||||||
|
this.setChartLabels(data.labels);
|
||||||
|
this.setChartBounds(data.bounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
private setChartBounds(data) {
|
||||||
|
this.lineChartOptions.scales.xAxes[0].time.max = data.max;
|
||||||
|
this.lineChartOptions.scales.xAxes[0].time.min = data.min;
|
||||||
|
}
|
||||||
|
|
||||||
|
private setChartData(data: Array<number>) {
|
||||||
|
this.lineChartData[0].data = data;
|
||||||
|
this.graphSum = data.reduce((a, b) => a + b, 0);
|
||||||
|
// Set point size based on data
|
||||||
|
if ( data.length < 15 ) {
|
||||||
|
this.lineChartOptions.elements.point.radius = 4;
|
||||||
|
this.lineChartOptions.elements.line.borderWidth = 1;
|
||||||
|
} else {
|
||||||
|
this.lineChartOptions.elements.point.radius = 2;
|
||||||
|
this.lineChartOptions.elements.line.borderWidth = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private setChartLabels(data: Array<string>) {
|
||||||
|
this.lineChartLabels = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// events
|
||||||
|
public chartClicked(e: any): void {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public chartHovered(e: any): void {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private tooltipLabelCallback(tooltipItem: any, data: any) {
|
||||||
|
const value = tooltipItem.yLabel;
|
||||||
|
return value || '0';
|
||||||
|
}
|
||||||
|
}
|
Reference in a new issue