summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alvarez <pedro.alvarez@codethink.co.uk>2015-09-28 16:30:22 (GMT)
committerPedro Alvarez <pedro.alvarez@codethink.co.uk>2015-09-28 16:30:22 (GMT)
commite9aaaaba7425cfb127954327460afb8a4e189f40 (patch)
tree5b1ae5ea4f107875612074e0fd544104a5bc60e4
downloadciat-ui-e9aaaaba7425cfb127954327460afb8a4e189f40.tar.gz
Import Adam Coldrick and Michael Drake work
-rw-r--r--index.html39
-rw-r--r--js/main.js76
-rw-r--r--style.css98
3 files changed, 213 insertions, 0 deletions
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..75a0923
--- /dev/null
+++ b/index.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link href='https://fonts.googleapis.com/css?family=Sarpanch:800' rel='stylesheet' type='text/css'>
+ <link href='style.css' rel='stylesheet' type='text/css'>
+ <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.28/angular.min.js"></script>
+ <script src="js/main.js"></script>
+</head>
+<body ng-app="ciat">
+ <h1><em>Baserock</em> <span>|</span> CIAT</h1>
+ <div class="container" ng-controller="VisualisationController" ng-click="select()">
+ <div class="visualisation">
+ <div class="box"
+ ng-class="{'pass': step.lastBuild.success, 'active': step.data.state == 'building', 'fail': step.lastBuild.failed}"
+ ng-repeat="step in steps"
+ ng-click="select(step, $event)">
+ {{step.name}}
+ </div>
+ <br />
+ <div class="detail"
+ ng-show="selected"
+ ng-click="$event.stopPropagation()">
+ <h3>{{selected.name}}</h3>
+ <div class="detail-contents">
+ <p><strong>State:</strong> {{selected.data.state}}</p>
+ <p><strong>Last Build:</strong> {{selected.lastBuild.number}} at {{selected.lastBuild.sourceStamps[0].changes[0].at}}
+ <p><strong>Logs for {{selected.lastBuild.number}}:</strong></p>
+ <ul>
+ <li ng-repeat="step in selected.lastBuild.steps">
+ <a ng-href="{{step.logs[0][1]}}">{{step.name}} {{step.logs[0][0]}}</a>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+</body>
+</html>
+
diff --git a/js/main.js b/js/main.js
new file mode 100644
index 0000000..a31c5f0
--- /dev/null
+++ b/js/main.js
@@ -0,0 +1,76 @@
+var app = angular.module('ciat', []);
+
+app.config(['$httpProvider', function($httpProvider) {
+ $httpProvider.defaults.useXDomain = true;
+ delete $httpProvider.defaults.headers.common['X-Requested-With'];
+ }
+]);
+
+app.controller('VisualisationController', function($scope, $http, $q, $interval) {
+ function checkInArray(array, key) {
+ if (array) {
+ if (array.indexOf(key) > -1) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function load() {
+ $scope.steps = [];
+ $http.get('http://ciat.baserock.org:8010/json/builders')
+ .then(function(builders) {
+ angular.forEach(builders.data, function(value, key) {
+ var lastBuildID;
+ if (value.state === 'building') {
+ lastBuildID = value.cachedBuilds[value.cachedBuilds.length - 2];
+ } else {
+ lastBuildID = value.cachedBuilds[value.cachedBuilds.length - 1];
+ }
+
+ var buildsPath = 'http://ciat.baserock.org:8010/json/builders/' +
+ key + '/builds/' + lastBuildID;
+ $http.get(buildsPath).then(function(response) {
+ var details = {
+ success: checkInArray(response.data.text, 'successful'),
+ failed: checkInArray(response.data.text, 'failed'),
+ steps: response.data.steps,
+ sourceStamps: response.data.sourceStamps,
+ number: response.data.number
+ };
+ $scope.steps.push({
+ name: key,
+ lastBuild: details,
+ data: value
+ });
+ $scope.steps.sort(function(a, b) {
+ return a.name.charAt(0) > b.name.charAt(0);
+ });
+ });
+ });
+ });
+ }
+
+ $scope.selected = null;
+ $scope.select = function(step, e) {
+ if (e) {
+ e.stopPropagation();
+ }
+ $scope.selected = step;
+ };
+
+ function cancelRefresh() {
+ if (angular.isDefined(autorefresh)) {
+ $interval.cancel(autorefresh);
+ autorefresh = undefined;
+ }
+ }
+
+ load();
+ var autorefresh = $interval(load, 60000);
+
+ $scope.$on('$destroy', function() {
+ cancelRefresh();
+ });
+ }
+);
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..2bcc6d1
--- /dev/null
+++ b/style.css
@@ -0,0 +1,98 @@
+
+
+html,body {
+ margin: 0;
+ padding: 0;
+ overflow-x: hidden;
+ height: 100%;
+}
+
+body {
+ color: #bbb;
+ background: #444;
+ font-family: sans-serif;
+}
+
+h1 {
+ font-family: 'Sarpanch', sans-serif;
+ font-size: 32pt;
+ border-bottom: 2px solid #f80;
+ padding: 2.1em 1.5em 0.1em 1.5em;
+ box-shadow: inset 0 0 60px 10px #111;
+ margin: 0 -1em -1em -1em;
+ position: relative;
+ top: -2em;
+}
+
+h1>em {
+ font-style: normal;
+ color: #ddd;
+}
+
+h1>span {
+ font-style: normal;
+ color: #777;
+}
+
+.box {
+ color: black;
+ display: inline-block;
+ padding: 1em;
+ margin: 1.4em;
+ box-shadow:6px 6px 10px 2px #111;
+ border-radius: 0.5em;
+}
+
+.box:hover {
+ cursor: pointer;
+}
+
+.pass {
+ background: #77ee77;
+ border: 2px solid #00dd00;
+}
+
+.fail {
+ background: #ff8888;
+ border: 2px solid #ff0000;
+}
+
+.active {
+ -webkit-animation:active 1s linear infinite;
+ animation:active 1s linear infinite;
+}
+
+@-webkit-keyframes active {
+ 0%{box-shadow:0 0 0 1px #444, 0 0 0 4px rgba(255, 255, 78, 0.7),6px 6px 10px 2px #111}
+ 100%{box-shadow:0 0 0 5px #444, 0 0 0 14px rgba(255, 255, 78, 0 ),6px 6px 10px 2px #111}
+}
+
+@keyframes active {
+ 0%{box-shadow:0 0 0 1px #444, 0 0 0 4px rgba(255, 255, 78, 0.7),6px 6px 10px 2px #111}
+ 100%{box-shadow:0 0 0 5px #444, 0 0 0 14px rgba(255, 255, 78, 0 ),6px 6px 10px 2px #111}
+}
+
+.visualisation {
+ font-size: 90%;
+ position: absolute;
+ text-align: center;
+ width: 100%;
+ top: 45%;
+}
+
+.detail {
+ background: #eee;
+ color: black;
+ display: inline-block;
+ padding: 1em;
+ border-radius: 0.5em;
+ width: 50%;
+}
+
+.detail-contents {
+ text-align: left;
+}
+
+.container {
+ height: 85%;
+}