Skip to content

Commit

Permalink
www_ui: first stub implementation of some widgets
Browse files Browse the repository at this point in the history
provided as an example on how this is supposed to work

Code should eventually be replaced by using the api

Signed-off-by: Pierre Tardy <tardyp@gmail.com>
  • Loading branch information
tardyp authored and Pierre Tardy committed Jul 26, 2012
1 parent 46f48f8 commit 1fdfd0f
Show file tree
Hide file tree
Showing 11 changed files with 322 additions and 16 deletions.
17 changes: 17 additions & 0 deletions master/buildbot/www/static/js/lib/fakeChangeStore.js
@@ -0,0 +1,17 @@
define(
[
"dojo/_base/declare",
"lib/fakeStore"
],
function(declare, fakeStore) {
var data=[];
return declare(fakeStore, {
data:data,
fields: ["changeid", "revision", "committer", "files", "comments" ],
addData: function(o) {
/* persist data over reload */
data = this.data;
this.put(o);
}
});
});
39 changes: 39 additions & 0 deletions master/buildbot/www/static/js/lib/fakeStore.js
@@ -0,0 +1,39 @@
define(
[
"dojo/_base/declare",
"dojo/store/Memory"
],
function(declare, Memory) {
return declare([Memory], {
fields: ["field1"],
constructor: function(args){
declare.safeMixin(this,args);
this.interval = setInterval(dojo.hitch(this, this.addSomeData), 1000); //simulate adding some data every second
},
addSomeData: function() {
var randomfeed = "sdlkjs alkdj alsdjl ksdj lsajldkjaslkdj asdlkja iwjedo ajlskj lhsl";
var curId=0;
if (this.data.length>0) {
curId = this.data[this.data.length-1].id+1;
}
var o = {id:curId};
this.curId+=1;
for (var i=0; i < this.fields.length; i+=1) {
var l = Math.floor(Math.random()*20);
var v = "";
for (var j=0; j<l; j+=1) {
v +=randomfeed[Math.floor(Math.random()*randomfeed.length)];
}
o[this.fields[i]] = v;
}
this.addData(o);
},
addData: function(o) {
this.put(o);
},
destroy: function(){
clearInterval(this.interval);
this.inherited(arguments);
}
});
});
4 changes: 3 additions & 1 deletion master/buildbot/www/static/js/lib/haml.js
Expand Up @@ -655,7 +655,9 @@ define(["dojo/_base/xhr"], function(xhr){
return f;
}catch(e){
if ( typeof(console) !== 'undefined' ) { console.log(str); console.error(e); }
throw e;
return function() {
return "<div><h1> Error in parsing haml!</h1><p><pre>"+Haml.html_escape(str)+"</pre><p><pre>"+Haml.html_escape(e.toString())+"</pre></div>";
}
}
}
/* dojo/AMD magic: require( ["lib/haml!./template/mytemplate.haml"], function(template){ ...
Expand Down
8 changes: 4 additions & 4 deletions master/buildbot/www/static/js/lib/router.js
Expand Up @@ -13,8 +13,8 @@
//
// Copyright Buildbot Team Members

define(["dojo/_base/declare", "dojo/_base/connect","dojo/_base/array","dojo/dom", "put-selector/put","dojo/hash", "dojo/io-query"],
function(declare, connect, array, dom, put, hash, ioquery) {
define(["dojo/_base/declare", "dojo/_base/connect","dojo/_base/array","dojo/dom", "put-selector/put","dojo/hash", "dojo/io-query", "dojo/dom-class"],
function(declare, connect, array, dom, put, hash, ioquery, domclass) {
"use strict";
/* allow chrome to display correctly generic errbacks from dojo */
console.error = function(err) {
Expand Down Expand Up @@ -131,11 +131,11 @@ define(["dojo/_base/declare", "dojo/_base/connect","dojo/_base/array","dojo/dom"
});
});
if (nav) {
nav.classList.add("active");
domclass.add(nav, "active");
}
} else { /* match */
if (nav) {
nav.classList.remove("active");
domclass.remove(nav, "active");
}
}
}));
Expand Down
63 changes: 61 additions & 2 deletions master/buildbot/www/static/js/lib/ui/build.js
Expand Up @@ -13,11 +13,70 @@
//
// Copyright Buildbot Team Members

define(["dojo/_base/declare", "lib/ui/base"], function(declare, Base) {
define(["dojo/_base/declare", "lib/ui/base",
"lib/haml!./templates/build.haml"
], function(declare, Base, template) {
"use strict";
return declare([Base], {
templateFunc : template,
constructor: function(args){
declare.safeMixin(this,args);
}
},
loadMoreContext: function(){
var deferred = new dojo.Deferred();
this.builderName = this.path_components[1].toString();
this.number = this.path_components[2].toString();
/* simulate loading of all needed stuff from json API */
setTimeout(dojo.hitch(this, function(){
this.sourceStamps = [ { changes: { changeid:"changeid1",
revision:"revision1",
committer: "me@anonymous.com",
files: ["path/to/file1",
"path/to/file2"],
comments: "this code should pas CI" }}];
this.reason = "change committed";
this.blame = ["me@anonymous.com"];
this.properties = [ { name:"prop1", value:"value1", source:"fake"} ];
this.times = ['two hours ago', 'last hour'];
this.when_time = "soon";
this.when = "~5min";
this.text = "build succeeded";
this.results = "SUCCESS"
this.slave = "slave1"
this.slave_url = "#/slaves/"+this.slave
this.steps = [ {name:"build step",
text:"make done",
results:"SUCCESS",
isStarted:true,
isFinished:true,
statistics:[],
times:[0,1],
expectations: [],
eta:null,
urls:{url1:"./url1.html"},
step_number: 1,
hidden:false,
logs:{stdio:"./stdio"}},
{name:"test step",
text:"test done",
results:"SUCCESS",
isStarted:true,
isFinished:true,
statistics:[],
times:[0,1],
expectations: [],
eta:null,
urls:{url1:"url2.html"},
step_number: 2,
hidden:false,
logs:{stdio:"stdio"}}];
this.currentStep="test step";
this.results_class = "btn-success"
deferred.callback({success: true}); }), 100);
return deferred;
},
isFinished: function() {
return this.number<5;
}
});
});
61 changes: 53 additions & 8 deletions master/buildbot/www/static/js/lib/ui/changes.js
Expand Up @@ -13,11 +13,56 @@
//
// Copyright Buildbot Team Members

define(["dojo/_base/declare", "lib/ui/base"], function(declare, Base) {
"use strict";
return declare([Base], {
constructor: function(args){
declare.safeMixin(this,args);
}
});
});
define(["dojo/_base/declare", "lib/ui/base", "dgrid/OnDemandGrid",
"dgrid/Selection", "dgrid/Keyboard","dgrid/extensions/ColumnHider",
"dojo/store/Observable", "lib/fakeChangeStore",
"dojo/text!./templates/changes.html"],
function(declare, Base, Grid, Selection, Keyboard, Hider, observable, Store, template) {
"use strict";
return declare([Base], {
templateString:template,
constructor: function(args){
declare.safeMixin(this,args);
},
postCreate: function(){
this.store = observable(new Store());
var maingrid = new (declare([Grid, Selection, Keyboard, Hider]))({
loadingMessage: "loading...",
store: this.store,
minRowsPerPage: 15,
maxRowsPerPage: 15,
cellNavigation:false,
tabableHeader: false,
columns: {
id: {label:"ID", width:"10px"},
changeid: "Change ID",
revision:
{label: "Revision",
sortable: false},
committer:
{label: "committer",
sortable: false},
comments:
{label: "Comments",
sortable: false}
}
}, this.maingrid_node);
maingrid.on(".dgrid-row:dblclick", dojo.hitch(this, this.rowDblClick));
maingrid.on("dgrid-select", dojo.hitch(this, this.select));
maingrid.refresh();
this.maingrid = maingrid;
},
select: function(event) {
var _this = this;
if (this.withSelect) {
this.withSelect(arrayUtil.map(event.rows, function(row){ return _this.store.get(row.id); }));
}
},
rowDblClick : function(evt) {
},
destroy: function(){
this.maingrid.destroy();
this.store.destroy();
}
});
});
5 changes: 4 additions & 1 deletion master/buildbot/www/static/js/lib/ui/home.js
Expand Up @@ -13,9 +13,12 @@
//
// Copyright Buildbot Team Members

define(["dojo/_base/declare", "lib/ui/base"], function(declare, Base) {
define(["dojo/_base/declare", "lib/ui/base",
"dojo/text!./templates/home.html"
], function(declare, Base, template) {
"use strict";
return declare([Base], {
templateString : template,
constructor: function(args){
declare.safeMixin(this,args);
}
Expand Down
43 changes: 43 additions & 0 deletions master/buildbot/www/static/js/lib/ui/templates/build.haml
@@ -0,0 +1,43 @@
.container-fluid
%ul.breadcrumb
%li
%a{href:"../"}<> #{ builderName }
%span.divider #{"/"}
%li.active Build ##{number}
.row-fluid
.span5
.well
:if !isFinished()
%h3 Build In Progress:
:if when_time
%p ETA: #{ when_time } [ #{ when } ]
%li.form-inline>= currentStep
&nbsp;
.btn.btn-inverse.btn-mini{data-dojo-attach-point:"stop_build_node"} Stop Build
:if isFinished()
%h3.form-inline Results:
&nbsp
.btn.disabled{class:results_class} #{text}
.well
%h3.form-inline BuildSlave:
:if this.slave_url
%a{href:slave_url}= slave
:if !this.slave_url
%span= slave
.well
%h3.form-inline Reason:
%p= reason
.well
%h3 Steps and Logfiles:
%ol
:each step in steps
%li #{step.name}
%ol
:each name, url in step.logs
%li
%a{href:url} #{name}
:each name, url in step.urls
%li
%a{href:url} #{name}
.span7.well
%h3 build properties
21 changes: 21 additions & 0 deletions master/buildbot/www/static/js/lib/ui/templates/changes.html
@@ -0,0 +1,21 @@
<div class="container-fluid">
<style type="text/css">
.mainchangegrid .field-id {
width: 30px;
}
</style>
<div class="row-fluid">
<div class="span12">
<h2>Last changes coming into the system</h2>
</div>
</div>
<div class="row-fluid">
<div class="span5">
<div class="mainchangegrid" data-dojo-attach-point="maingrid_node"></div>
</div><!--/span-->
<div class="span7">
<h4>Associated Files</h4>
<div data-dojo-attach-point="filesgrid_node"></div>
</div><!--/span-->
</div>
</div>
37 changes: 37 additions & 0 deletions master/buildbot/www/static/js/lib/ui/templates/home.html
@@ -0,0 +1,37 @@
<div class="container-fluid">
<div class="row-fluid">
<div class="span3">
<div class="well sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header">Most recently browsed builds</li>
<li><a href="#/builders/builder1/builds/1">builder1/1</a></li>
<li><a href="#/builders/builder2/builds/10">builder2/10</a></li>
<li><a href="#/builders/tester1/builds/1">tester1/1</a></li>
<li class="nav-header">Most recently browsed builders</li>
<li><a href="#/builders/builder1">builder1</a></li>
<li><a href="#/builders/builder2">builder2</a></li>
<li><a href="#/builders/tester1">tester1</a></li>
</ul>
</div><!--/.well -->
</div><!--/span-->
<div class="span9">
<div class="well">
<h2>Welcome to buildbot</h2>
Probably we should display information about the current config
</div>
<div class="row-fluid">
<div class="span4">
<ul>
<li>Buildbot version</li>
<li>Twisted version</li>
</div>
<div class="span4">
<ul>
<li>Project name</li>
<li>Project version</li>
<li>Project URL</li>
</ul>
</div>
</div>
</div>
</div>
40 changes: 40 additions & 0 deletions master/buildbot/www/ui.py
Expand Up @@ -37,3 +37,43 @@ def render(self, request):
static_url = self.static_url,
ws_url = self.baseurl.replace("http:", "ws:"))
return html % contents

if __name__ == '__main__':
from twisted.application import strports, service
from twisted.web import server, static
from twisted.internet import reactor
class myStaticFile(static.File):
"""Fix issue in twisted static implementation
where a 304 Not Modified always returns text/html
which makes chrome complain a lot in its logs"""
def render_GET(self, request):
r = static.File.render_GET(self, request)
if r=="":
request.setHeader('content-type', self.type)
return r

class WWWService(service.MultiService):
def __init__(self):
service.MultiService.__init__(self)
class fakeConfig():
www = dict(url="http://localhost:8010/", port=8010)
class fakeMaster():
config = fakeConfig()
self.master = fakeMaster()

This comment has been minimized.

Copy link
@djmitche

djmitche Jul 30, 2012

Member

should probably use buildbot.test.fake.fakemaster.make_master here?

This comment has been minimized.

Copy link
@tardyp

tardyp Jul 30, 2012

Author Member

Well I should not have merge this code. It was temporary, for me to test the UI in the train while I had no internet access :-)

I dont think we really need a entry point in this file.

This comment has been minimized.

Copy link
@djmitche

djmitche Jul 30, 2012

Member

Fair enough :)

self.setup_site()
self.port_service = strports.service("8010", self.site)
self.port_service.setServiceParent(self)
self.startService()
def setup_site(self):
root = static.Data('placeholder', 'text/plain')
# redirect the root to UI
root.putChild('', resource.RedirectResource(self.master, 'ui/'))
# /ui
root.putChild('ui', UIResource(self.master))
# /static
staticdir = util.sibpath(__file__, 'static')

root.putChild('static', myStaticFile(staticdir))
self.site = server.Site(root)
WWWService()
reactor.run()

0 comments on commit 1fdfd0f

Please sign in to comment.