1{% extends "base.html" %} 2{% load projecttags %} 3{% load project_url_tag %} 4{% load objects_to_dictionaries_filter %} 5{% load humanize %} 6{% load field_values_filter %} 7{% block pagecontent %} 8 9 <script> 10 var configVarUrl = "{% url 'configvars' build.id %}"; 11 12 $(document).ready(function(){ 13 14 $("#delete-build-confirm").click(function(){ 15 libtoaster.disableAjaxLoadingTimer(); 16 $(this).find('[data-role="submit-state"]').hide(); 17 $(this).find('[data-role="loading-state"]').show(); 18 $(this).attr("disabled", "disabled"); 19 20 /* Make the modal non cancelable while delete is in progress */ 21 $('#delete-build-modal button[data-dismiss="modal"]').hide(); 22 23 $.ajax({ 24 type: 'DELETE', 25 url: "{% url 'xhr_build' build.id %}", 26 headers: { 'X-CSRFToken' : $.cookie('csrftoken')}, 27 success: function (data) { 28 if (data.error !== "ok") { 29 console.warn(data.error); 30 } else { 31 libtoaster.setNotification("build-deleted", 32 $("#deleted-build-message").html()); 33 window.location.replace(data.gotoUrl); 34 } 35 }, 36 error: function (data) { 37 console.warn(data); 38 } 39 }); 40 }); 41 42 43 $('#breadcrumb > li').append('<span class="divider">→</span>'); 44 $('#breadcrumb > li:last').addClass("active"); 45 $('#breadcrumb > li:last > span').remove(); 46 47 $("#build-menu li a").each(function(){ 48 /* Set the page active state in the Build menu */ 49 var currentUrl = window.location.href.split('?')[0]; 50 if (currentUrl === $(this).prop("href")){ 51 $(this).parent().addClass("active"); 52 } else { 53 /* Special case the configvar as this is part of configuration 54 * page but is a separate url 55 */ 56 if (window.location.pathname === configVarUrl){ 57 $("#menu-configuration").addClass("active"); 58 } else { 59 $(this).parent().removeClass("active"); 60 } 61 } 62 }); 63 }); 64 </script> 65 66<span style="display:none" id="deleted-build-message"> 67 You have deleted 1 build: <strong>{{build.get_sorted_target_list|field_values:"target"|join:", "}} {{build.machine}}</strong> completed on <strong>{{build.completed_on|date:"d/m/y H:i"}}</strong> 68</span> 69 70<div class="modal fade" tabindex="-1" role="dialog" id="delete-build-modal" style="display: none;" data-backdrop="static" data-keyboard="false"> 71 <div class="modal-dialog"> 72 <div class="modal-content"> 73 <div class="modal-body"> 74 <p>Are you sure you want to delete the build <strong>{{build.get_sorted_target_list|field_values:"target"|join:", "}} {{build.machine}}</strong> completed on <strong>{{build.completed_on|date:"d/m/y H:i"}}</strong>?</p> 75 </div> 76 <div class="modal-footer"> 77 <button id="delete-build-confirm" class="btn btn-primary btn-large"> 78 <span data-role="submit-state">Delete build</span> 79 <span data-role="loading-state" style="display:none"> 80 <span class="fa-pulse"> 81 <i class="icon-spinner"></i> 82 </span> 83 Deleting build... 84 </span> 85 </button> 86 <button type="button" class="btn btn-link" data-dismiss="modal">Cancel</button> 87 </div> 88 </div><!-- /.modal-content --> 89 </div><!-- /.modal-dialog --> 90</div> <!-- / modal --> 91 92<div class="row"> 93 <!-- breadcrumbs --> 94 <div class="col-md-12"> 95 <ul class="breadcrumb" id="breadcrumb"> 96 <li><a href="{% project_url build.project %}">{{build.project.name}}</a></li> 97 {% if not build.project.is_default %} 98 <li><a href="{% url 'projectbuilds' build.project.id %}">Builds</a></li> 99 {% endif %} 100 <li> 101 {% block parentbreadcrumb %} 102 <a href="{%url 'builddashboard' build.pk%}"> 103 {{build.get_sorted_target_list.0.target}} {% if build.target_set.all.count > 1 %}(+{{build.target_set.all.count|add:"-1"}}){% endif %} {{build.machine}} ({{build.completed_on|date:"d/m/y H:i"}}) 104 </a> 105 {% endblock %} 106 </li> 107 {% block localbreadcrumb %}{% endblock %} 108 </ul> 109 </div> 110</div> 111 112 <!-- begin left sidebar container for builds which started properly --> 113 {% if build.started %} 114 <div class="row"> 115 <div id="nav" class="col-md-2"> 116 <ul class="nav nav-pills nav-stacked" id="build-menu"> 117 <li id="menu-dashboard" 118 {% if request.resolver_match.url_name == 'builddashboard' %} 119 class="active" 120 {% endif %} > 121 <a href="{% url 'builddashboard' build.pk %}">Build summary</a> 122 </li> 123 {% if build.has_images and build.outcome == build.SUCCEEDED %} 124 <li class="nav-header" data-menu-heading="images">Images</li> 125 {% block nav-target %} 126 {% for t in build.get_sorted_target_list %} 127 {% if t.has_images %} 128 <li id="menu-{{t.target}}"><a href="{% url 'target' build.pk t.pk %}">{{t.target}}</a><li> 129 {% endif %} 130 {% endfor %} 131 {% endblock %} 132 {% endif %} 133 <li class="nav-header">Build</li> 134 <li id="menu-configuration"><a href="{% url 'configuration' build.pk %}">Configuration</a></li> 135 <li id="menu-tasks"><a href="{% url 'tasks' build.pk %}">Tasks</a></li> 136 <li id="menu-recipes"><a href="{% url 'recipes' build.pk %}">Recipes</a></li> 137 <li id="menu-packages"><a href="{% url 'packages' build.pk %}">Packages</a></li> 138 <li class="nav-header">Performance</li> 139 <li id="menu-time"><a href="{% url 'buildtime' build.pk %}">Time</a></li> 140 <li id="menu-cpu-time"><a href="{% url 'cputime' build.pk %}">CPU usage</a></li> 141 <li id="menu-disk-io"><a href="{% url 'diskio' build.pk %}">Disk I/O</a></li> 142 143 <li class="nav-header">Actions</li> 144 <li id="menu-download-build-log"> 145 <a href="{% url 'build_artifact' build.id 'cookerlog' build.id %}"> 146 <span class="glyphicon glyphicon-download-alt"></span> 147 Download build log 148 </a> 149 </li> 150 151 {% with build.get_custom_image_recipes as custom_image_recipes %} 152 {% if custom_image_recipes.count > 0 %} 153 <!-- edit custom image built during this build --> 154 <li id="menu-edit-custom-image"> 155 <a href="#" data-role="edit-custom-image-trigger"> 156 <span class="glyphicon glyphicon-edit"></span> 157 Edit custom image 158 </a> 159 {% include 'editcustomimage_modal.html' %} 160 <script> 161 var editableCustomImageRecipes = {{ custom_image_recipes | objects_to_dictionaries:"id,name" | json }}; 162 163 $(document).ready(function () { 164 var editCustomImageTrigger = $('[data-role="edit-custom-image-trigger"]'); 165 var editCustomImageModal = $('#edit-custom-image-modal'); 166 167 // edit custom image which was built during this build 168 editCustomImageTrigger.click(function () { 169 // single editable custom image: redirect to the edit page 170 // for that image 171 if (editableCustomImageRecipes.length === 1) { 172 var url = '{% url "customrecipe" build.project.id custom_image_recipes.first.id %}'; 173 document.location.href = url; 174 } 175 // multiple editable custom images: show modal to select 176 // one of them for editing 177 else { 178 editCustomImageModal.modal('show'); 179 } 180 }); 181 }); 182 </script> 183 </li> 184 {% endif %} 185 {% endwith %} 186 187 <!-- new custom image from image recipe in this build --> 188 {% if build.has_image_recipes %} 189 <li id="menu-new-custom-image"> 190 <a href="#" data-role="new-custom-image-trigger"> 191 <span class="glyphicon glyphicon-plus"></span> 192 New custom image 193 </a> 194 {% include 'newcustomimage_modal.html' %} 195 <script> 196 // imageRecipes includes both custom image recipes and built-in 197 // image recipes, any of which can be used as the basis for a 198 // new custom image 199 var imageRecipes = {{ build.get_image_recipes | objects_to_dictionaries:"id,name" | json }}; 200 201 $(document).ready(function () { 202 var newCustomImageModal = $('#new-custom-image-modal'); 203 var newCustomImageTrigger = $('[data-role="new-custom-image-trigger"]'); 204 205 // show create new custom image modal to select an image built 206 // during this build as the basis for the custom recipe 207 newCustomImageTrigger.click(function () { 208 if (!imageRecipes.length) { 209 return; 210 } 211 212 newCustomImageModalSetRecipes(imageRecipes); 213 newCustomImageModal.modal('show'); 214 }); 215 }); 216 </script> 217 {% endif %} 218 219 <li id="menu-delete-build"> 220 <a href="#delete-build-modal" id="delete-build" data-toggle="modal" data-target="#delete-build-modal" class="text-danger"> 221 <span class="glyphicon glyphicon-trash"></span> 222 Delete build 223 </a> 224 </ul> 225 </div> 226 <!-- end left sidebar container --> 227 {% endif %} 228 229 <!-- right container; need class="row" for builds without left-hand menu --> 230 <div{% if not build.started %} class="row"{% endif %}> 231 {% block buildinfomain %}{% endblock %} 232 </div> 233 </div> 234{% endblock %} 235