Skip to content
This repository was archived by the owner on Apr 15, 2025. It is now read-only.

Commit 0419013

Browse files
committed
Initial version
Though the backend supports per-commit querying, we currently make an inefficient query to gather all runs. The backend needs to support querying by projectid and test name or any arbitrary key/values. The frontend needs to be hosted somewhere so that the HTML5 history API will function properly when implemented.
0 parents  commit 0419013

File tree

4 files changed

+191
-0
lines changed

4 files changed

+191
-0
lines changed

CNAME

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ngdash.c-k.me

index.html

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<!doctype html>
2+
<html ng-app="ngDash">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="chrome=1">
6+
<title>Sample Report (ng-dash)</title>
7+
8+
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.13/angular.min.js"></script>
9+
<script src="index.js"></script>
10+
<script src="https://apis.google.com/js/client.js?onload=onGapiLoad"></script>
11+
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
12+
<link href="main.css" rel="stylesheet">
13+
<meta name="viewport" content="width=device-width, initial-scale=1">
14+
</head>
15+
<body ng-controller="MainController"><div class="wrapper">
16+
<h1>ng-dash – All Runs</h1><br>
17+
<div ng-hide="G.runs"></div>
18+
<div ng-if="G.runs">
19+
<ul ng-repeat="run in G.runs">
20+
<li>
21+
<div run="run"></div>
22+
</li>
23+
</ul>
24+
</div>
25+
</div>
26+
27+
28+
<script type="text/ng-template" id="/run.html">
29+
<div>
30+
<h4>
31+
commit <a href="https://github.com/angular/angular.dart/commit/{{run.commit_sha}}">{{run.commit_sha}}</a>
32+
on {{run.creation_timestamp | utcTimestampToLocalDate | date:'medium'}}
33+
by {{run.creator_email}}
34+
</h4>
35+
<div run-data="run.data" style="margin-left:-2em;"></div>
36+
</div>
37+
</script>
38+
39+
<script type="text/ng-template" id="/nameValues.html">
40+
<table ng-if="data">
41+
<tr ng-repeat="row in data">
42+
<td ng-bind="row.name"></td>
43+
<td ng-bind="row.value"></td>
44+
</tr>
45+
</table>
46+
</script>
47+
48+
49+
<script type="text/ng-template" id="/runData.html">
50+
<div>
51+
<h4>{{data.name}}</h4>
52+
<div style="margin-left: 2em;">
53+
<div name-values="data.dimensions"></div>
54+
<div name-values="data.metrics"></div>
55+
<div ng-if="data.children">
56+
<div ng-repeat="child in data.children">
57+
<div ng-init="data=child">
58+
<div ng-include="'/runData.html'"></div>
59+
</div>
60+
</div>
61+
</div>
62+
</div>
63+
</div>
64+
</script>
65+
66+
</body>
67+
</html>

index.js

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
"use strict";
2+
3+
var NG_DASH_API_ROOT = "https://ng-dash.appspot.com/_ah/api";
4+
var clientId = '731555738015-hna1v9or40ml5saoqh0b87t3j6fh6juv.apps.googleusercontent.com';
5+
var scopes = 'https://www.googleapis.com/auth/userinfo.email';
6+
7+
var G = {
8+
runs: [],
9+
errorMsg: ""
10+
};
11+
12+
function defaultCompare(a, b) {
13+
return (a == b) ? 0 : (a < b) ? -1 : 1;
14+
}
15+
16+
17+
function flattenNameValues(data, result, prefix) {
18+
result = result ? result : [];
19+
prefix = prefix ? prefix : "";
20+
Object.keys(data).forEach(function(name) {
21+
var value = data[name];
22+
if (value.__proto__ === Object.prototype) {
23+
flattenNameValues(value, result, prefix + name + ".");
24+
} else {
25+
result.push({name: prefix + name, value: value});
26+
}
27+
});
28+
result.sort(function(a, b) {
29+
return defaultCompare(a.name, b.name);
30+
});
31+
return result;
32+
}
33+
34+
35+
function processRunData(data) {
36+
data.dimensions = flattenNameValues(JSON.parse(data.dimensions_json));
37+
delete data.dimensions_json;
38+
data.metrics = flattenNameValues(JSON.parse(data.metrics_json));
39+
delete data.metrics_json;
40+
if (data.children) {
41+
data.children.forEach(processRunData);
42+
} else {
43+
data.children = [];
44+
}
45+
}
46+
47+
function processRun(run) {
48+
if (run.data) {
49+
processRunData(run.data);
50+
}
51+
}
52+
53+
54+
function processRuns(runs) {
55+
runs.sort(function compareCreationTimestamp(a, b) {
56+
return b.creation_timestamp - a.creation_timestamp;
57+
});
58+
runs.forEach(processRun);
59+
}
60+
61+
62+
function onNgDashApiLoaded() {
63+
gapi.client.ngdash.run.listRuns({}).execute(function(resp) {
64+
if (!resp.code) {
65+
G.runs = resp.items;
66+
processRuns(G.runs);
67+
} else {
68+
console.error(resp.code);
69+
G.errorMsg = "Error loading runs: " + resp.code;
70+
}
71+
});
72+
}
73+
74+
75+
function onGapiLoad() {
76+
gapi.client.load('ngdash', 'v0.1', onNgDashApiLoaded, NG_DASH_API_ROOT);
77+
}
78+
79+
80+
var module = angular.module('ngDash', []);
81+
82+
module.controller('MainController', ['$scope', function ($scope) {
83+
$scope.G = G;
84+
function onFrame() {
85+
$scope.$digest();
86+
window.requestAnimationFrame(onFrame);
87+
};
88+
window.requestAnimationFrame(onFrame);
89+
}]);
90+
91+
module.directive('run', function() {
92+
return {
93+
scope: { run: "=" },
94+
templateUrl: '/run.html'
95+
};
96+
});
97+
98+
module.directive('runData', function() {
99+
return {
100+
scope: { data: "=runData" },
101+
templateUrl: '/runData.html'
102+
};
103+
});
104+
105+
module.directive('nameValues', function() {
106+
return {
107+
scope: { data: "=nameValues", },
108+
templateUrl: '/nameValues.html'
109+
};
110+
});
111+
112+
module.filter('utcTimestampToLocalDate', function() {
113+
return function utcTimestampToLocalDate(timestamp) {
114+
return new Date(timestamp * 1000);
115+
};
116+
});

main.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
body {
2+
margin-left: 2em;
3+
}
4+
5+
li {
6+
padding-bottom: 4em;
7+
}

0 commit comments

Comments
 (0)