* widget layout implemented
This commit is contained in:
parent
7e82c57b0e
commit
985383797e
14
package-lock.json
generated
14
package-lock.json
generated
@ -3246,6 +3246,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"gify-parse": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/gify-parse/-/gify-parse-1.0.6.tgz",
|
||||||
|
"integrity": "sha1-NHRHheiiBLUhtJNtMFBwpqU0fos=",
|
||||||
|
"requires": {
|
||||||
|
"commander": "2.11.0",
|
||||||
|
"jdataview": "2.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"glob": {
|
"glob": {
|
||||||
"version": "7.1.2",
|
"version": "7.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
||||||
@ -5560,6 +5569,11 @@
|
|||||||
"integrity": "sha1-2llSddGuYx3nNqwKfH2Fyfc+9lI=",
|
"integrity": "sha1-2llSddGuYx3nNqwKfH2Fyfc+9lI=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"jdataview": {
|
||||||
|
"version": "2.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jdataview/-/jdataview-2.5.0.tgz",
|
||||||
|
"integrity": "sha1-MIGz/qZR+TF+xr1P6y3cmKpB1ZU="
|
||||||
|
},
|
||||||
"jquery": {
|
"jquery": {
|
||||||
"version": "3.2.1",
|
"version": "3.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.2.1.tgz",
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
"@angular/platform-browser-dynamic": "^4.0.0",
|
"@angular/platform-browser-dynamic": "^4.0.0",
|
||||||
"@angular/router": "^4.0.0",
|
"@angular/router": "^4.0.0",
|
||||||
"core-js": "^2.4.1",
|
"core-js": "^2.4.1",
|
||||||
|
"gify-parse": "^1.0.6",
|
||||||
"rxjs": "^5.4.1",
|
"rxjs": "^5.4.1",
|
||||||
"semantic-ui": "^2.2.11",
|
"semantic-ui": "^2.2.11",
|
||||||
"zone.js": "^0.8.14"
|
"zone.js": "^0.8.14"
|
||||||
|
|||||||
@ -3,13 +3,23 @@ import {Subscription} from "rxjs/Subscription";
|
|||||||
import {TimerObservable} from "rxjs/observable/TimerObservable";
|
import {TimerObservable} from "rxjs/observable/TimerObservable";
|
||||||
|
|
||||||
import {KanbanService} from "./kanban/shared/kanban.service";
|
import {KanbanService} from "./kanban/shared/kanban.service";
|
||||||
import {Router} from "@angular/router";
|
import {ActivatedRoute, Router} from "@angular/router";
|
||||||
import {SelfUpdaterService} from "./kanban/shared/self-updater.service";
|
import {SelfUpdaterService} from "./kanban/shared/self-updater.service";
|
||||||
|
|
||||||
|
|
||||||
const TIMER_DEPLOY_REFRESH = 30000;
|
const TIMER_DEPLOY_REFRESH = 30000;
|
||||||
const TIMER_JIRA_REFRESH = 60000;
|
const TIMER_JIRA_REFRESH = 60000;
|
||||||
const TIMER_PAGE_SWITCH = 300000;
|
const TIMER_PAGE_SWITCH_TICK = 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page switch timer in seconds
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
const TIMESPENT_KANBAN = 120000;
|
||||||
|
const TIMESPENT_TSPINFO = 60000;
|
||||||
|
|
||||||
|
const PAGE_KANBAN = '/kanban';
|
||||||
|
const PAGE_TSPINFO = '/tsp-info-page';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
@ -17,23 +27,25 @@ const TIMER_PAGE_SWITCH = 300000;
|
|||||||
styleUrls: ['./app.component.css']
|
styleUrls: ['./app.component.css']
|
||||||
})
|
})
|
||||||
export class AppComponent implements OnInit, OnDestroy {
|
export class AppComponent implements OnInit, OnDestroy {
|
||||||
|
private currentPage: string = PAGE_KANBAN;
|
||||||
|
private lastNavOccured: number = Date.now();
|
||||||
|
private autoSwitchEnabled: boolean = true;
|
||||||
|
|
||||||
selfUpdateCheckerTimer: Subscription;
|
private selfUpdateCheckerTimer: Subscription;
|
||||||
reloadJiraIssueTimer: Subscription;
|
private reloadJiraIssueTimer: Subscription;
|
||||||
pageSwitchTimer: Subscription;
|
private pageSwitchTimer: Subscription;
|
||||||
|
|
||||||
constructor(
|
constructor(private selfUpdaterService: SelfUpdaterService,
|
||||||
private selfUpdaterService: SelfUpdaterService,
|
|
||||||
private kanbanService: KanbanService,
|
private kanbanService: KanbanService,
|
||||||
private router: Router
|
private router: Router,
|
||||||
) {}
|
private activatedRoute: ActivatedRoute) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize application timers:
|
* Initialize application timers:
|
||||||
* - selfUpdateCheckerTimer is used to see if there is a newer revision deployed on the server
|
* - selfUpdateCheckerTimer is used to see if there is a newer revision deployed on the server
|
||||||
* - reloadJiraIssueTimer is used to refresh the status of the jira board
|
* - reloadJiraIssueTimer is used to refresh the status of the jira board
|
||||||
* - pageSwitchTimer handles switching back and forth between page views
|
* - pageSwitchTimer handles switching back and forth between page views
|
||||||
* @todo: pageSwitchTimer
|
|
||||||
*/
|
*/
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
let timer0 = TimerObservable.create(TIMER_DEPLOY_REFRESH, TIMER_JIRA_REFRESH);
|
let timer0 = TimerObservable.create(TIMER_DEPLOY_REFRESH, TIMER_JIRA_REFRESH);
|
||||||
@ -44,17 +56,63 @@ export class AppComponent implements OnInit, OnDestroy {
|
|||||||
this.reloadJiraIssueTimer = timer1.subscribe(() => {
|
this.reloadJiraIssueTimer = timer1.subscribe(() => {
|
||||||
this.kanbanService.reload();
|
this.kanbanService.reload();
|
||||||
});
|
});
|
||||||
let timer2 = TimerObservable.create(TIMER_PAGE_SWITCH, TIMER_PAGE_SWITCH);
|
this.activatedRoute.queryParamMap.subscribe(params => {
|
||||||
this.pageSwitchTimer = timer2.subscribe(() => {
|
if (!params.has("disableAutoSwitch")) {
|
||||||
// navigate to next page
|
let timer2 = TimerObservable.create(TIMER_PAGE_SWITCH_TICK, TIMER_PAGE_SWITCH_TICK);
|
||||||
// this.router.navigate();
|
// this.pageSwitchTimer = timer2.subscribe(this.switchSubscriber.bind(this));
|
||||||
console.log("pageSwitch");
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnDestroy() {
|
public ngOnDestroy() {
|
||||||
this.selfUpdateCheckerTimer.unsubscribe();
|
this.selfUpdateCheckerTimer.unsubscribe();
|
||||||
this.reloadJiraIssueTimer.unsubscribe();
|
this.reloadJiraIssueTimer.unsubscribe();
|
||||||
this.pageSwitchTimer.unsubscribe();
|
if (this.pageSwitchTimer) {
|
||||||
|
// this.pageSwitchTimer.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private switchSubscriber() {
|
||||||
|
let now = new Date();
|
||||||
|
let weekDay = now.getDay();
|
||||||
|
// on weekdays
|
||||||
|
if (weekDay > 0 && weekDay < 6) {
|
||||||
|
if (now.getHours() == 9 && now.getMinutes() >= 14 && this.autoSwitchEnabled) {
|
||||||
|
this.navigateToPage(PAGE_KANBAN);
|
||||||
|
this.autoSwitchEnabled = false;
|
||||||
|
}
|
||||||
|
if (now.getHours() == 9 && now.getMinutes() >= 29 && !this.autoSwitchEnabled) {
|
||||||
|
this.navigateToPage(PAGE_TSPINFO);
|
||||||
|
this.autoSwitchEnabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.autoSwitchEnabled) {
|
||||||
|
let compareTimer: number = 0;
|
||||||
|
let switchTo: string = '';
|
||||||
|
switch (this.currentPage) {
|
||||||
|
case PAGE_KANBAN:
|
||||||
|
compareTimer = TIMESPENT_KANBAN;
|
||||||
|
switchTo = PAGE_TSPINFO;
|
||||||
|
break;
|
||||||
|
case PAGE_TSPINFO:
|
||||||
|
compareTimer = TIMESPENT_TSPINFO;
|
||||||
|
switchTo = PAGE_KANBAN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.error("Unknown page in pageSwitcherTimer");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((Date.now() - this.lastNavOccured) > compareTimer) {
|
||||||
|
this.navigateToPage(switchTo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private navigateToPage(page: string) {
|
||||||
|
if (page != this.currentPage) {
|
||||||
|
this.router.navigate([page]);
|
||||||
|
this.currentPage = page;
|
||||||
|
this.lastNavOccured = Date.now();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,3 @@
|
|||||||
|
.widget.camera {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
<p>
|
<div class="widget camera">
|
||||||
animgif works!
|
<img [src]="cameraUrls[0]">
|
||||||
</p>
|
<img [src]="cameraUrls[1]">
|
||||||
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import {Component, Input, OnDestroy, OnInit} from '@angular/core';
|
||||||
import {InfoBoxComponent} from "../info-box/info-box.component";
|
import {InfoBoxComponent} from "../info-box/info-box.component";
|
||||||
|
import {AnimGif} from "../shared/anim-gif.model";
|
||||||
|
|
||||||
|
// import gifyParse from "gify-parse/gify-parse";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-animgif',
|
selector: 'app-animgif',
|
||||||
@ -9,13 +12,26 @@ import {InfoBoxComponent} from "../info-box/info-box.component";
|
|||||||
'./animgif.component.css'
|
'./animgif.component.css'
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class AnimgifComponent extends InfoBoxComponent implements OnInit {
|
export class AnimgifComponent extends InfoBoxComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
|
@Input() data: Array<AnimGif> = [];
|
||||||
|
@Input() cameraUrls: Array<string> = [];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
// gifyParse.getInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
// @todo subscriber
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
get imgHref(): string {
|
||||||
|
return this.cameraUrls[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,16 @@
|
|||||||
|
h2 {
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 76px;
|
||||||
|
font-weight: 700
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 30px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 15px;
|
||||||
|
color: rgba(255, 255, 255, 0.7);
|
||||||
|
}
|
||||||
@ -1,4 +1,7 @@
|
|||||||
<h1>{{title}}</h1>
|
<div class="widget {{widgetClass}}">
|
||||||
<h2>{{data.all}}</h2>
|
<h1>{{title}}</h1>
|
||||||
<h3>{{data.unassigned}}</h3>
|
<h2>{{data.all}}</h2>
|
||||||
<p>unassigned</p>
|
<h3>{{data.unassigned}}</h3>
|
||||||
|
<p>unassigned</p>
|
||||||
|
<i class="warning sign icon icon-background"></i>
|
||||||
|
</div>
|
||||||
@ -20,4 +20,11 @@ export class ExpeditesComponent extends InfoBoxComponent implements OnInit {
|
|||||||
|
|
||||||
ngOnInit() {}
|
ngOnInit() {}
|
||||||
|
|
||||||
|
get widgetClass(): string {
|
||||||
|
return this.data.unassigned > 0
|
||||||
|
? 'critical'
|
||||||
|
: this.data.all > 0
|
||||||
|
? 'warn'
|
||||||
|
: 'ok';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,107 @@
|
|||||||
:host {
|
:host {
|
||||||
display: inline-block;
|
position: absolute;
|
||||||
padding: 1.25em;
|
z-index: 2;
|
||||||
background-color: #0E566C;
|
display: table;
|
||||||
|
width: 468px;
|
||||||
|
height: 525px;
|
||||||
|
background-color: #00285F;
|
||||||
|
color: rgba(255, 255, 255, 0.7);
|
||||||
|
font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 20px;
|
||||||
|
box-shadow: 5px 5px 10px #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host-context(.sizex2) {
|
||||||
|
width: 946px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host-context(.sizey2) {
|
||||||
|
height: 1060px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host-context(.col1) {
|
||||||
|
left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host-context(.col2) {
|
||||||
|
left: 488px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host-context(.col3) {
|
||||||
|
left: 966px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host-context(.col4) {
|
||||||
|
left: 1444px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host-context(.row1) {
|
||||||
|
top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host-context(.row2) {
|
||||||
|
top: 545px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-family: 'EricssonCapital', "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 30px;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0 15px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul > li {
|
||||||
|
margin: 0 0 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul > li > span.label {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul > li > span.value {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widget {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 52px 12px;
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-background {
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
opacity: 0.1;
|
||||||
|
font-size: 300px;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 255px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ok {
|
||||||
|
background-color: rgb(137, 186, 23);
|
||||||
|
}
|
||||||
|
|
||||||
|
.warn {
|
||||||
|
background-color: #E95C38;
|
||||||
|
}
|
||||||
|
|
||||||
|
.critical {
|
||||||
|
background-color: rgb(227, 33, 25);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1 @@
|
|||||||
<p>
|
<p>info-box works!</p>
|
||||||
info-box works!
|
|
||||||
</p>
|
|
||||||
|
|||||||
@ -15,4 +15,7 @@ export class InfoBoxComponent implements OnInit {
|
|||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get widgetClass(): string {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +1,22 @@
|
|||||||
<p>
|
<p>
|
||||||
<app-tr-progress
|
<app-tr-progress
|
||||||
title="OVERDUE PROGRESS INFOS (DAYS)"
|
class="sizex2 col1 row1"
|
||||||
[data]="tspInfo.trProgressInfo"></app-tr-progress>
|
title="TR INFO"
|
||||||
<app-tr-flow-errors
|
[data]="{
|
||||||
title="TR FLOW ERRORS"
|
topData: tspInfo.trProgressInfo,
|
||||||
[data]="tspInfo.trFlowErrors"></app-tr-flow-errors>
|
bottomData: tspInfo.trFlowErrors
|
||||||
|
}"></app-tr-progress>
|
||||||
<app-pra-goals
|
<app-pra-goals
|
||||||
title="PRA TR GOALS(A,B,C PRIO)"
|
class="sizey2 col4 row1"
|
||||||
|
title="PRA TR GOALS (A,B,C PRIO)"
|
||||||
[data]="tspInfo.praGoals"></app-pra-goals>
|
[data]="tspInfo.praGoals"></app-pra-goals>
|
||||||
<app-expedites
|
<app-expedites
|
||||||
|
class="col3 row1"
|
||||||
title="NUMBER OF EXPEDITES (W/O PA)"
|
title="NUMBER OF EXPEDITES (W/O PA)"
|
||||||
[data]="tspInfo.expedites"></app-expedites>
|
[data]="tspInfo.expedites"></app-expedites>
|
||||||
<app-animgif
|
<app-animgif
|
||||||
title=""
|
class="col3 row2"
|
||||||
[data]="tspInfo.animGifs"></app-animgif>
|
title="ANIMATED IMPORTANCE"
|
||||||
|
[data]="tspInfo.animGifs"
|
||||||
|
[cameraUrls]="tspInfo.cameraUrls"></app-animgif>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -0,0 +1,28 @@
|
|||||||
|
p > span {
|
||||||
|
margin: 0 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
margin: 0 20px 0;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
.smallnum {
|
||||||
|
font-size: 30px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bignum {
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 76px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.numok {
|
||||||
|
color: rgb(137, 186, 23);
|
||||||
|
}
|
||||||
|
|
||||||
|
.numbad {
|
||||||
|
color: rgb(227, 33, 25);
|
||||||
|
}
|
||||||
@ -1,24 +1,27 @@
|
|||||||
<h1>{{title}}</h1>
|
<div class="widget">
|
||||||
<p>
|
<h1>{{title}}</h1>
|
||||||
<span class="heading">CORE</span>
|
<p class="header">
|
||||||
<span class="heading">SIG</span>
|
<span>CORE</span>
|
||||||
<span class="heading">TADE</span>
|
<span>SIG</span>
|
||||||
</p>
|
<span>TADE</span>
|
||||||
<p>
|
</p>
|
||||||
<span class="heading">{{data.core.A}}</span>
|
<p class="smallnum">
|
||||||
<span class="heading">{{data.sig.A}}</span>
|
<span [class]="getClass(data.core.A)">{{data.core.A}}</span>
|
||||||
<span class="heading">{{data.tade.A}}</span>
|
<span [class]="getClass(data.sig.A)">{{data.sig.A}}</span>
|
||||||
</p>
|
<span [class]="getClass(data.tade.A)">{{data.tade.A}}</span>
|
||||||
<h2>{{sumA}}</h2>
|
</p>
|
||||||
<p>
|
<h2 class="bignum {{getClass(sumA)}}">{{sumA}}</h2>
|
||||||
<span class="heading">{{data.core.B}}</span>
|
<p class="smallnum">
|
||||||
<span class="heading">{{data.sig.B}}</span>
|
<span [class]="getClass(data.core.B)">{{data.core.B}}</span>
|
||||||
<span class="heading">{{data.tade.B}}</span>
|
<span [class]="getClass(data.sig.B)">{{data.sig.B}}</span>
|
||||||
</p>
|
<span [class]="getClass(data.tade.B)">{{data.tade.B}}</span>
|
||||||
<h2>{{sumB}}</h2>
|
</p>
|
||||||
<p>
|
<h2 class="bignum {{getClass(sumB)}}">{{sumB}}</h2>
|
||||||
<span class="heading">{{data.core.C}}</span>
|
<p class="smallnum">
|
||||||
<span class="heading">{{data.sig.C}}</span>
|
<span [class]="getClass(data.core.C)">{{data.core.C}}</span>
|
||||||
<span class="heading">{{data.tade.C}}</span>
|
<span [class]="getClass(data.sig.C)">{{data.sig.C}}</span>
|
||||||
</p>
|
<span [class]="getClass(data.tade.C)">{{data.tade.C}}</span>
|
||||||
<h2>{{sumC}}</h2>
|
</p>
|
||||||
|
<h2 class="bignum {{getClass(sumC)}}">{{sumC}}</h2>
|
||||||
|
<i class="cocktail icon icon-background"></i>
|
||||||
|
</div>
|
||||||
|
|||||||
@ -40,4 +40,8 @@ export class PraGoalsComponent extends InfoBoxComponent implements OnInit {
|
|||||||
public sum(prio: string) {
|
public sum(prio: string) {
|
||||||
return ['core', 'sig', 'tade'].reduce((sum,unit) => sum + this.data[unit][prio], 0);
|
return ['core', 'sig', 'tade'].reduce((sum,unit) => sum + this.data[unit][prio], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getClass(value: number) {
|
||||||
|
return value < 1 ? 'numok' : 'numbad';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
<h1>{{title}} ({{errorSum}})</h1>
|
<div class="widget {{widgetClass}}">
|
||||||
<ul>
|
<h1>{{title}} ({{errorSum}})</h1>
|
||||||
|
<ul>
|
||||||
<li *ngFor="let flowError of data">
|
<li *ngFor="let flowError of data">
|
||||||
<span class="label">{{flowError.label}}</span>
|
<span class="label">{{flowError.label}}</span>
|
||||||
<span class="value">{{flowError.value}}</span>
|
<span class="value">{{flowError.value}}</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<i class="fire icon icon-background"></i>
|
||||||
|
</div>
|
||||||
@ -24,4 +24,8 @@ export class TrFlowErrorsComponent extends InfoBoxComponent implements OnInit {
|
|||||||
get errorSum(): number {
|
get errorSum(): number {
|
||||||
return this.data.reduce((sum: number, flowError: TrFlowError) => sum + flowError.value, 0);
|
return this.data.reduce((sum: number, flowError: TrFlowError) => sum + flowError.value, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get widgetClass(): string {
|
||||||
|
return this.data.length ? 'warn' : 'ok';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,3 @@
|
|||||||
|
.separator {
|
||||||
|
margin-top: 65px;
|
||||||
|
}
|
||||||
@ -1,7 +1,17 @@
|
|||||||
<h1>THE MOST OVERDUE PROGRESS INFOS (DAYS)</h1>
|
<div class="widget {{widgetClass}}">
|
||||||
<ul>
|
<h1>THE MOST OVERDUE PROGRESS INFOS (DAYS)</h1>
|
||||||
<li *ngFor="let progress of data">
|
<ul>
|
||||||
|
<li *ngFor="let progress of data.topData">
|
||||||
<span class="label">{{progress.eriref}} {{progress.heading}}</span>
|
<span class="label">{{progress.eriref}} {{progress.heading}}</span>
|
||||||
<span class="value">{{progress.lastProgressInDays}}</span>
|
<span class="value">{{progress.lastProgressInDays}}</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<h1 class="separator">TR FLOW ERRORS ({{errorSum}})</h1>
|
||||||
|
<ul>
|
||||||
|
<li *ngFor="let flowError of data.bottomData">
|
||||||
|
<span class="label">{{flowError.label}}</span>
|
||||||
|
<span class="value">{{flowError.value}}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<i class="warning sign icon icon-background"></i>
|
||||||
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import {Component, Input, OnInit} from '@angular/core';
|
import {Component, Input, OnInit} from '@angular/core';
|
||||||
import {InfoBoxComponent} from "../info-box/info-box.component";
|
import {InfoBoxComponent} from "../info-box/info-box.component";
|
||||||
import {TrProgress} from "../shared/tr-progress.model";
|
import {TrProgress} from "../shared/tr-progress.model";
|
||||||
|
import {TrFlowError} from "../shared/tr-flow-error.model";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-tr-progress',
|
selector: 'app-tr-progress',
|
||||||
@ -12,7 +13,10 @@ import {TrProgress} from "../shared/tr-progress.model";
|
|||||||
})
|
})
|
||||||
export class TrProgressComponent extends InfoBoxComponent implements OnInit {
|
export class TrProgressComponent extends InfoBoxComponent implements OnInit {
|
||||||
|
|
||||||
@Input() data: Array<TrProgress> = [];
|
@Input() data: {
|
||||||
|
topData: Array<TrProgress>,
|
||||||
|
bottomData: Array<TrFlowError>,
|
||||||
|
};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@ -21,4 +25,14 @@ export class TrProgressComponent extends InfoBoxComponent implements OnInit {
|
|||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get widgetClass(): string {
|
||||||
|
return [
|
||||||
|
this.data.topData,
|
||||||
|
this.data.bottomData
|
||||||
|
].every(data => data.length > 0) ? 'critical' : 'ok';
|
||||||
|
}
|
||||||
|
|
||||||
|
get errorSum(): number {
|
||||||
|
return this.data.bottomData.reduce((sum: number, flowError: TrFlowError) => sum + flowError.value, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
src/assets/font/impact.ttf
Normal file
BIN
src/assets/font/impact.ttf
Normal file
Binary file not shown.
BIN
src/assets/font/utm-ericsson-capital.ttf
Normal file
BIN
src/assets/font/utm-ericsson-capital.ttf
Normal file
Binary file not shown.
@ -1,4 +1,20 @@
|
|||||||
/* You can add global styles to this file, and also import other style files */
|
/* You can add global styles to this file, and also import other style files */
|
||||||
|
@import "//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700";
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'EricssonCapital';
|
||||||
|
src: url("./assets/font/utm-ericsson-capital.ttf");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Impact';
|
||||||
|
src: url("./assets/font/impact.ttf");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
height: 100% !important;
|
height: 100% !important;
|
||||||
@ -48,7 +64,7 @@ app-kanban-board {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.over-wip {
|
.over-wip {
|
||||||
background-color: rgba(194,59,34, 0.3);
|
background-color: rgba(194, 59, 34, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.prio-icon {
|
.prio-icon {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user