summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster/toastergui/templates
diff options
context:
space:
mode:
authorAlexandru DAMIAN <alexandru.damian@intel.com>2014-10-02 17:58:15 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-11-12 17:04:48 +0000
commit42afeb422ea0a5e226cef586353d194d0339bbd7 (patch)
tree86bc1c6716b6b60bb4f77ebd9fa9d044da0daf7a /bitbake/lib/toaster/toastergui/templates
parent46f1fbe3abb3677861178b7008bf5edf73125197 (diff)
downloadpoky-42afeb422ea0a5e226cef586353d194d0339bbd7.tar.gz
bitbake: toastergui: Various fixes for projects, layers and targets page
This is a combined set of fixes for the project, layers and targets pages in the project section of toaster. The fixes correct behaviour and look in various parts of the page, including submitting XHR commands and updating the DOM with the correct info. (Bitbake rev: 96d7738f964784871c928c376cb9fbc9a275cf00) Signed-off-by: Alexandru DAMIAN <alexandru.damian@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.html3
-rw-r--r--bitbake/lib/toaster/toastergui/templates/basetable_bottom.html13
-rw-r--r--bitbake/lib/toaster/toastergui/templates/layers.html124
-rw-r--r--bitbake/lib/toaster/toastergui/templates/mrb_section.html11
-rw-r--r--bitbake/lib/toaster/toastergui/templates/project.html48
-rw-r--r--bitbake/lib/toaster/toastergui/templates/targets.html340
6 files changed, 327 insertions, 212 deletions
diff --git a/bitbake/lib/toaster/toastergui/templates/base.html b/bitbake/lib/toaster/toastergui/templates/base.html
index d414bfbbde..f377081849 100644
--- a/bitbake/lib/toaster/toastergui/templates/base.html
+++ b/bitbake/lib/toaster/toastergui/templates/base.html
@@ -1,6 +1,6 @@
1<!DOCTYPE html> 1<!DOCTYPE html>
2{% load static %} 2{% load static %}
3<html> 3<html lang="en">
4 <head> 4 <head>
5 <title>{% if objectname %} {{objectname|title}} - {% endif %}Toaster</title> 5 <title>{% if objectname %} {{objectname|title}} - {% endif %}Toaster</title>
6<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}" type="text/css"> 6<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}" type="text/css">
@@ -9,6 +9,7 @@
9<link rel="stylesheet" href="{% static 'css/prettify.css' %}" type='text/css'> 9<link rel="stylesheet" href="{% static 'css/prettify.css' %}" type='text/css'>
10<link rel="stylesheet" href="{% static 'css/default.css' %}" type='text/css'> 10<link rel="stylesheet" href="{% static 'css/default.css' %}" type='text/css'>
11<meta name="viewport" content="width=device-width, initial-scale=1.0" /> 11<meta name="viewport" content="width=device-width, initial-scale=1.0" />
12<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
12<script src="{% static 'js/jquery-2.0.3.min.js' %}"> 13<script src="{% static 'js/jquery-2.0.3.min.js' %}">
13</script> 14</script>
14<script src="{% static 'js/jquery.cookie.js' %}"> 15<script src="{% static 'js/jquery.cookie.js' %}">
diff --git a/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html b/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html
index 091e11a51e..d48ad92020 100644
--- a/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html
+++ b/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html
@@ -58,9 +58,12 @@
58 } 58 }
59 59
60 // load cookie for number of entries to be displayed on page 60 // load cookie for number of entries to be displayed on page
61 pagesize = $.cookie('count'); 61 if ({{request.GET.count}} != "") {
62 if (!pagesize) 62 pagesize = {{request.GET.count}};
63 pagesize = 10; 63 } else {
64 pagesize = $.cookie('_count');
65 }
66
64 $('.pagesize option').prop('selected', false) 67 $('.pagesize option').prop('selected', false)
65 .filter('[value="' + pagesize + '"]') 68 .filter('[value="' + pagesize + '"]')
66 .attr('selected', true); 69 .attr('selected', true);
@@ -81,9 +84,9 @@
81 $('.progress, .lead span').tooltip({container:'table', placement:'top'}); 84 $('.progress, .lead span').tooltip({container:'table', placement:'top'});
82 85
83 $(".pagesize").change(function () { 86 $(".pagesize").change(function () {
84 reload_params({"count":$(this).val()});
85 // save cookie with pagesize 87 // save cookie with pagesize
86 $.cookie("count", $(this).val(), { path : $(location).attr('pathname') }); 88 $.cookie("_count", $(this).val(), { path : $(location).attr('pathname') });
89 reload_params({"count":$(this).val()});
87 }); 90 });
88}); 91});
89</script> 92</script>
diff --git a/bitbake/lib/toaster/toastergui/templates/layers.html b/bitbake/lib/toaster/toastergui/templates/layers.html
index 51f4dd96e7..db34fe4818 100644
--- a/bitbake/lib/toaster/toastergui/templates/layers.html
+++ b/bitbake/lib/toaster/toastergui/templates/layers.html
@@ -9,67 +9,66 @@
9{% block projectinfomain %} 9{% block projectinfomain %}
10 <div class="page-header"> 10 <div class="page-header">
11 <h1> 11 <h1>
12 {% if request.GET.search and objects.paginator.count > 0 %} 12 {% if request.GET.filter and objects.paginator.count > 0 or request.GET.search and objects.paginator.count > 0 %}
13 {{objects.paginator.count}} layer{{objects.paginator.count|pluralize}} found 13 {{objects.paginator.count}} layer{{objects.paginator.count|pluralize}} found
14 {%elif request.GET.search and objects.paginator.count == 0%} 14 {% elif request.GET.filter and objects.paginator.count == 0 or request.GET.search and objects.paginator.count == 0 %}
15 No layer found 15 No layers found
16 {%else%} 16 {%else%}
17 All layers 17 All layers
18 {%endif%} 18 {%endif%}
19 <i class="icon-question-sign get-help heading-help" title="This page lists all the layers compatible with " + {{project.release.name}} + " that Toaster knows about."></i> 19 <i class="icon-question-sign get-help heading-help" title="This page lists all the layers compatible with {{project.release.name}} that Toaster knows about."></i>
20 </h1> 20 </h1>
21 </div> 21 </div>
22 22
23 <div id="zone1alerts"> 23 <div id="zone1alerts">
24
25 </div> 24 </div>
26 25
27 26
28 <div id="layer-added" class="alert alert-info lead" style="display:none;"></div>
29
30
31{% include "basetable_top_layers.html" %} 27{% include "basetable_top_layers.html" %}
32 {% for lv in objects %} 28 {% for o in objects %}
33 <tr class="data"> 29 <tr class="data">
34 <td class="layer"><a href="{% url 'layerdetails' lv.id %}">{{lv.layer.name}}</a></td> 30 <td class="layer"><a href="{% url 'layerdetails' o.id %}">{{o.layer.name}}</a></td>
35 <td class="description">{{lv.layer.summary}}</td> 31 <td class="description">{% if o.layer.summary %}{{o.layer.summary}}{%endif%}</td>
36 <td class="source"><a href="{% url 'layerdetails' lv.pk %}">{{lv.layer_source.name}}</a></td> 32 <td class="source"><a href="{% url 'layerdetails' o.pk %}">{{o.layer_source.name}}</a></td>
37 <td class="git-repo"><a href="{% url 'layerdetails' lv.pk %}"><code>{{lv.layer.vcs_url}}</code></a> 33 <td class="git-repo"><a href="{% url 'layerdetails' o.pk %}"><code>{{o.layer.vcs_url}}</code></a>
38 {% if lv.get_vcs_link_url %} 34 {% if o.get_vcs_link_url %}
39 <a target="_blank" href="{{ lv.get_vcs_link_url }}"><i class="icon-share get-info"></i></a> 35 <a target="_blank" href="{{ o.get_vcs_link_url }}"><i class="icon-share get-info"></i></a>
40 {% endif %} 36 {% endif %}
41 </td> 37 </td>
42 <td class="git-subdir" style="display: table-cell;"><a href="{% url 'layerdetails' lv.pk %}"><code>{{lv.dirpath}}</code></a> 38 <td class="git-subdir" style="display: table-cell;"><a href="{% url 'layerdetails' o.pk %}"><code>{{o.dirpath}}</code></a>
43 {% if lv.dirpath and lv.get_vcs_dirpath_link_url %} 39 {% if o.dirpath and o.get_vcs_dirpath_link_url %}
44 <a target="_blank" href="{{ lv.get_vcs_dirpath_link_url }}"><i class="icon-share get-info"></i></a> 40 <a target="_blank" href="{{ o.get_vcs_dirpath_link_url }}"><i class="icon-share get-info"></i></a>
45 {% endif %} 41 {% endif %}
46 </td> 42 </td>
47 <td class="branch">{% if lv.branch %}{{lv.branch}}{% else %}{{lv.up_branch.name}}{% endif %}</td> 43 <td class="branch">{% if o.branch %}{{o.branch}}{% else %}{{o.up_branch.name}}{% endif %}</td>
48 <td class="dependencies"> 44 <td class="dependencies">
49 {% with lvds=lv.dependencies.all%} 45 {% with ods=o.dependencies.all%}
50 {% if lvds.count %} 46 {% if ods.count %}
51 <a class="btn" 47 <a class="btn"
52 title="<a href='{% url "layerdetails" lv.pk %}'>{{lv.layer.name}}</a> dependencies" 48 title="<a href='{% url "layerdetails" o.pk %}'>{{o.layer.name}}</a> dependencies"
53 data-content="<ul class='unstyled'> 49 data-content="<ul class='unstyled'>
54 {% for i in lvds%} 50 {% for i in ods%}
55 <li><a href='{% url "layerdetails" i.depends_on.pk %}'>{{i.depends_on.layer.name}}</a></li> 51 <li><a href='{% url "layerdetails" i.depends_on.pk %}'>{{i.depends_on.layer.name}}</a></li>
56 {% endfor %} 52 {% endfor %}
57 </ul>"> 53 </ul>">
58 {{lvds.count}} 54 {{ods.count}}
59 </a> 55 </a>
60 {% endif %} 56 {% endif %}
61 {% endwith %} 57 {% endwith %}
62 </td> 58 </td>
63 <td class="add-del-layers" value="{{lv.pk}}"> 59 {% if project %}
64 <button id="layer-del-{{lv.pk}}" class="btn btn-danger btn-block remove-layer" style="display:none;" onclick="layerDel({{lv.pk}}, '{{lv.layer.name}}', '{%url 'layerdetails' lv.pk%}')"> 60 <td class="add-del-layers" value="{{o.pk}}">
61 <div id="layer-tooltip-{{o.pk}}" style="display: none; font-size: 11px; line-height: 1.3;" class="tooltip-inner">layer was modified</div>
62 <button id="layer-del-{{o.pk}}" class="btn btn-danger btn-block remove-layer layerbtn" style="display:none;" onclick="layerDel({{o.pk}}, '{{o.layer.name}}', '{%url 'layerdetails' o.pk%}')" >
65 <i class="icon-trash"></i> 63 <i class="icon-trash"></i>
66 Delete layer 64 Delete layer
67 </button> 65 </button>
68 <button id="layer-add-{{lv.pk}}" class="btn btn-block" style="display:none;" onclick="layerAdd({{lv.pk}}, '{{lv.layer.name}}', '{%url 'layerdetails' lv.pk%}')" > 66 <button id="layer-add-{{o.pk}}" class="btn btn-block layerbtn" style="display:none;" onclick="layerAdd({{o.pk}}, '{{o.layer.name}}', '{%url 'layerdetails' o.pk%}')" title="layer added">
69 <i class="icon-plus"></i> 67 <i class="icon-plus"></i>
70 Add layer 68 Add layer
71 </button> 69 </button>
72 </td> 70 </td>
71 {% endif %}
73 </tr> 72 </tr>
74 {% endfor %} 73 {% endfor %}
75{% include "basetable_bottom.html" %} 74{% include "basetable_bottom.html" %}
@@ -78,7 +77,7 @@
78 77
79 <!-- 'Layer dependencies modal' --> 78 <!-- 'Layer dependencies modal' -->
80 <div id="dependencies_modal" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true"> 79 <div id="dependencies_modal" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true">
81 <form id="dependencies_modal_form"> 80 <form id="dependencies_modal_form" style="margin: 0px">
82 <div class="modal-header"> 81 <div class="modal-header">
83 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button> 82 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
84 <h3><span class="layer-name"></span> dependencies</h3> 83 <h3><span class="layer-name"></span> dependencies</h3>
@@ -95,8 +94,11 @@
95 </form> 94 </form>
96 </div> 95 </div>
97 96
97{% if project %}
98<script> 98<script>
99 99
100var tooltipUpdateText;
101
100function _makeXHREditCall(data, onsuccess, onfail) { 102function _makeXHREditCall(data, onsuccess, onfail) {
101 $.ajax( { 103 $.ajax( {
102 type: "POST", 104 type: "POST",
@@ -120,13 +122,14 @@ function _makeXHREditCall(data, onsuccess, onfail) {
120 122
121 123
122function layerDel(layerId, layerName, layerURL) { 124function layerDel(layerId, layerName, layerURL) {
125 tooltipUpdateText = "1 layer deleted";
123 _makeXHREditCall({ 'layerDel': layerId }, function () { 126 _makeXHREditCall({ 'layerDel': layerId }, function () {
124 show_alert("<strong>1</strong> layer deleted from <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>: <a href=\""+layerURL+"\">" + layerName +"</a>"); 127 show_alert("You have deleted <strong>1</strong> layer from <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>: <a href=\""+layerURL+"\">" + layerName +"</a>");
125 }); 128 });
126} 129}
127 130
128function show_alert(text, cls) { 131function show_alert(text, cls) {
129 $("#zone1alerts").html("<div class=\"alert alert-info\"><button type=\"button\" class=\"close\" data-dismiss=\"alert\">&times;</button>" + text + "</div>"); 132 $("#zone1alerts").html("<div class=\"alert alert-info lead\"><button type=\"button\" class=\"close\" data-dismiss=\"alert\">&times;</button>" + text + "</div>");
130} 133}
131 134
132function show_dependencies_modal(layerId, layerName, layerURL, dependencies) { 135function show_dependencies_modal(layerId, layerName, layerURL, dependencies) {
@@ -142,25 +145,35 @@ function show_dependencies_modal(layerId, layerName, layerURL, dependencies) {
142 } 145 }
143 $('#dependencies_list').html(deplistHtml); 146 $('#dependencies_list').html(deplistHtml);
144 147
148 var selected = [layerId];
149 var layer_link_list = "<a href='"+layerURL+"'>"+layerName+"</a>";
150
145 $("#dependencies_modal_form").submit(function (e) { 151 $("#dependencies_modal_form").submit(function (e) {
146 e.preventDefault(); 152 e.preventDefault();
147 var selected = [layerId];
148 $("input[name='dependencies']:checked").map(function () { selected.push(parseInt($(this).val()))}); 153 $("input[name='dependencies']:checked").map(function () { selected.push(parseInt($(this).val()))});
154 if (selected.length > 1) {
155 tooltipUpdateText = "" + selected.length + " layers added";
156 } else {
157 tooltipUpdateText = "1 layer added";
158 }
149 159
150 _makeXHREditCall({ 'layerAdd': selected.join(",") }, function () { 160 for (var i = 0; i < selected.length; i++) {
151 var layer_link_list = "<a href='"+layerURL+"'>"+layerName+"</a>"; 161 for (var j = 0; j < dependencies.length; j++) {
152 for (var i = 0; i < selected.length; i++) { 162 if (dependencies[j].id == selected[i]) {
153 for (var j = 0; j < dependencies.length; i++) { 163 layer_link_list+= ", <a href='"+dependencies[j].layerdetailurl+"'>"+dependencies[j].name+"</a>"
154 if (dependencies[j].id == selected[i]) { 164 break;
155 layer_link_list+= ", <a href='"+dependencies[j].layerdetailurl+"'>"+dependencies[j].name+"</a>"
156 break;
157 }
158 } 165 }
159 } 166 }
167 }
168
169 $('#dependencies_modal').modal('hide');
160 170
161 $('#dependencies_modal').modal('hide'); 171 {% if project %}
162 show_alert("<strong>"+selected.length+"</strong> layers added to <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>:" + layer_link_list); 172 _makeXHREditCall({ 'layerAdd': selected.join(",") }, function () {
173 show_alert("You have added <strong>"+selected.length+"</strong> layers to <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>: " + layer_link_list);
163 }); 174 });
175 {% endif %}
176
164 }); 177 });
165 $('#dependencies_modal').modal('show'); 178 $('#dependencies_modal').modal('show');
166} 179}
@@ -178,8 +191,9 @@ function layerAdd(layerId, layerName, layerURL) {
178 show_dependencies_modal(layerId, layerName, layerURL, _data.list); 191 show_dependencies_modal(layerId, layerName, layerURL, _data.list);
179 } 192 }
180 else { 193 else {
194 tooltipUpdateText = "1 layer added";
181 _makeXHREditCall({ 'layerAdd': layerId }, function () { 195 _makeXHREditCall({ 'layerAdd': layerId }, function () {
182 show_alert("<strong>1</strong> layer added to <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>: <a href=\""+layerURL+"\">" + layerName +"</a>"); 196 show_alert("You have added <strong>1</strong> layer to <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>: <a href=\""+layerURL+"\">" + layerName +"</a>");
183 }); 197 });
184 } 198 }
185 } 199 }
@@ -188,15 +202,31 @@ function layerAdd(layerId, layerName, layerURL) {
188} 202}
189 203
190function button_set(id, state) { 204function button_set(id, state) {
205 var tohide, toshow;
191 if (state == "add") 206 if (state == "add")
192 { 207 {
193 $("#layer-add-" + id).show(); 208 tohide = "#layer-del-";
194 $("#layer-del-" + id).hide(); 209 toshow = "#layer-add-";
195 } 210 }
196 else if (state == "del") 211 else if (state == "del")
197 { 212 {
198 $("#layer-add-" + id).hide(); 213 tohide = "#layer-add-";
199 $("#layer-del-" + id).show(); 214 toshow = "#layer-del-";
215 }
216
217
218 var previouslyvisible = $(tohide + id).is(":visible");
219 if (previouslyvisible) {
220 $(tohide + id).fadeOut( function() {
221 $("#layer-tooltip-" + id).text(tooltipUpdateText);
222 $("#layer-tooltip-" + id).fadeIn().delay(2000).fadeOut(function(){
223 $(toshow + id).delay(300).fadeIn();
224 });
225 });
226 } else {
227 $(tohide + id).hide();
228 $("#layer-tooltip-" + id).hide();
229 $(toshow + id).show();
200 } 230 }
201}; 231};
202 232
@@ -214,9 +244,11 @@ function updateButtons(projectLayers) {
214} 244}
215 245
216$(document).ready(function (){ 246$(document).ready(function (){
247 $('.layerbtn').tooltip({ trigger: 'manual' });
217 updateButtons({{projectlayerset}}); 248 updateButtons({{projectlayerset}});
218}); 249});
219 250
220</script> 251</script>
252{%endif%}
221 253
222{% endblock %} 254{% endblock %}
diff --git a/bitbake/lib/toaster/toastergui/templates/mrb_section.html b/bitbake/lib/toaster/toastergui/templates/mrb_section.html
index 3d17ac62e4..586c47bfae 100644
--- a/bitbake/lib/toaster/toastergui/templates/mrb_section.html
+++ b/bitbake/lib/toaster/toastergui/templates/mrb_section.html
@@ -44,7 +44,7 @@
44 Build time: <a href="{% url 'buildtime' build.pk %}">{{ build.timespent|sectohms }}</a> 44 Build time: <a href="{% url 'buildtime' build.pk %}">{{ build.timespent|sectohms }}</a>
45 </span> 45 </span>
46 {% if build.project %} 46 {% if build.project %}
47 <a class="btn {%if build.outcome == build.SUCCEEDED%}btn-success{%elif build.outcome == build.FAILED%}btn-danger{%else%}btn-info{%endif%} pull-right" onclick="scheduleBuild({%url 'xhr_projectbuild' build.project.id as myurl %}{{myurl|json}}, {{build.project.name|json}}, {{build.get_sorted_target_list|mapselect:'target'|json}})">Run again</a> 47 <a class="btn {%if build.outcome == build.SUCCEEDED%}btn-success{%elif build.outcome == build.FAILED%}btn-danger{%else%}btn-info{%endif%} pull-right" onclick="scheduleBuild({% url 'xhr_projectbuild' build.project.id as bpi%}{{bpi|json}}, {{build.project.name|json}}, {{build.get_sorted_target_list|mapselect:'target'|json}})">Run again</a>
48 {% endif %} 48 {% endif %}
49 </div> 49 </div>
50 {%endif%} 50 {%endif%}
@@ -81,19 +81,18 @@ function _makeXHRBuildCall(url, data, onsuccess, onfail) {
81 alert("Call failed"); 81 alert("Call failed");
82 console.log(_data); 82 console.log(_data);
83 if (onfail) onfail(data); 83 if (onfail) onfail(data);
84 } 84 } });
85 });
86} 85}
87 86
88 87
89function scheduleBuild(url, projectName, buildlist) { 88function scheduleBuild(url, projectName, buildlist) {
90 console.log("scheduleBuild"); 89 console.log("scheduleBuild");
91// _makeXHRBuildCall(url , {targets: buildlist.join(" ")}, function (_data) { 90 _makeXHRBuildCall(url, {targets: buildlist.join(" ")}, function (_data) {
92 91
93 $('#latest-builds').prepend('<div class="alert alert-info" style="padding-top:0px">' + '<span class="label label-info" style="font-weight: normal; margin-bottom: 5px; margin-left:-15px; padding-top:5px;">'+projectName+'</span><div class="row-fluid">' + 92 $('#latest-builds').prepend('<div class="alert alert-info" style="padding-top:0px">' + '<span class="label label-info" style="font-weight: normal; margin-bottom: 5px; margin-left:-15px; padding-top:5px;">'+projectName+'</span><div class="row-fluid">' +
94 '<div class="span4 lead">' + buildlist.join(" ") + 93 '<div class="span4 lead">' + buildlist.join(" ") +
95 '</div><div class="span4 lead pull-right">Build queued. Your build will start shortly.</div></div></div>'); 94 '</div><div class="span4 lead pull-right">Build queued. Your build will start shortly.</div></div></div>');
96// } 95 });
97} 96}
98 97
99</script> 98</script>
diff --git a/bitbake/lib/toaster/toastergui/templates/project.html b/bitbake/lib/toaster/toastergui/templates/project.html
index 9399b312ca..6a812834d3 100644
--- a/bitbake/lib/toaster/toastergui/templates/project.html
+++ b/bitbake/lib/toaster/toastergui/templates/project.html
@@ -76,6 +76,14 @@ vim: expandtab tabstop=2
76 </div> 76 </div>
77 </script> 77 </script>
78 78
79 <script type="text/ng-template" id="target_display">
80 <div ng-switch on="t.task.length">
81 <div ng-switch-when="0">{[t.target]}</div>
82 <div ng-switch-default>{[t.target]}:{[t.task]}</div>
83 </div>
84 </script>
85
86
79 <!-- build form --> 87 <!-- build form -->
80 <div class="well"> 88 <div class="well">
81 <form class="build-form" ng-submit="targetNamedBuild()"> 89 <form class="build-form" ng-submit="targetNamedBuild()">
@@ -99,11 +107,11 @@ vim: expandtab tabstop=2
99 107
100 <h2 class="air" ng-if="builds.length">Latest builds</h2> 108 <h2 class="air" ng-if="builds.length">Latest builds</h2>
101 109
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]"> 110 <div class="alert" ng-repeat="b in builds" ng-class="{'queued':'alert-info', 'deleted':'alert-info', 'in progress': 'alert-info', 'failed':'alert-error', 'completed':{'In Progress':'alert-info', 'Succeeded':'alert-success', 'Failed':'alert-error'}[b.build[0].status]}[b.status]" >
103 <div class="row-fluid"> 111 <div class="row-fluid">
104 <switch ng-switch="b.status"> 112 <switch ng-switch="b.status">
105 <case ng-switch-when="failed"> 113 <case ng-switch-when="failed">
106 <div class="lead span3"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div> 114 <div class="lead span3"> <span ng-repeat="t in b.targets" ng-include src="'target_display'"></span> </div>
107 <div class="row-fluid"> 115 <div class="row-fluid">
108 <div class="air well" ng-repeat="e in b.errors"> 116 <div class="air well" ng-repeat="e in b.errors">
109 {[e.type]}: <pre>{[e.msg]}</pre> 117 {[e.type]}: <pre>{[e.msg]}</pre>
@@ -111,53 +119,51 @@ vim: expandtab tabstop=2
111 </div> 119 </div>
112 </case> 120 </case>
113 <case ng-switch-when="queued"> 121 <case ng-switch-when="queued">
114 <div class="lead span5"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div> 122 <div class="lead span5"> <span ng-repeat="t in b.targets" ng-include src="'target_display'"></span> </div>
115 <div class="span4 lead" >Build queued 123 <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> 124 <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> 125 </div>
118 <button class="btn pull-right btn-info" ng-click="buildCancel(b.id)">Cancel</button> 126 <button class="btn pull-right btn-info" ng-click="buildCancel(b.id)">Cancel</button>
119 </case> 127 </case>
120 <case ng-switch-when="created"> 128 <case ng-switch-when="created">
121 <div class="lead span3"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div> 129 <div class="lead span3"> <span ng-repeat="t in b.targets" ng-include src="'target_display'"></span> </div>
122 <div class="span6" > 130 <div class="span6" >
123 <span class="lead">Creating build</span> 131 <span class="lead">Creating build</span>
124 </div> 132 </div>
125 <button class="btn pull-right btn-info" ng-click="buildCancel(b.id)">Cancel</button> 133 <button class="btn pull-right btn-info" ng-click="buildCancel(b.id)">Cancel</button>
126 </case> 134 </case>
127 <case ng-switch-when="deleted"> 135 <case ng-switch-when="deleted">
128 <div class="lead span3"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div> 136 <div class="lead span3"> <span ng-repeat="t in b.targets" ng-include src="'target_display'"></span> </div>
129 <div class="span6" id="{[b.id]}-deleted" > 137 <div class="span6" id="{[b.id]}-deleted" >
130 <span class="lead">Build deleted</span> 138 <span class="lead">Build deleted</span>
131 </div> 139 </div>
132 <button class="btn pull-right btn-info" ng-click="builds.splice(builds.indexOf(b), 1)">Close</button> 140 <button class="btn pull-right btn-info" ng-click="builds.splice(builds.indexOf(b), 1)">Close</button>
133 </case> 141 </case>
134 <case ng-switch-when="in progress"> 142 <case ng-switch-when="in progress">
135 <div class="lead span3"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div> 143 <div class="lead span3"> <span ng-repeat="t in b.targets" ng-include src="'target_display'"></span> </div>
136 <div class="span4" >
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" > 144 <div class="span4" >
142 <div class="progress" style="margin-top:5px;" data-toggle="tooltip" tooltip="{[b.completeper]}% of tasks complete"> 145 <div class="progress" style="margin-top:5px;" data-toggle="tooltip" tooltip="{[b.build[0].completeper]}% of tasks complete">
143 <div style="width: {[b.completeper]}%;" class="bar"></div> 146 <div style="width: {[b.build[0].completeper]}%;" class="bar"></div>
144 </div> 147 </div>
145 </div> 148 </div>
146 <div class="lead pull-right">ETA: at {[b.eta]}</div> 149 <div class="lead pull-right">ETA: at {[b.build[0].eta|date:"shortDate"]}</div>
147 </case> 150 </case>
148 <case ng-switch-default=""> 151 <case ng-switch-when="completed">
149 <div class="lead span3"><a href="{[b.build_page_url]}"><span ng-repeat="t in b.targets">{[t.target]} </span> </div></a> 152 <div class="lead span3"><a href="{[b.build[0].build_page_url]}"><span ng-repeat="t in b.targets" ng-include src="'target_display'"></span></a></div>
150 <div class="span2 lead"> 153 <div class="span2 lead">
151 {[b.completed_on|date:'dd/MM/yy HH:mm']} 154 {[b.build[0].completed_on|date:'dd/MM/yy HH:mm']}
152 </div> 155 </div>
153 <div class="span2"><span>{[b.errors.len]}</span></div> 156 <div class="span2"><span><a href="{[b.build[0].build_page_url]}#errors" class="lead error" ng-if="b.build[0].errors">{[b.build[0].errors]}</a></span></div>
154 <div class="span2"><span>{[b.warnings.len]}</span></div> 157 <div class="span2"><span><a href="{[b.build[0].build_page_url]}#warnings" class="lead warning" ng-if="b.build[0].warnings">{[b.build[0].warnings]}</a></span></div>
155 <div> <span class="lead">Build time: {[b.build_time|date:"HH:mm"]}</span> 158 <div> <span class="lead">Build time: {[b.build[0].build_time|timediff]}</span>
156 <button class="btn pull-right" ng-class="{'Succeeded': 'btn-success', 'Failed': 'btn-danger'}[b.status]" 159 <button class="btn pull-right" ng-class="{'Succeeded': 'btn-success', 'Failed': 'btn-danger'}[b.build[0].status]"
157 ng-click="targetExistingBuild(b.targets)">Run again</button> 160 ng-click="targetExistingBuild(b.targets)">Run again</button>
158 161
159 </div> 162 </div>
160 </case> 163 </case>
164 <case ng-switch-default="">
165 <div>FIXME!</div>
166 </case>
161 </switch> 167 </switch>
162 <div class="lead pull-right"> 168 <div class="lead pull-right">
163 </div> 169 </div>
diff --git a/bitbake/lib/toaster/toastergui/templates/targets.html b/bitbake/lib/toaster/toastergui/templates/targets.html
index 3afdf0a5e9..32a644a743 100644
--- a/bitbake/lib/toaster/toastergui/templates/targets.html
+++ b/bitbake/lib/toaster/toastergui/templates/targets.html
@@ -9,55 +9,74 @@
9{% block projectinfomain %} 9{% block projectinfomain %}
10 <div class="page-header"> 10 <div class="page-header">
11 <h1> 11 <h1>
12 All targets 12 {% if request.GET.filter and objects.paginator.count > 0 or request.GET.search and objects.paginator.count > 0 %}
13 <i class="icon-question-sign get-help heading-help" title="This page lists all the targets compatible with Yocto Project 1.7 'Dxxxx' that Toaster knows about. They include community-created targets suitable for use on top of OpenEmbedded Core and any targets you have imported"></i> 13 {{objects.paginator.count}} target{{objects.paginator.count|pluralize}} found
14 {% elif request.GET.filter and objects.paginator.count == 0 or request.GET.search and objects.paginator.count == 0 %}
15 No targets found
16 {%else%}
17 All targets
18 {%endif%}
19 <i class="icon-question-sign get-help heading-help" title="This page lists all the targets compatible with " + {{project.release.name}} + " that Toaster knows about."></i>
14 </h1> 20 </h1>
15 </div> 21 </div>
16 <!--div class="alert">
17 <div class="input-append" style="margin-bottom:0px;">
18 <input class="input-xxlarge" type="text" placeholder="Search targets" value="browser" />
19 <a class="add-on btn">
20 <i class="icon-remove"></i>
21 </a>
22 <button class="btn" type="button">Search</button>
23 <a class="btn btn-link" href="#">Show all targets</a>
24 </div>
25 </div-->
26 <div id="target-added" class="alert alert-info lead" style="display:none;"></div>
27 <div id="target-removed" class="alert alert-info lead" style="display:none;">
28 <button type="button" class="close" data-dismiss="alert">&times;</button>
29 <strong>1</strong> target deleted from <a href="project-with-targets.html">your project</a>: <a href="#">meta-aarch64</a>
30 </div>
31 22
23 <div id="zone1alerts">
24
25 </div>
26
27{% if objects.paginator.count == 0 %}
28 <div class="row-fluid">
29 <div class="alert">
30 <form class="no-results input-append" id="searchform">
31 <input id="search" name="search" class="input-xxlarge" type="text" value="{{request.GET.search}}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %}
32 <button class="btn" type="submit" value="Search">Search</button>
33 <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all targets</button>
34 </form>
35 </div>
36 </div>
37
38{% else %}
32 39
33{% include "basetable_top.html" %} 40{% include "basetable_top.html" %}
34 {% for o in objects %} 41 {% for o in objects %}
35 <tr class="data"> 42 <tr class="data">
36 <td class="target"> 43 <td class="target">
37 {{o.name}} ({{o.id}}, {{o.up_id}}) 44 {{o.name}}
38 <a target="_blank" href="{{o.get_layersource_view_url}}"><i class="icon-share get-info"></i></a> 45 <a target="_blank" href="{{o.get_layersource_view_url}}"><i class="icon-share get-info"></i></a>
39 </td> 46 </td>
40 <td class="version">{{o.version}}</td> 47 <td class="version">{{o.version}}</td>
41 <td class="description">{{o.description}}</td> 48 <td class="description">{% if o.description %}{{o.description}}{% else %}{{o.summary}}{%endif%}</td>
42 <td class="recipe-file"> 49 <td class="recipe-file">
43 <code>{{o.file_path}}</code> 50 <code>{{o.file_path}}</code>
44 <a href="{{o.get_vcs_link_url}}" target="_blank"><i class="icon-share get-info"></i></a> 51 <a href="{{o.get_vcs_link_url}}{{o.file_path}}" target="_blank"><i class="icon-share get-info"></i></a>
45 </td> 52 </td>
46 <td class="target-section">{{o.section}}</td> 53 <td class="target-section">{{o.section}}</td>
47 <td class="license">{{o.license}}</td> 54 <td class="license">{{o.license}}</td>
48 <td class="layer"><a href="#">{{o.layer_version.layer.name}}</a></td> 55 <td class="layer"><a href="{% url 'layerdetails' o.layer_version.id%}">{{o.layer_version.layer.name}}</a></td>
49 <td class="source">{{o.layer_source.name}}</td> 56 <td class="source">{{o.layer_source.name}}</td>
50 <td class="branch">{{o.layer_version.commit}}</td> 57 <td class="branch">
51 <td class="build"> 58 {% if o.layer_version.up_branch %}
52 <a id="build-target" href="project-with-targets.html?target=3g-router-image" class="btn btn-block" style="display:none;"> 59 {{o.layer_version.up_branch.name}}
53 Build target 60 {% else %}
54 </a> 61 <a class="btn"
55 <a id="add-layer" href="#" class="btn btn-block nopop" title="1 layer added"> 62 data-content="<ul class='unstyled'>
56 <i class="icon-plus"></i> 63 <li>{{o.layer_version.commit}}</li>
57 Add layer 64 </ul>">
58 <i class="icon-question-sign get-help" title="To build this target, you must first add the meta-embeddedgeeks layer to your project"></i> 65 {{o.layer_version.commit|truncatechars:13}}
59 </a> 66 </a>
60 </td> 67 {% endif %}
68 </td>
69 <td class="add-layer" value="{{o.pk}}" layerversion_id="{{o.layer_version.pk}}">
70 <div id="layer-tooltip-{{o.pk}}" style="display: none; font-size: 11px; line-height: 1.3;" class="tooltip-inner">layer was modified</div>
71 <a href="{% url 'project' project.id %}#/targetbuild={{o.name}}" id="target-build-{{o.pk}}" class="btn btn-block remove-layer" style="display:none;" >
72 Build target
73 </a>
74 <a id="layer-add-{{o.pk}}" class="btn btn-block" style="display:none;" href="javascript:layerAdd({{o.layer_version.pk}}, '{{o.layer_version.layer.name}}', '{%url 'layerdetails' o.layer_version.pk%}', {{o.pk}})" >
75 <i class="icon-plus"></i>
76 Add layer
77 <i title="" class="icon-question-sign get-help" data-original-title="To build this target, you must first add the {{o.layer_version.layer.name}} layer to your project"></i>
78 </a>
79 </td>
61 </tr> 80 </tr>
62 {% endfor %} 81 {% endfor %}
63{% include "basetable_bottom.html" %} 82{% include "basetable_bottom.html" %}
@@ -65,122 +84,177 @@
65 <!-- Modals --> 84 <!-- Modals -->
66 85
67 <!-- 'Layer dependencies modal' --> 86 <!-- 'Layer dependencies modal' -->
68 <div id="dependencies-message" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true"> 87 <div id="dependencies_modal" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true">
88 <form id="dependencies_modal_form">
69 <div class="modal-header"> 89 <div class="modal-header">
70 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button> 90 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
71 <h3>meta-acer dependencies</h3> 91 <h3><span class="layer-name"></span> dependencies</h3>
72 </div> 92 </div>
73 <div class="modal-body"> 93 <div class="modal-body">
74 <p><strong>meta-acer</strong> depends on some targets that are not added to your project. Select the ones you want to add:</p> 94 <p><strong class="layer-name"></strong> depends on some layers that are not added to your project. Select the ones you want to add:</p>
75 <ul class="unstyled"> 95 <ul class="unstyled" id="dependencies_list">
76 <li>
77 <label class="checkbox">
78 <input type="checkbox" checked="checked">
79 meta-android
80 </label>
81 </li>
82 <li>
83 <label class="checkbox">
84 <input type="checkbox" checked="checked">
85 meta-oe
86 </label>
87 </li>
88 </ul> 96 </ul>
89 </div> 97 </div>
90 <div class="modal-footer"> 98 <div class="modal-footer">
91 <button id="add-target-dependencies" type="submit" class="btn btn-primary" data-dismiss="modal" >Add targets</button> 99 <button class="btn btn-primary" type="submit">Add layers</button>
92 <button class="btn" data-dismiss="modal">Cancel</button> 100 <button class="btn" type="reset" data-dismiss="modal">Cancel</button>
93 </div> 101 </div>
102 </form>
94 </div> 103 </div>
95 104
96 <script src="assets/js/jquery-1.9.1.min.js" type='text/javascript'></script> 105{% endif %}
97 <script src="assets/js/jquery.tablesorter.min.js" type='text/javascript'></script> 106
98 <script src="assets/js/jquery-ui-1.10.3.custom.min.js"></script> 107{% if project %}
99 <script src="assets/js/bootstrap.min.js" type='text/javascript'></script> 108<script>
100 <script src="assets/js/prettify.js" type='text/javascript'></script> 109
101 <script src="assets/js/jit.js" type='text/javascript'></script> 110var tooltipUpdateText;
102 <script src="assets/js/main.js" type='text/javascript'></script> 111
103 112function _makeXHREditCall(data, onsuccess, onfail) {
104 <script> 113 $.ajax( {
105 $(document).ready(function() { 114 type: "POST",
106 115 url: "{% url 'xhr_projectedit' project.id %}",
107 //show or hide selected columns on load 116 data: data,
108 $("input:checkbox").each(function(){ 117 headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
109 var selectedType = $(this).val(); 118 success: function (_data) {
110 if($(this).is(":checked")){ 119 if (_data.error != "ok") {
111 $("."+selectedType).show(); 120 alert(_data.error);
121 } else {
122 updateButtons(_data.layers.map(function (e) {return e.id}));
123 if (onsuccess != undefined) onsuccess(_data);
112 } 124 }
113 else{ 125 },
114 $("."+selectedType).hide(); 126 error: function (_data) {
127 alert("Call failed");
128 console.log(_data);
129 }
130 });
131}
132
133function show_alert(text, cls) {
134 $("#zone1alerts").html("<div class=\"alert alert-info lead\"><button type=\"button\" class=\"close\" data-dismiss=\"alert\">&times;</button>" + text + "</div>");
135}
136
137
138function show_dependencies_modal(layerId, layerName, layerURL, dependencies) {
139 // update layer name
140 $('.layer-name').text(layerName);
141 var deplistHtml = "";
142 for (var i = 0; i < dependencies.length; i++) {
143 deplistHtml += "<li><label class=\"checkbox\"><input name=\"dependencies\" value=\""
144 deplistHtml += dependencies[i].id;
145 deplistHtml +="\" type=\"checkbox\" checked=\"checked\"/>";
146 deplistHtml += dependencies[i].name;
147 deplistHtml += "</label></li>";
148 }
149 $('#dependencies_list').html(deplistHtml);
150
151 var selected = [layerId];
152 var layer_link_list = undefined;
153
154 $("#dependencies_modal_form").submit(function (e) {
155 e.preventDefault();
156 $("input[name='dependencies']:checked").map(function () { selected.push(parseInt($(this).val()))});
157 layer_link_list = "<a href='"+layerURL+"'>"+layerName+"</a>";
158 if (selected.length > 1) {
159 tooltipUpdateText = "" + selected.length + " layers added";
160 } else {
161 tooltipUpdateText = "1 layer added";
162 }
163
164 for (var i = 0; i < selected.length; i++) {
165 for (var j = 0; j < dependencies.length; j++) {
166 if (dependencies[j].id == selected[i]) {
167 layer_link_list+= ", <a href='"+dependencies[j].layerdetailurl+"'>"+dependencies[j].name+"</a>"
168 break;
169 }
115 } 170 }
171 }
172
173 $('#dependencies_modal').modal('hide');
174
175 {% if project %}
176 _makeXHREditCall({ 'layerAdd': selected.join(",") }, function onXHRSuccess() {
177 show_alert("You have added <strong>"+selected.length+"</strong> layer(s) to <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>:" + layer_link_list);
116 }); 178 });
179 {% endif %}
117 180
118 // enable add target button 181 });
119 $('#add-target-with-deps').removeAttr('disabled'); 182 $('#dependencies_modal').modal('show');
183}
120 184
121 //edit columns functionality (show / hide table columns)
122 $("input:checkbox").change();
123 $("input:checkbox").change(function(){
124 var selectedType = $(this).val();
125 if($(this).is(":checked")){
126 $("."+selectedType).show();
127 }
128 else{
129 $("."+selectedType).hide();
130 }
131 });
132 185
133 //turn edit columns dropdown into a multi-select menu 186var pressedButton = undefined;
134 $('.dropdown-menu input, .dropdown-menu label').click(function(e) {
135 e.stopPropagation();
136 });
137 187
138 //show tooltip with applied filter 188function layerAdd(layerId, layerName, layerURL, pressedButtonId) {
139 $('#filtered').tooltip({container:'table', placement:'bottom', delay:{hide:1500}, html:true}); 189 pressedButton = pressedButtonId;
190 $.ajax({
191 url: '{% url "xhr_datatypeahead" %}',
192 data: {'type': 'layerdeps','value':layerId},
193 success: function(_data) {
194 if (_data.error != "ok") {
195 alert(_data.error);
196 } else {
197 if (_data.list.length > 0) {
198 show_dependencies_modal(layerId, layerName, layerURL, _data.list);
199 }
200 else {
201 tooltipUpdateText = "1 layer added";
202 _makeXHREditCall({ 'layerAdd': layerId }, function () {
203 show_alert("You have added <strong>1</strong> layer to <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>: <a href=\""+layerURL+"\">" + layerName +"</a>");
204 });
205 }
206 }
207 }
208 })
209}
140 210
141 $('#filtered').click(function() { 211function buttonSet(id, state) {
142 $(this).tooltip('hide'); 212 var tohide, toshow;
143 }); 213 if (state == "add")
214 {
215 toshow = "#layer-add-";
216 tohide = "#target-build-";
217 }
218 else if (state == "build")
219 {
220 tohide = "#layer-add-";
221 toshow = "#target-build-";
222 }
144 223
145 //show target added tooltip 224 var previouslyvisible = $(tohide + id).is(":visible");
146 $("#remove-target, #add-target, #add-target-with-deps2").tooltip({ trigger: 'manual' }); 225 if (previouslyvisible && id == pressedButton) {
147 226 $(tohide + id).fadeOut( function() {
148 // add target without dependencies 227 $("#layer-tooltip-" + id).text(tooltipUpdateText);
149 $("#add-target").click(function(){ 228 $("#layer-tooltip-" + id).fadeIn().delay(2000).fadeOut(function(){
150 $('#target-removed').hide(); 229 $(toshow + id).delay(300).fadeIn();
151 $('#target-added').html('<button type="button" class="close" data-dismiss="alert">&times;</button><strong>1</strong> target added to <a href="project-with-targets.html">your project</a>: <a href="#">meta-aarch64</a>').fadeIn();
152 $('#add-target').tooltip('show');
153 $("#add-target").hide();
154 $(".add-targets .tooltip").delay(2000).fadeOut(function(){
155 $("#remove-target").delay(300).fadeIn();
156 }); 230 });
157 }); 231 });
232 } else {
233 $(tohide + id).hide();
234 $("#layer-tooltip-" + id).hide();
235 $(toshow + id).show();
236 }
237};
158 238
159 // add target with dependencies
160 $(document).on("click", "#add-target-dependencies", function() {
161 $('#target-removed').hide();
162 $('#target-added').html('<button type="button" class="close" data-dismiss="alert">&times;</button><strong>3</strong> targets added to <a href="project-with-targets.html">your project</a>: <a href="#">meta-acer</a> and its dependencies <a href="#">meta-android</a> and <a href="#">meta-oe</a>').delay(400).fadeIn(function(){
163 $('#add-target-with-deps').tooltip('show');
164 $("#add-target-with-deps, #add-target-with-deps").hide();
165 $(".add-targets .tooltip").delay(2000).fadeOut(function(){
166 $("#remove-target-with-deps").delay(300).fadeIn();
167 });
168 });
169 });
170 239
171 // delete target 240function updateButtons(projectLayers) {
172 $("#remove-target").click(function(){ 241 var displayedLayers = [];
173 $('#target-added').hide(); 242 $(".add-layer").map(function () { displayedLayers.push( { "l": parseInt($(this).attr('layerversion_id')), "i": parseInt($(this).attr('value'))})});
174 $('#target-removed').show(); 243 for (var i=0; i < displayedLayers.length; i++) {
175 $('#remove-target').tooltip('show'); 244 if (projectLayers.indexOf(displayedLayers[i].l) > -1) {
176 $("#remove-target").hide(); 245 buttonSet(displayedLayers[i].i, "build");
177 $(".add-targets .tooltip").delay(2000).fadeOut(function(){ 246 }
178 $("#add-target").delay(300).fadeIn(); 247 else {
179 }); 248 buttonSet(displayedLayers[i].i, "add");
180 }); 249 }
250 }
251}
181 252
182 }); 253$(document).ready(function (){
254 updateButtons({{projectlayerset}});
255});
183 256
184</script> 257</script>
258{%endif%}
185 259
186{% endblock %} 260{% endblock %}