* tsp board disabled
* multi assignee
This commit is contained in:
parent
cc8a3ddd03
commit
82184678b9
@ -3,25 +3,25 @@ import {Subscription} from "rxjs/Subscription";
|
||||
import {TimerObservable} from "rxjs/observable/TimerObservable";
|
||||
|
||||
import {KanbanService} from "./kanban/shared/kanban.service";
|
||||
import {ActivatedRoute, NavigationEnd, Router} from "@angular/router";
|
||||
// import {ActivatedRoute, NavigationEnd, Router} from "@angular/router";
|
||||
import {SelfUpdaterService} from "./kanban/shared/self-updater.service";
|
||||
import {TspInfoService} from "./tsp-info/shared/tsp-info.service";
|
||||
// import {TspInfoService} from "./tsp-info/shared/tsp-info.service";
|
||||
|
||||
|
||||
const TIMER_DEPLOY_REFRESH = 30000;
|
||||
const TIMER_JIRA_REFRESH = 60000;
|
||||
const TIMER_TSPINFO_REFRESH = 60000;
|
||||
const TIMER_PAGE_SWITCH_TICK = 1000;
|
||||
// const TIMER_TSPINFO_REFRESH = 60000;
|
||||
// const TIMER_PAGE_SWITCH_TICK = 1000;
|
||||
|
||||
/**
|
||||
* Page switch timer in seconds
|
||||
* @type {number}
|
||||
*/
|
||||
const TIMESPENT_KANBAN = 120000;
|
||||
const TIMESPENT_TSPINFO = 30000;
|
||||
// const TIMESPENT_KANBAN = 120000;
|
||||
// const TIMESPENT_TSPINFO = 30000;
|
||||
|
||||
const PAGE_KANBAN = '/kanban';
|
||||
const PAGE_TSPINFO = '/tspinfopage';
|
||||
// const PAGE_KANBAN = '/kanban';
|
||||
// const PAGE_TSPINFO = '/tspinfopage';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@ -29,21 +29,21 @@ const PAGE_TSPINFO = '/tspinfopage';
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
export class AppComponent implements OnInit, OnDestroy {
|
||||
private currentPage: string = PAGE_KANBAN;
|
||||
private lastNavOccured: number = Date.now();
|
||||
private autoSwitchEnabled: boolean = true;
|
||||
// private currentPage: string = PAGE_KANBAN;
|
||||
// private lastNavOccured: number = Date.now();
|
||||
// private autoSwitchEnabled: boolean = true;
|
||||
|
||||
private selfUpdateCheckerTimer: Subscription;
|
||||
private reloadKanbanTimer: Subscription;
|
||||
private reloadTspInfoTimer: Subscription;
|
||||
private pageSwitchTimer: Subscription;
|
||||
// private reloadTspInfoTimer: Subscription;
|
||||
// private pageSwitchTimer: Subscription;
|
||||
|
||||
constructor(private selfUpdaterService: SelfUpdaterService,
|
||||
private kanbanService: KanbanService,
|
||||
private tspInfoService: TspInfoService,
|
||||
private router: Router,
|
||||
private activatedRoute: ActivatedRoute) {
|
||||
}
|
||||
// private tspInfoService: TspInfoService,
|
||||
// private router: Router,
|
||||
// private activatedRoute: ActivatedRoute
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Initialize application timers:
|
||||
@ -60,81 +60,81 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
this.reloadKanbanTimer = timer1.subscribe(() => {
|
||||
this.kanbanService.reload();
|
||||
});
|
||||
let timer2 = TimerObservable.create(TIMER_TSPINFO_REFRESH, TIMER_TSPINFO_REFRESH);
|
||||
this.reloadTspInfoTimer = timer2.subscribe(() => {
|
||||
this.tspInfoService.reload();
|
||||
});
|
||||
// let timer2 = TimerObservable.create(TIMER_TSPINFO_REFRESH, TIMER_TSPINFO_REFRESH);
|
||||
// this.reloadTspInfoTimer = timer2.subscribe(() => {
|
||||
// this.tspInfoService.reload();
|
||||
// });
|
||||
|
||||
this.router.events
|
||||
.filter(e => e instanceof NavigationEnd)
|
||||
.map(() => {
|
||||
let route = this.activatedRoute;
|
||||
while (route.firstChild) {
|
||||
route = route.firstChild;
|
||||
}
|
||||
return route;
|
||||
})
|
||||
.filter((route) => route.outlet === 'primary')
|
||||
.mergeMap((route) => route.data)
|
||||
.subscribe(data => {
|
||||
if (!data['disableAutoSwitch']) {
|
||||
let timer4 = TimerObservable.create(TIMER_PAGE_SWITCH_TICK, TIMER_PAGE_SWITCH_TICK);
|
||||
this.pageSwitchTimer = timer4.subscribe(this.switchSubscriber.bind(this));
|
||||
}
|
||||
});
|
||||
// this.router.events
|
||||
// .filter(e => e instanceof NavigationEnd)
|
||||
// .map(() => {
|
||||
// let route = this.activatedRoute;
|
||||
// while (route.firstChild) {
|
||||
// route = route.firstChild;
|
||||
// }
|
||||
// return route;
|
||||
// })
|
||||
// .filter((route) => route.outlet === 'primary')
|
||||
// .mergeMap((route) => route.data)
|
||||
// .subscribe(data => {
|
||||
// if (!data['disableAutoSwitch']) {
|
||||
// let timer4 = TimerObservable.create(TIMER_PAGE_SWITCH_TICK, TIMER_PAGE_SWITCH_TICK);
|
||||
// this.pageSwitchTimer = timer4.subscribe(this.switchSubscriber.bind(this));
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
public ngOnDestroy() {
|
||||
this.selfUpdateCheckerTimer.unsubscribe();
|
||||
this.reloadKanbanTimer.unsubscribe();
|
||||
this.reloadTspInfoTimer.unsubscribe();
|
||||
if (this.pageSwitchTimer) {
|
||||
this.pageSwitchTimer.unsubscribe();
|
||||
}
|
||||
// this.reloadTspInfoTimer.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() == 10) {
|
||||
if (this.autoSwitchEnabled && now.getMinutes() > 14) {
|
||||
this.navigateToPage(PAGE_KANBAN);
|
||||
this.autoSwitchEnabled = false;
|
||||
}
|
||||
if (!this.autoSwitchEnabled && now.getMinutes() > 30) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
// private switchSubscriber() {
|
||||
// let now = new Date();
|
||||
// let weekDay = now.getDay();
|
||||
// // on weekdays
|
||||
// if (weekDay > 0 && weekDay < 6) {
|
||||
// if (now.getHours() == 10) {
|
||||
// if (this.autoSwitchEnabled && now.getMinutes() > 14) {
|
||||
// this.navigateToPage(PAGE_KANBAN);
|
||||
// this.autoSwitchEnabled = false;
|
||||
// }
|
||||
// if (!this.autoSwitchEnabled && now.getMinutes() > 30) {
|
||||
// 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();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@ -57,3 +57,43 @@ a:hover {
|
||||
/*.ui.divided.items > .item.trivial.bottom-separator {*/
|
||||
/*border-bottom: 1px solid rgba(181, 204, 24, 0.5);*/
|
||||
/*}*/
|
||||
|
||||
.ui.images {
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
margin-left: 0px;
|
||||
margin-right: 4px;
|
||||
margin-bottom: 0;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ui.images .image {
|
||||
margin: 0;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
/* 2 images */
|
||||
.ui.two.images .image {
|
||||
width: 22px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
/* 3 images */
|
||||
.ui.three.images .image {
|
||||
height: 22px;
|
||||
}
|
||||
.ui.three.images .image:first-child {
|
||||
object-fit: cover;
|
||||
}
|
||||
.ui.three.images .image:not(:first-child) {
|
||||
width: 22px;
|
||||
margin-top: -14px;
|
||||
}
|
||||
|
||||
/* 4 images */
|
||||
.ui.four.images .image {
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
}
|
||||
|
||||
@ -5,17 +5,27 @@
|
||||
</ng-template>
|
||||
</h1>
|
||||
<div class="ui divided items">
|
||||
<div class="item {{kanbanEntry.issuePriority|lowercase}}" [ngClass]="entryClass(kanbanEntry)" *ngFor="let kanbanEntry of kanbanEntries">
|
||||
<div *ngFor="let kanbanEntry of kanbanEntries"
|
||||
class="item {{kanbanEntry.issuePriority|lowercase}}"
|
||||
[ngClass]="entryClass(kanbanEntry)">
|
||||
<div class="content">
|
||||
<div class="task-description">
|
||||
<ng-template [ngIf]="hasLabels(kanbanEntry)">
|
||||
<span *ngFor="let label of kanbanEntry.labels" class="ui mini {{labelClass(label)}} right floated label">{{label|uppercase|blockedDays:kanbanEntry.daysBlocked}}</span>
|
||||
<span *ngFor="let label of kanbanEntry.labels"
|
||||
class="ui mini {{labelClass(label)}} right floated label">{{label|uppercase|blockedDays:kanbanEntry.daysBlocked}}</span>
|
||||
</ng-template>
|
||||
<span *ngIf="wasBlocked(kanbanEntry)" class="ui mini {{labelClass('blocked')}} right floated label">{{kanbanEntry.daysBlocked}}D</span>
|
||||
<div class="ui jira-avatar floated image">
|
||||
<div *ngIf="!hasMultiAssignee(kanbanEntry)" class="ui jira-avatar floated image">
|
||||
<img src="{{avatarUrl(kanbanEntry.assignee?.avatar)}}" [title]="kanbanEntry.assignee?.name">
|
||||
</div>
|
||||
<a [href]="jiraHref(kanbanEntry)" target="_blank" [innerHTML]="kanbanEntry.summary|shortenText|priorityColor:kanbanEntry.issuePriorityIcon:kanbanEntry.worklog" [title]="kanbanEntry.summary"></a>
|
||||
<div *ngIf="hasMultiAssignee(kanbanEntry)" class="ui jira-avatar floated {{assigneeCount(kanbanEntry)}} images">
|
||||
<img *ngFor="let assignee of getAssignees(kanbanEntry)" class="image"
|
||||
src="{{avatarUrl(assignee?.avatar)}}"
|
||||
[title]="assignee?.name">
|
||||
</div>
|
||||
<a [href]="jiraHref(kanbanEntry)" target="_blank"
|
||||
[innerHTML]="kanbanEntry.summary|shortenText|priorityColor:kanbanEntry.issuePriorityIcon:kanbanEntry.worklog"
|
||||
[title]="kanbanEntry.summary"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -2,6 +2,7 @@ import {Component, Input} from '@angular/core';
|
||||
|
||||
import {environment} from "../../../environments/environment";
|
||||
import {KanbanEntry} from "../shared";
|
||||
import { JiraAssignee } from "../shared/jira-assignee.model";
|
||||
|
||||
const DEFAULT_AVATAR = '/assets/riddler.png';
|
||||
const JIRA_BOARD_BASE_HREF = 'https://jirapducc.mo.ca.am.ericsson.se/browse/';
|
||||
@ -97,4 +98,22 @@ export class KanbanEntryItemComponent {
|
||||
return kanbanEntry.daysBlocked > 0
|
||||
&& kanbanEntry.labels.every(label => label.toUpperCase() != 'BLOCKED');
|
||||
}
|
||||
|
||||
public hasMultiAssignee(kanbanEntry: KanbanEntry): boolean {
|
||||
return kanbanEntry.additionalAssignees.length > 0;
|
||||
}
|
||||
|
||||
public assigneeCount(kanbanEntry: KanbanEntry): string {
|
||||
let count = 1 + kanbanEntry.additionalAssignees.length;
|
||||
switch (count) {
|
||||
case 2: return "two";
|
||||
case 3: return "three";
|
||||
case 4:
|
||||
default: return "four";
|
||||
}
|
||||
}
|
||||
|
||||
public getAssignees(kanbanEntry: KanbanEntry): Array<JiraAssignee> {
|
||||
return [].concat([kanbanEntry.assignee], kanbanEntry.additionalAssignees);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ export class KanbanEntry {
|
||||
public issueType: JiraIssueType;
|
||||
public status: JiraStatus;
|
||||
public assignee: JiraAssignee;
|
||||
public additionalAssignees: Array<JiraAssignee> = [];
|
||||
public issuePriority: string;
|
||||
public issuePriorityIcon: string;
|
||||
public labels: Array<string>;
|
||||
|
||||
@ -5,5 +5,5 @@
|
||||
|
||||
export const environment = {
|
||||
production: false,
|
||||
apiUri: "http://localhost:8080",
|
||||
apiUri: "http://localhost:8888",
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user