mirror of
https://github.com/simon987/task_tracker.git
synced 2025-12-13 23:09:02 +00:00
monitoring setup, project dashboard, account page
This commit is contained in:
@@ -3,7 +3,8 @@ import {ApiService} from "../api.service";
|
||||
import {Project} from "../models/project";
|
||||
import {ActivatedRoute} from "@angular/router";
|
||||
|
||||
import {Chart, ChartData, Point} from "chart.js";
|
||||
import {Chart} from "chart.js";
|
||||
import {AssignedTasks, MonitoringSnapshot} from "../models/monitoring";
|
||||
|
||||
|
||||
@Component({
|
||||
@@ -15,22 +16,30 @@ export class ProjectDashboardComponent implements OnInit {
|
||||
|
||||
private projectId;
|
||||
project: Project;
|
||||
noTasks = false;
|
||||
|
||||
private timeline: Chart;
|
||||
private statusPie: Chart;
|
||||
private assigneesPir: Chart;
|
||||
private assigneesPie: Chart;
|
||||
|
||||
|
||||
private colors = {
|
||||
new: "#76FF03",
|
||||
failed: "#FF3D00",
|
||||
closed: "#E0E0E0",
|
||||
awaiting: "#FFB74D"
|
||||
awaiting: "#FFB74D",
|
||||
random: [
|
||||
"#3D5AFE", "#2979FF", "#2196F3",
|
||||
"#7C4DFF", "#673AB7", "#7C4DFF",
|
||||
"#FFC400", "#FFD740", "#FFC107",
|
||||
"#FF3D00", "#FF6E40", "#FF5722",
|
||||
"#76FF03", "#B2FF59", "#8BC34A"
|
||||
]
|
||||
};
|
||||
|
||||
tmpLabels = [];
|
||||
tmpNew = [];
|
||||
tmpFailed = [];
|
||||
tmpClosed = [];
|
||||
tmpAwaiting = [];
|
||||
snapshots: MonitoringSnapshot[] = [];
|
||||
lastSnapshot: MonitoringSnapshot;
|
||||
assignees: AssignedTasks[];
|
||||
|
||||
constructor(private apiService: ApiService, private route: ActivatedRoute) {
|
||||
}
|
||||
@@ -42,19 +51,110 @@ export class ProjectDashboardComponent implements OnInit {
|
||||
this.getProject();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
let n = 40;
|
||||
for (let i = 0; i < n; i++) {
|
||||
this.tmpLabels.push((1549501926 + 600 * i) * 1000);
|
||||
this.tmpNew.push(Math.ceil(Math.random() * 30))
|
||||
this.tmpClosed.push(Math.ceil(Math.random() * 100))
|
||||
this.tmpFailed.push(Math.ceil(Math.random() * 13))
|
||||
this.tmpAwaiting.push(Math.ceil(Math.random() * 40))
|
||||
}
|
||||
public refresh() {
|
||||
|
||||
this.setupTimeline();
|
||||
this.setupStatusPie();
|
||||
this.setupAssigneesPie();
|
||||
this.apiService.getMonitoringSnapshots(60, this.projectId)
|
||||
.subscribe((data: any) => {
|
||||
this.snapshots = data.snapshots;
|
||||
this.lastSnapshot = this.snapshots ? this.snapshots.sort((a, b) => {
|
||||
return b.time_stamp - a.time_stamp
|
||||
})[0] : null;
|
||||
|
||||
if (this.lastSnapshot == null || (this.lastSnapshot.awaiting_verification_count == 0 &&
|
||||
this.lastSnapshot.closed_task_count == 0 &&
|
||||
this.lastSnapshot.new_task_count == 0 &&
|
||||
this.lastSnapshot.failed_task_count == 0)) {
|
||||
this.noTasks = true;
|
||||
return
|
||||
}
|
||||
this.noTasks = false;
|
||||
|
||||
this.timeline.data.labels = this.snapshots.map(s => s.time_stamp as any);
|
||||
this.timeline.data.datasets = this.makeTimelineDataset(this.snapshots);
|
||||
this.timeline.update();
|
||||
this.statusPie.data.datasets = [
|
||||
{
|
||||
label: "Task status",
|
||||
data: [
|
||||
this.lastSnapshot.new_task_count,
|
||||
this.lastSnapshot.failed_task_count,
|
||||
this.lastSnapshot.closed_task_count,
|
||||
this.lastSnapshot.awaiting_verification_count,
|
||||
],
|
||||
backgroundColor: [
|
||||
this.colors.new,
|
||||
this.colors.failed,
|
||||
this.colors.closed,
|
||||
this.colors.awaiting
|
||||
],
|
||||
}
|
||||
];
|
||||
this.statusPie.update();
|
||||
|
||||
this.apiService.getAssigneeStats(this.projectId)
|
||||
.subscribe((data: any) => {
|
||||
this.assignees = data.assignees;
|
||||
let colors = this.assignees.map(() => {
|
||||
return this.colors.random[Math.floor(Math.random() * this.colors.random.length)]
|
||||
});
|
||||
this.assigneesPie.data.labels = this.assignees.map(x => x.assignee);
|
||||
this.assigneesPie.data.datasets = [
|
||||
{
|
||||
label: "Task status",
|
||||
data: this.assignees.map(x => x.task_count),
|
||||
backgroundColor: colors,
|
||||
}
|
||||
];
|
||||
this.assigneesPie.update();
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
private makeTimelineDataset(snapshots: MonitoringSnapshot[]) {
|
||||
return [
|
||||
{
|
||||
label: "New",
|
||||
type: "line",
|
||||
fill: false,
|
||||
borderColor: this.colors.new,
|
||||
backgroundColor: this.colors.new,
|
||||
data: snapshots.map(s => s.new_task_count),
|
||||
pointRadius: 0,
|
||||
lineTension: 0.2,
|
||||
},
|
||||
{
|
||||
label: "Failed",
|
||||
type: "line",
|
||||
fill: false,
|
||||
borderColor: this.colors.failed,
|
||||
backgroundColor: this.colors.failed,
|
||||
data: snapshots.map(s => s.failed_task_count),
|
||||
pointRadius: 0,
|
||||
lineTension: 0.2,
|
||||
},
|
||||
{
|
||||
label: "Closed",
|
||||
type: "line",
|
||||
fill: false,
|
||||
borderColor: this.colors.closed,
|
||||
backgroundColor: this.colors.closed,
|
||||
pointRadius: 0,
|
||||
data: snapshots.map(s => s.closed_task_count),
|
||||
lineTension: 0.2,
|
||||
},
|
||||
{
|
||||
label: "Awaiting verification",
|
||||
type: "line",
|
||||
fill: false,
|
||||
borderColor: this.colors.awaiting,
|
||||
backgroundColor: this.colors.awaiting,
|
||||
data: snapshots.map(s => s.awaiting_verification_count),
|
||||
pointRadius: 0,
|
||||
lineTension: 0.2,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
private setupTimeline() {
|
||||
@@ -64,49 +164,8 @@ export class ProjectDashboardComponent implements OnInit {
|
||||
this.timeline = new Chart(ctx, {
|
||||
type: "bar",
|
||||
data: {
|
||||
labels: this.tmpLabels,
|
||||
datasets: [
|
||||
{
|
||||
label: "New",
|
||||
type: "line",
|
||||
fill: false,
|
||||
borderColor: this.colors.new,
|
||||
backgroundColor: this.colors.new,
|
||||
data: this.tmpNew,
|
||||
pointRadius: 0,
|
||||
lineTension: 0.2,
|
||||
},
|
||||
{
|
||||
label: "Failed",
|
||||
type: "line",
|
||||
fill: false,
|
||||
borderColor: this.colors.failed,
|
||||
backgroundColor: this.colors.failed,
|
||||
data: this.tmpFailed,
|
||||
pointRadius: 0,
|
||||
lineTension: 0.2,
|
||||
},
|
||||
{
|
||||
label: "Closed",
|
||||
type: "line",
|
||||
fill: false,
|
||||
borderColor: this.colors.closed,
|
||||
backgroundColor: this.colors.closed,
|
||||
pointRadius: 0,
|
||||
data: this.tmpClosed,
|
||||
lineTension: 0.2,
|
||||
},
|
||||
{
|
||||
label: "Awaiting verification",
|
||||
type: "line",
|
||||
fill: false,
|
||||
borderColor: this.colors.awaiting,
|
||||
backgroundColor: this.colors.awaiting,
|
||||
data: this.tmpAwaiting,
|
||||
pointRadius: 0,
|
||||
lineTension: 0.2,
|
||||
},
|
||||
],
|
||||
labels: this.snapshots.map(s => s.time_stamp as any),
|
||||
datasets: this.makeTimelineDataset(this.snapshots),
|
||||
},
|
||||
options: {
|
||||
title: {
|
||||
@@ -124,10 +183,6 @@ export class ProjectDashboardComponent implements OnInit {
|
||||
ticks: {
|
||||
source: "auto"
|
||||
},
|
||||
time: {
|
||||
unit: "minute",
|
||||
unitStepSize: 10,
|
||||
}
|
||||
}]
|
||||
},
|
||||
tooltips: {
|
||||
@@ -136,12 +191,20 @@ export class ProjectDashboardComponent implements OnInit {
|
||||
mode: "index",
|
||||
position: "nearest",
|
||||
},
|
||||
responsive: true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private setupStatusPie() {
|
||||
|
||||
if (this.lastSnapshot == null || (this.lastSnapshot.awaiting_verification_count == 0 &&
|
||||
this.lastSnapshot.closed_task_count == 0 &&
|
||||
this.lastSnapshot.new_task_count == 0 &&
|
||||
this.lastSnapshot.failed_task_count == 0)) {
|
||||
this.noTasks = true;
|
||||
}
|
||||
|
||||
let elem = document.getElementById("status-pie") as any;
|
||||
let ctx = elem.getContext("2d");
|
||||
|
||||
@@ -158,10 +221,10 @@ export class ProjectDashboardComponent implements OnInit {
|
||||
{
|
||||
label: "Task status",
|
||||
data: [
|
||||
10,
|
||||
24,
|
||||
301,
|
||||
90,
|
||||
this.lastSnapshot.new_task_count,
|
||||
this.lastSnapshot.failed_task_count,
|
||||
this.lastSnapshot.closed_task_count,
|
||||
this.lastSnapshot.awaiting_verification_count,
|
||||
],
|
||||
backgroundColor: [
|
||||
this.colors.new,
|
||||
@@ -186,7 +249,7 @@ export class ProjectDashboardComponent implements OnInit {
|
||||
animation: {
|
||||
animateScale: true,
|
||||
animateRotate: true
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -196,30 +259,19 @@ export class ProjectDashboardComponent implements OnInit {
|
||||
let elem = document.getElementById("assignees-pie") as any;
|
||||
let ctx = elem.getContext("2d");
|
||||
|
||||
this.statusPie = new Chart(ctx, {
|
||||
let colors = this.assignees.map(() => {
|
||||
return this.colors.random[Math.floor(Math.random() * this.colors.random.length)]
|
||||
});
|
||||
|
||||
this.assigneesPie = new Chart(ctx, {
|
||||
type: "doughnut",
|
||||
data: {
|
||||
labels: [
|
||||
"marc",
|
||||
"simon",
|
||||
"bernie",
|
||||
"natasha",
|
||||
],
|
||||
labels: this.assignees.map(x => x.assignee),
|
||||
datasets: [
|
||||
{
|
||||
label: "Task status",
|
||||
data: [
|
||||
10,
|
||||
24,
|
||||
1,
|
||||
23,
|
||||
],
|
||||
backgroundColor: [
|
||||
this.colors.new,
|
||||
this.colors.failed,
|
||||
this.colors.closed,
|
||||
this.colors.awaiting
|
||||
],
|
||||
data: this.assignees.map(x => x.task_count),
|
||||
backgroundColor: colors,
|
||||
}
|
||||
],
|
||||
},
|
||||
@@ -237,23 +289,35 @@ export class ProjectDashboardComponent implements OnInit {
|
||||
animation: {
|
||||
animateScale: true,
|
||||
animateRotate: true
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private getProject() {
|
||||
this.apiService.getProject(this.projectId).subscribe(data => {
|
||||
this.project = <Project>{
|
||||
id: data["project"]["id"],
|
||||
name: data["project"]["name"],
|
||||
clone_url: data["project"]["clone_url"],
|
||||
git_repo: data["project"]["git_repo"],
|
||||
motd: data["project"]["motd"],
|
||||
priority: data["project"]["priority"],
|
||||
version: data["project"]["version"],
|
||||
public: data["project"]["public"],
|
||||
}
|
||||
this.apiService.getProject(this.projectId).subscribe((data: any) => {
|
||||
this.project = data.project;
|
||||
|
||||
this.apiService.getMonitoringSnapshots(60, this.projectId)
|
||||
.subscribe((data: any) => {
|
||||
this.snapshots = data.snapshots;
|
||||
this.lastSnapshot = this.snapshots ? this.snapshots.sort((a, b) => {
|
||||
return b.time_stamp - a.time_stamp
|
||||
})[0] : null;
|
||||
|
||||
this.setupTimeline();
|
||||
this.setupStatusPie();
|
||||
|
||||
if (!this.snapshots) {
|
||||
return
|
||||
}
|
||||
|
||||
this.apiService.getAssigneeStats(this.projectId)
|
||||
.subscribe((data: any) => {
|
||||
this.assignees = data.assignees;
|
||||
this.setupAssigneesPie();
|
||||
});
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user