summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster/toastergui/templates
diff options
context:
space:
mode:
authorElliot Smith <elliot.smith@intel.com>2016-06-29 15:41:56 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-08-11 00:09:26 +0100
commit952ffb3e1f4a00793e0c9c49bc0c8fb8729424c4 (patch)
tree604083d9477c9d3d2f51c714fe3b74ac8196f26c /bitbake/lib/toaster/toastergui/templates
parentc471740f5ba023dccc992438c75f1534950d26af (diff)
downloadpoky-952ffb3e1f4a00793e0c9c49bc0c8fb8729424c4.tar.gz
bitbake: toaster: move most recent builds templating to client
The most recent builds area of the all builds and project builds table needs to update as a build progresses. It also needs additional functionality to show other states (e.g. recipe parsing, queued) which again needs to update on the client side. Rather than add to the existing mix of server-side templating with client-side DOM updating, translate all of the server-side templates to client-side ones (jsrender), and add logic which updates the most recent builds area as the state of a build changes. Add a JSON API for mostrecentbuilds, which returns the state of all "recent" builds. Fetch this via Ajax from the build dashboard (rather than fetching the ad hoc API as in the previous version). Then, as new states for builds are fetched via Ajax, determine whether the build state has changed completely, or whether the progress has just updated. If the state completely changed, re-render the template on the client side for that build. If only the progress changed, just update the progress bar. (NB this fixes the task progress bar so it works for the project builds and all builds pages.) In cases where the builds table needs to update as the result of a build finishing, reload the whole page. This work highlighted a variety of other issues, such as build requests not being able to change state as necessary. This was one part of the cause of the "cancelling build..." state being fragile and disappearing entirely when the page refreshed. The cancelling state now persists between page reloads, as the logic for determining whether a build is cancelling is now on the Build object itself. Note that jsrender is redistributed as part of Toaster, so a note was added to LICENSE to that effect. [YOCTO #9631] (Bitbake rev: c868ea036aa34b387a72ec5116a66b2cd863995b) Signed-off-by: Elliot Smith <elliot.smith@intel.com> 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.html6
-rw-r--r--bitbake/lib/toaster/toastergui/templates/buildrequestdetails.html64
-rw-r--r--bitbake/lib/toaster/toastergui/templates/mrb_section.html308
-rw-r--r--bitbake/lib/toaster/toastergui/templates/projectbuilds-toastertable.html2
4 files changed, 176 insertions, 204 deletions
diff --git a/bitbake/lib/toaster/toastergui/templates/base.html b/bitbake/lib/toaster/toastergui/templates/base.html
index 8a9f690309..58491eba81 100644
--- a/bitbake/lib/toaster/toastergui/templates/base.html
+++ b/bitbake/lib/toaster/toastergui/templates/base.html
@@ -22,6 +22,8 @@
22 </script> 22 </script>
23 <script src="{% static 'js/typeahead.jquery.js' %}"> 23 <script src="{% static 'js/typeahead.jquery.js' %}">
24 </script> 24 </script>
25 <script src="{% static 'js/jsrender.min.js' %}">
26 </script>
25 <script src="{% static 'js/prettify.js' %}"> 27 <script src="{% static 'js/prettify.js' %}">
26 </script> 28 </script>
27 <script src="{% static 'js/libtoaster.js' %}"> 29 <script src="{% static 'js/libtoaster.js' %}">
@@ -32,6 +34,8 @@
32 </script> 34 </script>
33 {% endif %} 35 {% endif %}
34 <script> 36 <script>
37 $.views.settings.delimiters("<%", "%>");
38
35 libtoaster.ctx = { 39 libtoaster.ctx = {
36 jsUrl : "{% static 'js/' %}", 40 jsUrl : "{% static 'js/' %}",
37 htmlUrl : "{% static 'html/' %}", 41 htmlUrl : "{% static 'html/' %}",
@@ -48,7 +52,9 @@
48 xhrCustomRecipeUrl : "{% url 'xhr_customrecipe' %}", 52 xhrCustomRecipeUrl : "{% url 'xhr_customrecipe' %}",
49 projectId : {{project.id}}, 53 projectId : {{project.id}},
50 xhrBuildRequestUrl: "{% url 'xhr_buildrequest' project.id %}", 54 xhrBuildRequestUrl: "{% url 'xhr_buildrequest' project.id %}",
55 mostRecentBuildsUrl: "{% url 'most_recent_builds' %}?project_id={{project.id}}",
51 {% else %} 56 {% else %}
57 mostRecentBuildsUrl: "{% url 'most_recent_builds' %}",
52 projectId : undefined, 58 projectId : undefined,
53 projectPageUrl : undefined, 59 projectPageUrl : undefined,
54 projectName : undefined, 60 projectName : undefined,
diff --git a/bitbake/lib/toaster/toastergui/templates/buildrequestdetails.html b/bitbake/lib/toaster/toastergui/templates/buildrequestdetails.html
deleted file mode 100644
index c782074448..0000000000
--- a/bitbake/lib/toaster/toastergui/templates/buildrequestdetails.html
+++ /dev/null
@@ -1,64 +0,0 @@
1{% extends "baseprojectpage.html" %}
2
3{% load static %}
4{% load projecttags %}
5{% load humanize %}
6
7
8{% block projectinfomain %}
9 <!-- begin content -->
10
11 <div class="row">
12
13 <!-- end left sidebar container -->
14 <!-- Begin right container -->
15 <div class="col-md-10">
16 <div class="page-header">
17 <h1>
18 <span data-toggle="tooltip" {%if buildrequest.brtarget_set.all.count > 1%}title="Targets: {%for target in buildrequest.brtarget_set.all%}{{target.target}} {%endfor%}"{%endif%}>{{buildrequest.brtarget_set.all.0.target}} {%if buildrequest.brtarget_set.all.count > 1%}(+ {{buildrequest.brtarget_set.all.count|add:"-1"}}){%endif%} {{buildrequest.get_machine}} </span>
19
20 </h1>
21 </div>
22 <div class="alert alert-error">
23 <p class="lead">
24 <strong>Failed</strong>
25 on {{ buildrequest.updated|date:'d/m/y H:i' }}
26 with
27
28 <i class="icon-minus-sign error" style="margin-left:6px;"></i>
29 <strong><a class="error accordion-toggle toggle-errors" href="#errors">
30 {{buildrequest.brerror_set.all.count}} error{{buildrequest.brerror_set.all.count|pluralize}}
31 </a></strong>
32 <span class="pull-right">Build time: {{buildrequest.get_duration|sectohms}}</span>
33 </p>
34 </div>
35
36 <div class="accordion" id="errors">
37 <div class="accordion-group">
38 <div class="accordion-heading">
39 <a class="accordion-toggle error toggle-errors">
40 <h2>
41 <i class="icon-minus-sign"></i>
42 {{buildrequest.brerror_set.all.count}} error{{buildrequest.brerror_set.all.count|pluralize}}
43 </h2>
44 </a>
45 </div>
46 <div class="accordion-body collapse in" id="collapse-errors">
47 <div class="accordion-inner">
48 <div class="col-md-10">
49 {% for error in buildrequest.brerror_set.all %}
50 <div class="alert alert-error">
51 ERROR: <div class="air well"><pre>{{error.errmsg}}</pre></div>
52 </div>
53 {% endfor %}
54 </div>
55 </div>
56 </div>
57
58 </div>
59 </div>
60 </div>
61 </div> <!-- end of row -->
62
63
64{%endblock%}
diff --git a/bitbake/lib/toaster/toastergui/templates/mrb_section.html b/bitbake/lib/toaster/toastergui/templates/mrb_section.html
index b164269a13..302b4b0da4 100644
--- a/bitbake/lib/toaster/toastergui/templates/mrb_section.html
+++ b/bitbake/lib/toaster/toastergui/templates/mrb_section.html
@@ -1,26 +1,9 @@
1{% load static %} 1{% load static %}
2{% load projecttags %}
3{% load project_url_tag %}
4{% load humanize %} 2{% load humanize %}
3{% load project_url_tag %}
5<script src="{% static 'js/mrbsection.js' %}"></script> 4<script src="{% static 'js/mrbsection.js' %}"></script>
6 5
7<script>
8 $(document).ready(function () {
9 var ctx = {
10 mrbType : "{{mrb_type}}",
11 }
12
13 try {
14 mrbSectionInit(ctx);
15 } catch (e) {
16 document.write("Sorry, An error has occurred loading this page");
17 console.warn(e);
18 }
19 });
20</script>
21
22{% if mru %} 6{% if mru %}
23
24 {% if mrb_type == 'project' %} 7 {% if mrb_type == 'project' %}
25 <h2> 8 <h2>
26 Latest project builds 9 Latest project builds
@@ -38,6 +21,7 @@
38 <div id="latest-builds"> 21 <div id="latest-builds">
39 {% for build in mru %} 22 {% for build in mru %}
40 <div data-latest-build-result="{{build.id}}" class="alert build-result {% if build.outcome == build.SUCCEEDED %}alert-success{% elif build.outcome == build.FAILED %}alert-danger{% else %}alert-info{% endif %}"> 23 <div data-latest-build-result="{{build.id}}" class="alert build-result {% if build.outcome == build.SUCCEEDED %}alert-success{% elif build.outcome == build.FAILED %}alert-danger{% else %}alert-info{% endif %}">
24 <!-- project title -->
41 {% if mrb_type != 'project' %} 25 {% if mrb_type != 'project' %}
42 <div class="row project-name"> 26 <div class="row project-name">
43 <div class="col-md-12"> 27 <div class="col-md-12">
@@ -48,134 +32,180 @@
48 </div> 32 </div>
49 {% endif %} 33 {% endif %}
50 34
51 <div class="row"> 35 <div class="row" data-role="build-status-container">
52 <div class="col-md-3"> 36 <div class="col-md-12">
53 {% if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %} 37 Loading...
54 <a href="{% url 'builddashboard' build.pk %}" class="alert-link">
55 {% endif %}
56
57 {% if build.target_set.all.count > 0 %}
58 <span data-toggle="tooltip"
59 {% if build.target_set.all.count > 1 %}
60 {{build.get_sorted_target_list.0.target}}
61 title="Recipes:
62 {% for target in build.get_sorted_target_list %}
63 {% if target.task %}
64 {{target.target}}:{{target.task}}
65 {% else %}
66 {{target.target}}
67 {% endif %}
68 {% endfor %}"
69 {% endif %}
70 >
71 {% if build.target_set.all.0.task %}
72 {{build.get_sorted_target_list.0.target}}:{{build.target_set.all.0.task}}
73 {% else %}
74 {{build.get_sorted_target_list.0.target}}
75 {% endif %}
76
77 {% if build.target_set.all.count > 1 %}
78 (+{{build.target_set.all.count|add:"-1"}})
79 {% endif %}
80 </span>
81 {% endif %}
82 {% if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %}
83 </a>
84 {% endif %}
85 </div> 38 </div>
39 </div>
40 </div>
41 {% endfor %}
42 </div>
43{% endif %}
44
45<!-- build main template -->
46<script id="build-template" type="text/x-jsrender">
47 <div class="col-md-3">
48 <!-- only show link for completed builds -->
49 <%if state == 'Succeeded' || state == 'Failed'%>
50 <a class="alert-link" href="<%:dashboard_url%>">
51 <span data-toggle="tooltip" data-role="targets-text" title="Recipes: <%:targets%>">
52 <%:targets_abbreviated%>
53 </span>
54 </a>
55 <%else%>
56 <span data-toggle="tooltip" data-role="targets-text" title="Recipes: <%:targets%>">
57 <%:targets_abbreviated%>
58 </span>
59 <%/if%>
60 </div>
86 61
87 {% if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %} 62 <%if state == 'Queued'%>
88 <div class="col-md-2"> 63 <%include tmpl='#queued-build-template'/%>
89 {% if build.completed_on|format_build_date %} 64 <%else state == 'Succeeded' || state == 'Failed'%>
90 {{build.completed_on|date:'d/m/y H:i'}} 65 <%include tmpl='#succeeded-or-failed-build-template'/%>
91 {% else %} 66 <%else state == 'Cancelling'%>
92 {{ build.completed_on|date:'H:i' }} 67 <%include tmpl='#cancelling-build-template'/%>
93 {% endif %} 68 <%else state == 'In Progress'%>
94 </div> 69 <%include tmpl='#in-progress-build-template'/%>
95 {% endif %} 70 <%else state == 'Cancelled'%>
96 71 <%include tmpl='#cancelled-build-template'/%>
97 {% if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %} 72 <%/if%>
98 <div class="col-md-2"> 73</script>
99 {% if build.errors.count %}
100 <span class="glyphicon glyphicon-minus-sign"></span>
101 <a href="{%url 'builddashboard' build.pk%}#errors" class="alert-link">
102 {{build.errors.count}} error{{build.errors.count|pluralize}}
103 </a>
104 {% endif %}
105 </div>
106 74
107 <div class="col-md-2"> 75<!-- queued build -->
108 {% if build.warnings.count %} 76<script id="queued-build-template" type="text/x-jsrender">
109 <span class="glyphicon glyphicon-warning-sign build-warnings"></span> 77 <div class="col-md-5">
110 <a href="{%url 'builddashboard' build.pk%}#warnings" class="alert-link build-warnings"> 78 Build queued
111 {{build.warnings.count}} warning{{build.warnings.count|pluralize}} 79 </div>
112 </a>
113 {% endif %}
114 </div>
115 80
116 <div class="col-md-3"> 81 <div class="col-md-4">
117 Build time: <a class="alert-link" href="{% url 'buildtime' build.pk %}">{{ build.timespent_seconds|sectohms }} 82 <%if is_default_project_build%>
118 </a> 83 <!-- no cancel icon -->
119 84 <span class="glyphicon glyphicon-question-sign get-help get-help-blue pull-right" title="Builds in this project cannot be cancelled from Toaster: they can only be cancelled from the command line"></span>
120 {% if build.project.is_default %} 85 <%else%>
121 <span class="pull-right glyphicon glyphicon-question-sign get-help {% if build.outcome == build.SUCCEEDED %}get-help-green{% elif build.outcome == build.FAILED %}get-help-red{% else %}get-help-blue{% endif %}" 86 <!-- cancel button -->
122 title="Builds in this project cannot be started from Toaster: they are started from the command line"> 87 <span class="cancel-build-btn pull-right alert-link"
123 </span> 88 data-buildrequest-id="<%:id%>" data-request-url="<%:cancel_url%>">
124 {% else %} 89 <span class="glyphicon glyphicon-remove-circle"></span>
125 <a href="#" class="run-again-btn alert-link {% if build.outcome == build.SUCCEEDED %}success{% elif build.outcome == build.FAILED %}danger{% else %}info{% endif %} pull-right" 90 Cancel
126 data-request-url="{% url 'xhr_buildrequest' build.project.pk %}" 91 </span>
127 data-target='{{build.target_set.all|get_tasks|json}}'> 92 <%/if%>
128 <span class="glyphicon glyphicon-repeat"></span> 93 </div>
129 Rebuild 94</script>
130 </a>
131 {% endif %}
132 </div>
133 {% endif %}
134 95
135 {% if build.outcome == build.IN_PROGRESS %} 96<!-- in progress build -->
136 <div class="col-md-4" style="display:none" id="cancelling-msg-{{build.buildrequest.pk}}"> 97<script id="in-progress-build-template" type="text/x-jsrender">
137 Cancelling the build ... 98 <!-- progress bar and task completion percentage -->
138 </div> 99 <div data-role="build-status" class="col-md-4 col-md-offset-1 progress-info">
100 <!-- progress bar -->
101 <div class="progress" id="build-pc-done-title-<%:id%>">
102 <div id="build-pc-done-bar-<%:id%>"
103 style="width: <%:tasks_complete_percentage%>%;"
104 class="progress-bar">
105 </div>
106 </div>
107 </div>
139 108
140 <div class="col-md-4 col-md-offset-1 progress-info"> 109 <div class="col-md-4 progress-info">
141 <div class="progress" id="build-pc-done-title-{{build.pk}}"> 110 <!-- task completion percentage -->
142 <div id="build-pc-done-bar-{{build.pk}}" style="width: {{build.completeper}}%;" class="progress-bar"> 111 <span id="build-pc-done-<%:id%>"><%:tasks_complete_percentage%></span>% of
143 </div> 112 tasks complete
144 </div> 113 <%if is_default_project_build%>
145 </div> 114 <!-- no cancel icon -->
115 <span class="glyphicon glyphicon-question-sign get-help get-help-blue pull-right" title="Builds in this project cannot be cancelled from Toaster: they can only be cancelled from the command line"></span>
116 <%else%>
117 <!-- cancel button -->
118 <span class="cancel-build-btn pull-right alert-link"
119 data-buildrequest-id="<%:id%>" data-request-url="<%:cancel_url%>">
120 <span class="glyphicon glyphicon-remove-circle"></span>
121 Cancel
122 </span>
123 <%/if%>
124 </div>
125</script>
146 126
147 <div class="col-md-4 progress-info"> 127<!-- cancelling build -->
148 <span id="build-pc-done-{{build.pk}}">{{build.completeper}}</span>% of tasks complete 128<script id="cancelling-build-template" type="text/x-jsrender">
149 {# No build cancel for command line builds project #} 129 <div class="col-md-9">
150 {% if build.project.is_default %} 130 Cancelling the build ...
151 <span class="glyphicon glyphicon-question-sign get-help get-help-blue pull-right" title="Builds in this project cannot be cancelled from Toaster: they can only be cancelled from the command line"></span> 131 </div>
152 {% else %} 132</script>
153 <a href="#" class="cancel-build-btn pull-right alert-link"
154 data-buildrequest-id={{build.buildrequest.pk}}
155 data-request-url="{% url 'xhr_buildrequest' build.project.pk %}">
156 <span class="glyphicon glyphicon-remove-circle"></span>
157 Cancel
158 </a>
159 {% endif %}
160 </div>
161 {% endif %} {# end if in progress #}
162 133
163 {% if build.outcome == build.CANCELLED %} 134<!-- succeeded or failed build -->
164 <div class="col-md-6"> 135<script id="succeeded-or-failed-build-template" type="text/x-jsrender">
165 Build cancelled 136 <!-- completed_on -->
166 </div> 137 <div class="col-md-2">
138 <%:completed_on%>
139 </div>
167 140
168 <div class="col-md-3"> 141 <!-- errors -->
169 <a href="#" class="info pull-right run-again-btn alert-link" 142 <div class="col-md-2">
170 data-request-url="{% url 'xhr_buildrequest' build.project.pk %}" 143 <%if errors%>
171 data-target='{{build.target_set.all|get_tasks|json}}'> 144 <span class="glyphicon glyphicon-minus-sign"></span>
172 <span class="glyphicon glyphicon-repeat"></span> 145 <a href="<%:dashboard_errors_url%>" class="alert-link">
173 Rebuild 146 <%:errors%> error<%:errors_pluralize%>
174 </a> 147 </a>
175 </div> 148 <%/if%>
176 {% endif %} 149 </div>
177 </div> 150
178 </div> 151 <!-- warnings -->
179 {% endfor %} 152 <div class="col-md-2">
153 <%if warnings%>
154 <span class="glyphicon glyphicon-minus-sign"></span>
155 <a href="<%:dashboard_warnings_url%>" class="alert-link">
156 <%:warnings%> warning<%:warnings_pluralize%>
157 </a>
158 <%/if%>
159 </div>
160
161 <!-- build time -->
162 <div class="col-md-3">
163 Build time: <a class="alert-link" href="<%:buildtime_url%>"><%:buildtime%></a>
164
165 <%if is_default_project_build%>
166 <!-- info icon -->
167 <span class="pull-right glyphicon glyphicon-question-sign get-help <%if state == 'Success'%>get-help-green<%else state == 'Failed'%>get-help-red<%else%>get-help-blue<%/if%>"
168 title="Builds in this project cannot be started from Toaster: they are started from the command line">
169 </span>
170 <%else%>
171 <!-- rebuild button -->
172 <span class="rebuild-btn alert-link <%if state == 'Success'%>success<%else state == 'Failed'%>danger<%else%>info<%/if%> pull-right"
173 data-request-url="<%:rebuild_url%>" data-target='<%:build_targets_json%>'>
174 <span class="glyphicon glyphicon-repeat"></span>
175 Rebuild
176 </span>
177 <%/if%>
178 </div>
179</script>
180
181<!-- cancelled build -->
182<script id="cancelled-build-template" type="text/x-jsrender">
183 <!-- build cancelled message -->
184 <div class="col-md-6">
185 Build cancelled
180 </div> 186 </div>
181{% endif %} \ No newline at end of file 187
188 <!-- rebuild button -->
189 <div class="col-md-3">
190 <span class="info pull-right rebuild-btn alert-link"
191 data-request-url="<%:rebuild_url%>" data-target='<%:build_targets_json%>'>
192 <span class="glyphicon glyphicon-repeat"></span>
193 Rebuild
194 </span>
195 </div>
196</script>
197
198<script>
199 $(document).ready(function () {
200 var ctx = {
201 mrbType : "{{mrb_type}}",
202 }
203
204 try {
205 mrbSectionInit(ctx);
206 } catch (e) {
207 document.write("Sorry, An error has occurred loading this page");
208 console.warn(e);
209 }
210 });
211</script>
diff --git a/bitbake/lib/toaster/toastergui/templates/projectbuilds-toastertable.html b/bitbake/lib/toaster/toastergui/templates/projectbuilds-toastertable.html
index 1fe76a7a24..a5fed2dd41 100644
--- a/bitbake/lib/toaster/toastergui/templates/projectbuilds-toastertable.html
+++ b/bitbake/lib/toaster/toastergui/templates/projectbuilds-toastertable.html
@@ -24,7 +24,7 @@
24 24
25 <h2 class="top-air" data-role="page-title"></h2> 25 <h2 class="top-air" data-role="page-title"></h2>
26 26
27 {% if not build_in_progress_none_completed %} 27 {% if not build_in_progress_none_completed %}
28 {% url 'projectbuilds' project.id as xhr_table_url %} 28 {% url 'projectbuilds' project.id as xhr_table_url %}
29 {% include 'toastertable.html' %} 29 {% include 'toastertable.html' %}
30 {% endif %} 30 {% endif %}