summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster/toastergui/templates
diff options
context:
space:
mode:
authorAlexandru DAMIAN <alexandru.damian@intel.com>2014-09-09 11:47:13 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-10-30 13:39:49 +0000
commit960580cb70ab1c775b49f8a40d41632c080b3cbb (patch)
tree173570e0a9a80b14926c9dbbac995a39c49fbdcb /bitbake/lib/toaster/toastergui/templates
parent1a463ab98ec1220b22a721a1f88ff5af61c33dc3 (diff)
downloadpoky-960580cb70ab1c775b49f8a40d41632c080b3cbb.tar.gz
bitbake: toaster: fix Project page in order to trigger builds
This patch rewrites the Project page and the additional infrastructure in order to fix a bug that makes triggering builds through UI impossible, and to introduce data feeds for suggestions for the user. Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/toaster/toastergui/templates')
-rw-r--r--bitbake/lib/toaster/toastergui/templates/base.html12
-rw-r--r--bitbake/lib/toaster/toastergui/templates/baseprojectpage.html8
-rw-r--r--bitbake/lib/toaster/toastergui/templates/build.html7
-rw-r--r--bitbake/lib/toaster/toastergui/templates/layers.html8
-rw-r--r--bitbake/lib/toaster/toastergui/templates/newproject.html7
-rw-r--r--bitbake/lib/toaster/toastergui/templates/project.html652
6 files changed, 331 insertions, 363 deletions
diff --git a/bitbake/lib/toaster/toastergui/templates/base.html b/bitbake/lib/toaster/toastergui/templates/base.html
index 9ef249aab3..d414bfbbde 100644
--- a/bitbake/lib/toaster/toastergui/templates/base.html
+++ b/bitbake/lib/toaster/toastergui/templates/base.html
@@ -61,18 +61,6 @@ function reload_params(params) {
61 {%if MANAGED %} 61 {%if MANAGED %}
62 <div class="btn-group pull-right"> 62 <div class="btn-group pull-right">
63 <a class="btn" href="{% url 'newproject' %}">New project</a> 63 <a class="btn" href="{% url 'newproject' %}">New project</a>
64 <button class="btn dropdown-toggle" data-toggle="dropdown">
65 <i class="icon-caret-down"></i>
66 </button>
67 <ul class="dropdown-menu">
68{% for prj in projects %}
69 <li><a href="{% url 'project' prj.id %}">{{prj.name}}</a></li>
70{% endfor %}
71 <li><hr/></li>
72 <li><a href="#">Clone project</a></li>
73 <li><a href="#">Export project</a></li>
74 <li><a href="#">Import project</a></li>
75 </ul>
76 </div> 64 </div>
77 {%endif%} 65 {%endif%}
78 <a class="pull-right manual" target="_blank" href="http://www.yoctoproject.org/documentation/toaster-manual"> 66 <a class="pull-right manual" target="_blank" href="http://www.yoctoproject.org/documentation/toaster-manual">
diff --git a/bitbake/lib/toaster/toastergui/templates/baseprojectpage.html b/bitbake/lib/toaster/toastergui/templates/baseprojectpage.html
index 54edaaf27c..95a9f470ba 100644
--- a/bitbake/lib/toaster/toastergui/templates/baseprojectpage.html
+++ b/bitbake/lib/toaster/toastergui/templates/baseprojectpage.html
@@ -12,7 +12,7 @@
12 {% block parentbreadcrumb %} 12 {% block parentbreadcrumb %}
13 {% if project %} 13 {% if project %}
14 <li> 14 <li>
15 <a href="{%url 'project' project.id %}">{{project.name}} 15 <a href="{%url 'project' project.id %}"><span id="project_name">{{project.name}}</span>
16 </a> 16 </a>
17 </li> 17 </li>
18 {% endif %} 18 {% endif %}
@@ -28,11 +28,11 @@
28 </script> 28 </script>
29 </div> 29 </div>
30 30
31 <div class="row-fluid"> 31 <div>
32 32
33 <!-- Begin right container --> 33 <!-- Begin main page container -->
34 {% block projectinfomain %}{% endblock %} 34 {% block projectinfomain %}{% endblock %}
35 <!-- End right container --> 35 <!-- End main container -->
36 36
37 37
38 </div> 38 </div>
diff --git a/bitbake/lib/toaster/toastergui/templates/build.html b/bitbake/lib/toaster/toastergui/templates/build.html
index faabd22f8b..bef1f15399 100644
--- a/bitbake/lib/toaster/toastergui/templates/build.html
+++ b/bitbake/lib/toaster/toastergui/templates/build.html
@@ -127,6 +127,13 @@
127 <a href="{%url "builddashboard" build.id%}#images">{{fstypes|get_dict_value:build.id}}</a> 127 <a href="{%url "builddashboard" build.id%}#images">{{fstypes|get_dict_value:build.id}}</a>
128 {% endif %} 128 {% endif %}
129 </td> 129 </td>
130 {% if MANAGED %}
131 <td class="project">
132 {% if build.project %}
133 <a href="{% url 'project' build.project.id %}">{{build.project.name}}</a>
134 {% endif %}
135 </td>
136 {% endif %}
130 </tr> 137 </tr>
131 138
132 {% endfor %} 139 {% endfor %}
diff --git a/bitbake/lib/toaster/toastergui/templates/layers.html b/bitbake/lib/toaster/toastergui/templates/layers.html
index 281b72aec5..b32a7ed2e2 100644
--- a/bitbake/lib/toaster/toastergui/templates/layers.html
+++ b/bitbake/lib/toaster/toastergui/templates/layers.html
@@ -85,14 +85,6 @@
85 </div> 85 </div>
86 </div> 86 </div>
87 87
88 <script src="assets/js/jquery-1.9.1.min.js" type='text/javascript'></script>
89 <script src="assets/js/jquery.tablesorter.min.js" type='text/javascript'></script>
90 <script src="assets/js/jquery-ui-1.10.3.custom.min.js"></script>
91 <script src="assets/js/bootstrap.min.js" type='text/javascript'></script>
92 <script src="assets/js/prettify.js" type='text/javascript'></script>
93 <script src="assets/js/jit.js" type='text/javascript'></script>
94 <script src="assets/js/main.js" type='text/javascript'></script>
95
96 <script> 88 <script>
97 $(document).ready(function() { 89 $(document).ready(function() {
98 90
diff --git a/bitbake/lib/toaster/toastergui/templates/newproject.html b/bitbake/lib/toaster/toastergui/templates/newproject.html
index 12c4e9f07f..43c4e28bee 100644
--- a/bitbake/lib/toaster/toastergui/templates/newproject.html
+++ b/bitbake/lib/toaster/toastergui/templates/newproject.html
@@ -17,13 +17,6 @@
17 <label>Project name <span class="muted">(required)</span></label> 17 <label>Project name <span class="muted">(required)</span></label>
18 <input type="text" class="input-xlarge" required name="projectname" value="{{projectname}}"> 18 <input type="text" class="input-xlarge" required name="projectname" value="{{projectname}}">
19 <label class="project-form"> 19 <label class="project-form">
20 Project owner
21 <i class="icon-question-sign get-help" title="The go-to person for this project"></i>
22 </label>
23 <input type="text" name="username" value="{{username}}">
24 <label class="project-form">Owner's email</label>
25 <input type="email" class="input-large" name="email" value="{{email}}">
26 <label class="project-form">
27 Yocto Project version 20 Yocto Project version
28 <i class="icon-question-sign get-help" title="This sets the branch for the Yocto Project core layers (meta, meta-yocto and meta-yocto-bsp), and for the layers you use from the OpenEmbedded Metadata Index"></i> 21 <i class="icon-question-sign get-help" title="This sets the branch for the Yocto Project core layers (meta, meta-yocto and meta-yocto-bsp), and for the layers you use from the OpenEmbedded Metadata Index"></i>
29 </label> 22 </label>
diff --git a/bitbake/lib/toaster/toastergui/templates/project.html b/bitbake/lib/toaster/toastergui/templates/project.html
index c3a470c54a..9399b312ca 100644
--- a/bitbake/lib/toaster/toastergui/templates/project.html
+++ b/bitbake/lib/toaster/toastergui/templates/project.html
@@ -1,366 +1,354 @@
1{% extends "base.html" %} 1{% extends "baseprojectpage.html" %}
2<!--
3vim: expandtab tabstop=2
4-->
2{% load projecttags %} 5{% load projecttags %}
3{% load humanize %} 6{% load humanize %}
4{% block pagecontent %} 7{% load static %}
5
6<script>
7
8var buildrequests = [];
9
10function targetInPage(targetname) {
11 return targetname in $("ul#target-list > li > a").map(function (i, x) {return x.text});
12}
13
14function setEventHandlers() {
15 $("i#del-target-icon").unbind().click(function (evt) {
16 console.log("del target", evt.target.attributes["x-data"].value);
17 postEditAjaxRequest({"targetDel": evt.target.attributes["x-data"].value});
18 });
19 $("button#add-target-button").unbind().click( function (evt) {
20 if ( $("input#target")[0].value.length == 0) {
21 alert("cannot add empty target");
22 return;
23 }
24 postEditAjaxRequest({"targetAdd" : $("input#target")[0].value});
25 });
26}
27
28function onEditPageUpdate(data) {
29 // update targets
30 var i; var orightml = "";
31
32 $("span#target-count").html(data.targets.length);
33 for (i = 0; i < data.targets.length; i++) {
34 if (! targetInPage(data.targets[i].target)) {
35 orightml += '<li><a href="#">'+data.targets[i].target;
36 if (data.targets[i].task != "" && data.targets[i].task !== null) {
37 orightml += " ("+data.targets[i].task+")";
38 }
39 orightml += '</a><i title="" data-original-title="" class="icon-trash" id="del-target-icon" x-data="'+data.targets[i].pk+'"></i></li>';
40 }
41 }
42
43 $("ul#target-list").html(orightml);
44
45 // update recent builds
46
47 setEventHandlers();
48}
49
50function onEditAjaxSuccess(data, textstatus) {
51 console.log("XHR returned:", data, "(" + textstatus + ")");
52 if (data.error != "ok") {
53 alert("error on request:\n" + data.error);
54 return;
55 }
56 onEditPageUpdate(data);
57}
58
59function onEditAjaxError(jqXHR, textstatus, error) {
60 alert("XHR errored:\n" + error + "\n(" + textstatus + ")");
61}
62
63function postEditAjaxRequest(reqdata) {
64 var ajax = $.ajax({
65 type:"POST",
66 data: $.param(reqdata),
67 url:"{% url 'xhr_projectedit' project.id%}",
68 headers: { 'X-CSRFToken': $.cookie("csrftoken")},
69 success: onEditAjaxSuccess,
70 error: onEditAjaxError,
71 })
72}
73
74
75
76
77$(document).ready(function () {
78 setEventHandlers();
79
80 /* Provide XHR calls for the "build" buttons.*/
81 $("button#build-all-button").click( function (evt) {
82 var ajax = $.ajax({
83 type:"POST",
84 url:"{% url 'xhr_projectbuild' project.id %}",
85 headers: { 'X-CSRFToken': $.cookie("csrftoken")},
86 success: function (data, textstatus) {
87 if (data.error != "ok") {
88 alert("XHR fail: " + data.error );
89 }
90 },
91 error: function (jqXHR, textstatus, error) { alert("XHR errored:" + error + "(" + textstatus + ")"); },
92 })
93 });
94});
95
96
97</script>
98 8
99 9
100 <div class="page-header"> 10{% block projectinfomain %}
101 <h1> 11<script src="{% static "js/angular.min.js" %}"></script>
102 {{project.name}} 12<script src="{% static "js/angular-cookies.min.js" %}"></script>
103 {% if project.build_set.all.count == 0 %} 13<script src="{% static "js/ui-bootstrap-tpls-0.11.0.js" %}"></script>
104 <small>No builds yet</small>
105 {% else %}
106 <small><a href="#">{{project.build_set.all.count}} builds</a></small>
107 {% endif %}
108 </h1>
109 </div>
110 14
111 15
112 <div class="well"> 16<div id="main" role="main" ng-app="project" ng-controller="prjCtrl" class="top-padded">
113 <form class="build-form">
114 <div class="input-append input-prepend controls">
115 <input type="text" class="huge span7" placeholder="Type the target(s) you want to build" autocomplete="off" data-minLength="1" data-autocomplete="off"
116 data-provide="typeahead" data-source='["core-image-base [meta | daisy]",
117 "core-image-clutter [meta | daisy]",
118 "core-image-directfb [meta | daisy]",
119 "core-image-myimage [meta-imported-layer | 3e1dbabbf3&hellip;]",
120 "core-image-anotherimage [meta-imported-layer | master]",
121 "core-image-full-cmdline [meta | daisy]",
122 "core-image-lsb [meta | daisy]",
123 "core-image-lsb-dev [meta | daisy]",
124 "core-image-lsb-sdk [meta| daisy]",
125 "core-image-minimal [meta| daisy]"
126 ]'>
127 <a href="#" id="build-button" class="btn btn-large btn-primary" disabled>
128 Build
129 <i class="icon-question-sign get-help heading-help" style="margin-left: 5px;" title="Type the name of one or more targets you want to build, separated by a space. You can also specify a task by appending a semicolon and a task name to a target name, like so: <code>core-image-minimal:do_build</code>"></i>
130 </a>
131 </div>
132 <p>
133 <a href="all-targets.html" style="padding-right: 5px;">
134 View all targets
135 </a>
136 |
137 <a href="{% url 'projectbuilds' project.id%}" style="padding-left:5px;">
138 View all project builds ({{project.build_set.count}})
139 </a>
140 </form>
141 </div>
142 17
143 18
19 <!-- project name -->
20 <div class="page-header">
21 <h1>{[project.name]}</h1>
22 </div>
144 23
24 <!-- alerts section 1-->
25 <div ng-repeat="a in zone1alerts">
26 <div class="alert alert-dismissible lead" role="alert" ng-class="a.type"><button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">&times;</span></button>
27 <span ng-bind-html="a.text"></span>
28 </div>
29 </div>
145 30
31 <!-- custom templates for ng -->
146 32
147 {% if builds|length > 0 or buildrequests|length > 0 %} 33 <script type="text/ng-template" id="suggestion_details">
148 <h2 class="air">Recent Builds</h2> 34 <a> {[match.model.name]} {[match.model.detail]} </a>
35 </script>
149 36
150 <div id="scheduled-builds"> 37 <!-- modal dialogs -->
151 {% for br in buildrequests %} 38 <script type="text/ng-template" id="dependencies_modal">
152<div class="alert {% if br.0.state == br.0.REQ_FAILED%}alert-error{%else%}alert-info{%endif%}" id="build-request"> 39 <div class="modal-header">
153 <div class="row-fluid"> 40 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
154 <div class="lead span4"> 41 <h3><span ng-bind="layerAddName"></span> dependencies</h3>
155 <span> 42 </div>
156 {{br.0.brtarget_set.all.0.target}} {%if br.brtarget_set.all.count > 1%}(+ {{br.brtarget_set.all.count|add:"-1"}}){%endif%} {{br.1.machine.value}} (Created {{br.0.created}}) 43 <div class="modal-body">
157 </span> 44 <p><strong>{[layerAddName]}</strong> depends on some layers that are not added to your project. Select the ones you want to add:</p>
45 <ul class="unstyled">
46 <li ng-repeat="ld in items">
47 <label class="checkbox">
48 <input type="checkbox" ng-model="selectedItems[ld.id]"> {[ld.name]}
49 </label>
50 </li>
51 </ul>
52 </div>
53 <div class="modal-footer">
54 <button class="btn btn-primary" ng-click="ok()">Add layers</button>
55 <button class="btn" ng-click="cancel()">Cancel</button>
56 </div>
57 </form>
58 </script>
59
60
61 <script type="text/ng-template" id="change_version_modal">
62 <div class="modal-header">
63 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
64 <h3>Changing release to {[releaseName]}</h3>
65 </div>
66 <div class="modal-body">
67 <p>The following project layers do not exist for {[releaseName]}:</p>
68 <ul>
69 <li ng-repeat="i in items"><span class="layer-info" data-toggle="tooltip" tooltip="{[i.detail]}">{[i.name]}</span></li>
70 </ul>
71 <p>If you change the release to {[releaseName]}, the above layers will be deleted from your project layers.</p>
72 </div>
73 <div class="modal-footer">
74 <button class="btn btn-primary" ng-click="ok()">Change release and delete layers</button>
75 <button class="btn" ng-click="cancel()">Cancel</button>
76 </div>
77 </script>
78
79 <!-- build form -->
80 <div class="well">
81 <form class="build-form" ng-submit="targetNamedBuild()">
82 <div class="input-append input-prepend controls">
83 <input type="text" class="huge span7 " placeholder="Type the target(s) you want to build" autocomplete="off" ng-model="targetName" typeahead="e.name for e in getSuggestions('targets', $viewValue)|filter:$viewValue" typeahead-template-url="suggestion_details" ng-disabled="!layers.length"/>
84 <button type="submit" id="build-button" class="btn btn-large btn-primary" ng-disabled="!targetName.length">
85 Build
86 <i class="icon-question-sign get-help heading-help" style="margin-left: 5px;" data-toggle="tooltip" title="Type the name of one or more targets you want to build, separated by a space. You can also specify a task by appending a semicolon and a task name to a target name, like so: <code>core-image-minimal:do_build</code>"></i>
87 </button>
88 </div>
89 <p>
90 <a href="{% url 'targets' %}" style="padding-right: 5px;">
91 View all targets
92 </a>
93 {% if completedbuilds.count %}
94 | <a href="{% url 'projectbuilds' project.id %}">View all project builds ({{completedbuilds.count}})</a>
95 {% endif %}
96 </p>
97 </form>
98 </div>
99
100 <h2 class="air" ng-if="builds.length">Latest builds</h2>
101
102 <div class="alert" ng-repeat="b in builds" ng-class="{'queued':'alert-info', 'deleted':'alert-info', 'in progress': 'alert-info', 'In Progress':'alert-info', 'Succeeded':'alert-success', 'failed':'alert-error', 'Failed':'alert-error'}[b.status]">
103 <div class="row-fluid">
104 <switch ng-switch="b.status">
105 <case ng-switch-when="failed">
106 <div class="lead span3"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div>
107 <div class="row-fluid">
108 <div class="air well" ng-repeat="e in b.errors">
109 {[e.type]}: <pre>{[e.msg]}</pre>
110 </div>
111 </div>
112 </case>
113 <case ng-switch-when="queued">
114 <div class="lead span5"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div>
115 <div class="span4 lead" >Build queued
116 <i title="This build will start as soon as a build server is available" class="icon-question-sign get-help get-help-blue heading-help" data-toggle="tooltip"></i>
117 </div>
118 <button class="btn pull-right btn-info" ng-click="buildCancel(b.id)">Cancel</button>
119 </case>
120 <case ng-switch-when="created">
121 <div class="lead span3"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div>
122 <div class="span6" >
123 <span class="lead">Creating build</span>
158 </div> 124 </div>
159 <div class="span2"> 125 <button class="btn pull-right btn-info" ng-click="buildCancel(b.id)">Cancel</button>
160 {{br.0.get_state_display}} 126 </case>
127 <case ng-switch-when="deleted">
128 <div class="lead span3"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div>
129 <div class="span6" id="{[b.id]}-deleted" >
130 <span class="lead">Build deleted</span>
161 </div> 131 </div>
162 <div class="span8"> 132 <button class="btn pull-right btn-info" ng-click="builds.splice(builds.indexOf(b), 1)">Close</button>
163{% if br.state == br.REQ_FAILED%} 133 </case>
164 {% for bre in br.0.brerror_set.all %} {{bre.errmsg}} ({{bre.errtype}}) <br/><hr/><code>{{bre.traceback}}</code>{%endfor%} 134 <case ng-switch-when="in progress">
165{%endif%} 135 <div class="lead span3"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div>
136 <div class="span4" >
166 </div> 137 </div>
138 <div class="lead pull-right">Build starting shortly</div>
139 </case>
140 <case ng-switch-when="In Progress">
141 <div class="span4" >
142 <div class="progress" style="margin-top:5px;" data-toggle="tooltip" tooltip="{[b.completeper]}% of tasks complete">
143 <div style="width: {[b.completeper]}%;" class="bar"></div>
144 </div>
145 </div>
146 <div class="lead pull-right">ETA: at {[b.eta]}</div>
147 </case>
148 <case ng-switch-default="">
149 <div class="lead span3"><a href="{[b.build_page_url]}"><span ng-repeat="t in b.targets">{[t.target]} </span> </div></a>
150 <div class="span2 lead">
151 {[b.completed_on|date:'dd/MM/yy HH:mm']}
152 </div>
153 <div class="span2"><span>{[b.errors.len]}</span></div>
154 <div class="span2"><span>{[b.warnings.len]}</span></div>
155 <div> <span class="lead">Build time: {[b.build_time|date:"HH:mm"]}</span>
156 <button class="btn pull-right" ng-class="{'Succeeded': 'btn-success', 'Failed': 'btn-danger'}[b.status]"
157 ng-click="targetExistingBuild(b.targets)">Run again</button>
167 158
168 </div> 159 </div>
169</div> 160 </case>
161 </switch>
162 <div class="lead pull-right">
163 </div>
164 </div>
165 </div>
170 166
171 {% endfor %} 167 <h2 class="air">Project configuration</h2>
172 168
169 <!-- alerts section 2 -->
170 <div ng-repeat="a in zone2alerts">
171 <div class="alert alert-dismissible lead" role="alert" ng-class="a.type"><button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">&times;</span></button>
172 <span ng-bind-html="a.text"></span>
173 </div>
174 </div>
175
176 <div class="row-fluid">
177
178 <!-- project layers -->
179 <div id="layer-container" class="well well-transparent span4">
180 <h3>
181 Project layers <span class="muted counter">({[layers.length]})</span>
182 <i class="icon-question-sign get-help heading-help" title="OpenEmbedded organises metadata into modules called 'layers'. Layers allow you to isolate different types of customizations from each other. <a href='http://www.yoctoproject.org/docs/current/dev-manual/dev-manual.html#understanding-and-creating-layers' target='_blank'>More on layers</a>"></i>
183 </h3>
184 <div class="alert" ng-if="!layers.length">
185 <b>You need to add some layers </b>
186 <p>
187 You can:
188 <ul>
189 <li> <a href="{% url 'layers'%}">View all layers available in Toaster</a>
190 <li> <a href="{% url 'importlayer' %}">Import a layer</a>
191 <li> <a href="https://www.yoctoproject.org/docs/1.6.1/dev-manual/dev-manual.html#understanding-and-creating-layers" target="_blank">Read about layers in the manual</a>
192 </ul>
193 Or type a layer name below.
194 </p>
195 </div>
196 <form class="input-append" ng-submit="layerAdd()">
197 <input type="text" class="input-xlarge" id="layer" autocomplete="off" placeholder="Type a layer name" data-minLength="1" ng-model="layerAddName" typeahead="e.name for e in getSuggestions('layers', $viewValue)|filter:$viewValue" typeahead-template-url="suggestion_details" typeahead-on-select="onLayerSelect($item, $model, $label)" typeahead-editable="false" ng-class="{ 'has-error': layerAddName.$invalid }" />
198 <input type="submit" id="add-layer" class="btn" value="Add" ng-disabled="!layerAddName.length"/>
199 {% csrf_token %}
200 </form>
201 <p><a href="{% url 'layers' %}">View all layers</a> | <a href="{% url 'importlayer' %}">Import layer</a></p>
202 <ul class="unstyled configuration-list">
203 <li ng-repeat="l in layers">
204 <a href="{[l.layerdetailurl]}" target="_#" class="layer-info" data-toggle="tooltip" tooltip="{[l.branch.layersource]} | {[l.branch.name]}">{[l.name]} </a>
205 <i class="icon-trash" ng-click="layerDel(l.id)" tooltip="Delete"></i>
206 </li>
207 </ul>
173 </div> 208 </div>
174 209
175 210
211 <!-- project targets -->
212 <div id="target-container" class="well well-transparent span4">
213 <h3>
214 Targets
215 <i class="icon-question-sign get-help heading-help" title="What you build, often a recipe producing a root file system file (an image). Something like <code>core-image-minimal</code> or <code>core-image-sato</code>"></i>
216 </h3>
217 <form ng-submit="targetNamedBuild()" class="input-append">
218 <input type="text" class="input-xlarge" placeholder="Type the target(s) you want to build" autocomplete="off" data-minLength="1" ng-model="targetName" typeahead="e.name for e in getSuggestions('targets', $viewValue)|filter:$viewValue" typeahead-template-url="suggestion_details" ng-disabled="!layers.length">
219 <button type="submit" id="build-button" class="btn btn-primary" ng-disabled="!targetName.length">
220 Build </button>
221 {% csrf_token %}
222 </form>
223 <p><a href="{% url 'targets' %}">View all targets</a></p>
224 <div ng-if="frequenttargets.length">
225 <h4>
226 Most built targets
227 </h4>
228 <ul class="unstyled configuration-list">
229 <li ng-repeat="t in frequenttargets">
230 <label class="checkbox">
231 <input type="checkbox" ng-model="mostBuiltTargets[t]">{[t]}
232 </label>
233 </li>
234 </ul>
235 <button class="btn btn-large btn-primary" ng-disabled="selectedMostBuildTargets()">Build selected targets</button>
236 </div>
237 </div>
176 238
177<!-- Lifted from build.html --> 239 <!-- project configuration -->
178 {% for build in builds %} 240 <div id="machine-distro" class="well well-transparent span4">
179<div class="alert {%if build.outcome == build.SUCCEEDED%}alert-success{%elif build.outcome == build.FAILED%}alert-error{%else%}alert-info{%endif%}"> 241 <h3>
180 <div class="row-fluid"> 242 Project machine
181 <div class="lead span5"> 243 <i class="icon-question-sign get-help heading-help" title="The machine is the hardware for which you want to build. You can only set one machine per project"></i>
182 {%if build.outcome == build.SUCCEEDED%}<i class="icon-ok-sign success"></i>{%elif build.outcome == build.FAILED%}<i class="icon-minus-sign error"></i>{%else%}{%endif%} 244 </h3>
183 {%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %} 245 <p class="lead" id="select-machine-opposite">
184 <a href="{%url 'builddashboard' build.pk%}" class="{%if build.outcome == build.SUCCEEDED %}success{%else%}error{%endif%}"> 246 {[machine.name]}<i id="change-machine" class="icon-pencil" ng-click="toggle('#select-machine')" tooltip="Change"></i>
185 {% endif %} 247 </p>
186 <span data-toggle="tooltip" {%if build.target_set.all.count > 1%}title="Targets: {%for target in build.target_set.all%}{{target.target}} {%endfor%}"{%endif%}>{{build.target_set.all.0.target}} {%if build.target_set.all.count > 1%}(+ {{build.target_set.all.count|add:"-1"}}){%endif%} {{build.machine}} ({{build.completed_on|naturaltime}})</span> 248 <div id="select-machine" style="display: none">
187 {%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %} 249 <div class="alert alert-info">
188 </a> 250 <strong>Machine changes have a big impact on build outcome.</strong>
189 {% endif %} 251 You cannot really compare the builds for the new machine with the previous ones.
190 </div>
191 {%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %}
192 <div class="span2 lead">
193 {% if build.errors_no %}
194 <i class="icon-minus-sign red"></i> <a href="{%url 'builddashboard' build.pk%}#errors" class="error">{{build.errors_no}} error{{build.errors_no|pluralize}}</a>
195 {% endif %}
196 </div>
197 <div class="span2 lead">
198 {% if build.warnings_no %}
199 <i class="icon-warning-sign yellow"></i> <a href="{%url 'builddashboard' build.pk%}#warnings" class="warning">{{build.warnings_no}} warning{{build.warnings_no|pluralize}}</a>
200 {% endif %}
201 </div >
202 <div class="lead pull-right">
203 Build time: <a href="{% url 'buildtime' build.pk %}">{{ build.timespent|sectohms }}</a>
204 </div>
205 {%endif%}{%if build.outcome == build.IN_PROGRESS %}
206 <div class="span4">
207 <div class="progress" style="margin-top:5px;" data-toggle="tooltip" title="{{build.completeper}}% of tasks complete">
208 <div style="width: {{build.completeper}}%;" class="bar"></div>
209 </div>
210 </div>
211 <div class="lead pull-right">ETA: in {{build.eta|naturaltime}}</div>
212 {%endif%}
213 </div> 252 </div>
253 <form ng-submit="edit('#select-machine')" class="input-append">
254 <input type="text" id="machine" autocomplete="off" ng-model="machineName" typeahead="m.name for m in getSuggestions('machines', $viewValue)"/>
255 <input type="submit" id="apply-change-machine" class="btn" type="button" ng-disabled="machineName == machine.name || machineName.length == 0" value="Save"></input>
256 <input type="reset" id="cancel-machine" class="btn btn-link" ng-click="toggle('#select-machine')" value="Cancel"></input>
257 {% csrf_token %}
258 </form>
259 <p><a href="{% url 'machines' %}" class="link">View all machines</a></p>
260 </div>
261 <p class="link-action">
262 <a href="{% url 'projectconf' project.id %}" class="link">Edit configuration variables</a>
263 <i data-original-title="You can set other project configuration options here. Each option, like everything else in the build system, is a variable - value pair" class="icon-question-sign get-help heading-help" title=""></i>
264 </p>
214 </div> 265 </div>
215 {% endfor %} 266 </div>
216<!-- end of lift-->
217 {%endif%}
218 267
219 <h2 class="air">Project configuration</h2>
220 268
221 <div class="row-fluid"> 269 <h2>Project details</h2>
222 270
223 <div id="layer-container" class="well well-transparent span4"> 271 <!-- alerts section 3 -->
224 <h3> 272 <div ng-repeat="a in zone3alerts">
225 Add layers 273 <div class="alert alert-dismissible lead" role="alert" ng-class="a.type"><button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">&times;</span></button>
226 <i data-original-title="OpenEmbedded organises metadata into modules called 'layers'. Layers allow you to isolate different types of customizations from each other. <a href='http://www.yoctoproject.org/docs/1.6.1/dev-manual/dev-manual.html#understanding-and-creating-layers' target='_blank'>More on layers</a>" class="icon-question-sign get-help heading-help" title=""></i> 274 <span ng-bind-html="a.text"></span>
227 </h3> 275 </div>
228 <form style="margin-top:20px;"> 276 </div>
229 <div class="input-append"> 277
230 <input class="input-xlarge" id="layer" autocomplete="off" placeholder="Type a layer name" data-provide="typeahead" data-source="" data-minlength="1" data-autocomplete="off" type="text"> 278
231 <button id="add-layer" class="btn" disabled="">Add</button> 279 <div id="project-details" class="well well-transparent">
232 </div> 280 <h3>Project name</h3>
233 <div id="import-alert" class="alert alert-info" style="display:none;"> 281 <p class="lead" id="change-project-name-opposite">
234 Toaster does not know about this layer. Please <a href="#">import it</a> 282 <span >{[project.name]}</span>
235 </div> 283 <i class="icon-pencil" ng-click="toggle('#change-project-name')" tooltip="Change"></i>
236 <div id="dependency-alert" class="alert alert-info" style="display:none;"> 284 </p>
237 <p><strong>meta-tizen</strong> depends on the layers below. Check the ones you want to add: </p> 285 <div id="change-project-name" style="display:none;">
238 <ul class="unstyled"> 286 <form ng-submit="edit('#change-project-name')" class="input-append">
239 {% for f in layer_dependency %} 287 <input type="text" class="input-xlarge" id="type-project-name" ng-model="projectName">
240 <li> 288 <input type="submit" class="btn" value="Save" ng-disabled="project.name == projectName"/>
241 <label class="checkbox"> 289 <input type="reset" class="btn btn-link" value="Cancel" ng-click="toggle('#change-project-name')">
242 <input checked="checked" type="checkbox"> 290 </form>
243 meta-ruby 291 </div>
244 </label>
245 </li>
246 {% endfor %}
247 </ul>
248 <button id="add-layer-dependencies" class="btn btn-info add-layer">Add layers</button>
249 </div>
250
251 <p><a href="{% url 'importlayer' %}">Import your layer</a> | <a href="{% url 'layers'%}">View all layers</a></p>
252 </form>
253
254 <h4 class="air">
255 Added layers
256 <span class="muted counter">{{project.projectlayer_set.count}}</span>
257 <i data-original-title="Your added layers will be listed in this same order in your <code>bblayers.conf</code> file" class="icon-question-sign get-help heading-help" title=""></i>
258 </h4>
259 <ul class="unstyled configuration-list">
260 {% for pl in project.projectlayer_set.all %}
261 <li>
262 <a href="#">{{pl.layercommit.layer.name}} (<span class="layer-version">{{pl.layercommit.layer.layer_index_url}}</span>)</a>
263 {% if pl.optional %}
264 <i title="" data-original-title="" class="icon-trash" id="del-layer-icon" x-data="{{pl.pk}}"></i>
265 {% endif %}
266 </li>
267 {% endfor %}
268 </ul>
269 </div>
270 292
271 <div id="target-container" class="well well-transparent span4">
272 <h3>
273 Add targets
274 <i data-original-title="A target is what you want to build, usually an image recipe that produces a root file system" class="icon-question-sign get-help heading-help" title=""></i>
275 </h3>
276 <form style="margin-top:20px;">
277 <div class="input-append">
278 <input id="target" class="input-xlarge" autocomplete="off" placeholder="Type a target name" data-provide="typeahead" data-source="" data-minlength="1" data-autocomplete="off" type="text">
279 <button id="add-target-button" class="btn" type="button">Add</button>
280 </div>
281
282 <p><a href="{% url 'targets' %}" class="link">View all targets</a></p>
283 </form>
284 <h4 class="air">
285 Added targets
286 <span id="target-count" class="muted counter">{{project.projecttarget_set.count}}</span>
287 </h4>
288 <ul class="unstyled configuration-list" id="target-list">
289 {% for target in project.projecttarget_set.all %}
290 {% if target %}
291 <li>
292 <a href="#">{{target.target}}{% if target.task%} (target.task){%endif%}</a>
293 {% if target.notprovided %}
294 <i title="" data-original-title="" id="msg1" class="icon-exclamation-sign get-help-yellow" data-title="<strong>Target may not be provided</strong>" data-content="From the layer information it currently has, Toaster thinks this target is not provided by any of your added layers. If a target is not provided by one of your added layers, the build will fail.<h5>What Toaster suggests</h5><p>The <a href='#'>meta-abc</a> and <a href='#'>meta-efg</a> layers provide core-image-notprovided. You could add one of them to your project.</p><button class='btn btn-block'>Add meta-abc</button><button class='btn btn-block'>Add meta-efg</button><button id='dismiss1' class='btn btn-block btn-info'>Stop showing this message</button>"></i>
295 {% elif target.notknown %}
296 <i title="" data-original-title="" id="msg2" class="icon-exclamation-sign get-help-yellow" data-title="<strong>Target may not be provided</strong>" data-content="From the layer information it currently has, Toaster thinks this target is not provided by any of your added layers. If a target is not provided by one of your added layers, the build will fail.<h5>What Toaster suggests</h5><p>Review your added layers to make sure one of them provides core-image-unknown. Clicking on a layer name will give you all the information Toaster has about the layer. </p> <button class='btn btn-block btn-info'>Stop showing this message</button>"></i>
297 {% endif %}
298 <i title="" data-original-title="" class="icon-trash" id="del-target-icon" x-data="{{target.pk}}"></i>
299 </li>
300 {% endif %}
301 {% endfor %}
302
303
304 </ul>
305 </div>
306 293
307 <div class="well well-transparent span4"> 294 <h3>
308 295 Release
309 <h3> 296 <i class="icon-question-sign get-help heading-help" title="The version of the build system you want to use"></i>
310 Project machine 297 </h3>
311 <i class="icon-question-sign get-help heading-help" title="The machine is the hardware for which you want to build. You can only set one machine per project"></i> 298 <p class="lead" id="change-project-version-opposite">
312 </h3> 299 <span id="project-version">{[project.release.name]}</span>
313 <p class="lead" id="selected-machine"> {{machine}} 300 <i id="change-version" class="icon-pencil" ng-click="toggle('#change-project-version')" tooltip="Change"></i>
314 <i id="change-machine" class="icon-pencil"></i> 301 </p>
315 </p> 302 <div class="div-inline" id="change-project-version" style="display:none;">
316 <form id="select-machine"> 303 <form ng-submit="test('#change-project-version')" class="input-append">
317 <div class="alert alert-info"> 304 <select id="select-version" ng-model="projectVersion">
318 <strong>Machine changes have a big impact on build outcome.</strong> 305 <option ng-repeat="r in releases" value="{[r.id]}" ng-selected="r.id == project.release.id">{[r.name]}</option>
319 You cannot really compare the builds for the new machine with the previous ones. 306 </select>
320 </div> 307 <input type="submit" class="btn" style="margin-left:5px;" value="Save" ng-disabled="project.release.id == projectVersion"/>
321 <div class="input-append"> 308 <input type="reset" class="btn btn-link" value="Cancel" ng-click="toggle('#change-project-version')" ng-disabled="project.release.id == projectVersion"/>
322 <input type="text" id="machine" autocomplete="off" value="qemux86" data-provide="typeahead" 309
323 data-minLength="1" 310 </form>
324 data-autocomplete="off" 311 </div>
325 data-source='[ 312 </div>
326 ]'>
327 <button id="apply-change-machine" class="btn" type="button">Save</button>
328 <a href="#" id="cancel-machine" class="btn btn-link">Cancel</a>
329 </div>
330 <p><a href="{% url 'machines' %}" class="link">View all machines</a></p>
331 </form>
332 <p class="link-action">
333 <a href="{% url 'projectconf' project.id %}" class="link">Edit configuration variables</a>
334 <i class="icon-question-sign get-help heading-help" title="You can set other project configuration options here. Each option, like everything else in the build system, is a variable - value pair"></i>
335 </p>
336 313
337 </div> 314<!-- end main -->
315</div>
338 316
339 317
340 </div> 318<!-- load application logic !-->
319<script src="{% static "js/projectapp.js" %}"></script>
320
321<!-- dump initial data for use in the angular app -->
322<script>
323angular.element(document).ready(function() {
324 scope = angular.element("#main").scope();
325 scope.urls = {};
326 scope.urls.xhr_build = "{% url 'xhr_projectbuild' project.id %}";
327 scope.urls.xhr_edit = "{% url 'xhr_projectedit' project.id %}";
328 scope.urls.xhr_datatypeahead = "{% url 'xhr_datatypeahead' %}";
329 scope.urls.layers = "{% url 'layers' %}";
330 scope.urls.targets = "{% url 'targets' %}";
331 scope.urls.importlayer = "{% url 'importlayer'%}"
332 scope.project = {{prj|safe}};
333 scope.builds = {{builds|safe}};
334 scope.layers = {{layers|safe}};
335 scope.targets = {{targets|safe}};
336 scope.frequenttargets = {{freqtargets|safe}};
337 scope.machine = {{machine|safe}};
338 scope.releases = {{releases|safe}};
339
340 scope.zone1alerts = [];
341 scope.zone2alerts = [];
342 scope.zone3alerts = [];
343
344 scope.mostBuiltTargets = {};
345
346 scope.executeCommands();
347 scope.validateData();
348
349 scope.$digest();
350
351 });
352</script>
341 353
342 <h2>Project details</h2>
343
344 <div class="well well-transparent">
345 <h3>Project name</h3>
346 <p class="lead">
347 {{project.name}}
348 <i title="" data-original-title="" class="icon-pencil"></i>
349 </p>
350 <h3>Project owner</h3>
351 <p class="lead">
352 {{puser.username}}
353 <i title="" data-original-title="" class="icon-pencil"></i>
354 </p>
355 <h3>Owner's email</h3>
356 <p class="lead">
357 {{puser.email}}
358 <i title="" data-original-title="" class="icon-pencil"></i>
359 </p>
360 <h3>Yocto Project version</h3>
361 <p class="lead">
362 {{project.release.name}} - {{project.release.description}}
363 <i title="" data-original-title="" class="icon-pencil"></i>
364 </p>
365 </div>
366{% endblock %} 354{% endblock %}