| {% extends "base.html" %} |
| {% load projecttags %} |
| {% load project_url_tag %} |
| {% load objects_to_dictionaries_filter %} |
| {% load humanize %} |
| {% load field_values_filter %} |
| {% block pagecontent %} |
| |
| <script> |
| var configVarUrl = "{% url 'configvars' build.id %}"; |
| |
| $(document).ready(function(){ |
| |
| $("#delete-build-confirm").click(function(){ |
| libtoaster.disableAjaxLoadingTimer(); |
| $(this).find('[data-role="submit-state"]').hide(); |
| $(this).find('[data-role="loading-state"]').show(); |
| $(this).attr("disabled", "disabled"); |
| |
| /* Make the modal non cancelable while delete is in progress */ |
| $('#delete-build-modal button[data-dismiss="modal"]').hide(); |
| |
| $.ajax({ |
| type: 'DELETE', |
| url: "{% url 'xhr_build' build.id %}", |
| headers: { 'X-CSRFToken' : $.cookie('csrftoken')}, |
| success: function (data) { |
| if (data.error !== "ok") { |
| console.warn(data.error); |
| } else { |
| libtoaster.setNotification("build-deleted", |
| $("#deleted-build-message").html()); |
| window.location.replace(data.gotoUrl); |
| } |
| }, |
| error: function (data) { |
| console.warn(data); |
| } |
| }); |
| }); |
| |
| |
| $('#breadcrumb > li').append('<span class="divider">→</span>'); |
| $('#breadcrumb > li:last').addClass("active"); |
| $('#breadcrumb > li:last > span').remove(); |
| |
| $("#build-menu li a").each(function(){ |
| /* Set the page active state in the Build menu */ |
| var currentUrl = window.location.href.split('?')[0]; |
| if (currentUrl === $(this).prop("href")){ |
| $(this).parent().addClass("active"); |
| } else { |
| /* Special case the configvar as this is part of configuration |
| * page but is a separate url |
| */ |
| if (window.location.pathname === configVarUrl){ |
| $("#menu-configuration").addClass("active"); |
| } else { |
| $(this).parent().removeClass("active"); |
| } |
| } |
| }); |
| }); |
| </script> |
| |
| <span style="display:none" id="deleted-build-message"> |
| 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> |
| </span> |
| |
| <div class="modal fade" tabindex="-1" role="dialog" id="delete-build-modal" style="display: none;" data-backdrop="static" data-keyboard="false"> |
| <div class="modal-dialog"> |
| <div class="modal-content"> |
| <div class="modal-body"> |
| <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> |
| </div> |
| <div class="modal-footer"> |
| <button id="delete-build-confirm" class="btn btn-primary btn-large"> |
| <span data-role="submit-state">Delete build</span> |
| <span data-role="loading-state" style="display:none"> |
| <span class="fa-pulse"> |
| <i class="icon-spinner"></i> |
| </span> |
| Deleting build... |
| </span> |
| </button> |
| <button type="button" class="btn btn-link" data-dismiss="modal">Cancel</button> |
| </div> |
| </div><!-- /.modal-content --> |
| </div><!-- /.modal-dialog --> |
| </div> <!-- / modal --> |
| |
| <div class="row"> |
| <!-- breadcrumbs --> |
| <div class="col-md-12"> |
| <ul class="breadcrumb" id="breadcrumb"> |
| <li><a href="{% project_url build.project %}">{{build.project.name}}</a></li> |
| {% if not build.project.is_default %} |
| <li><a href="{% url 'projectbuilds' build.project.id %}">Builds</a></li> |
| {% endif %} |
| <li> |
| {% block parentbreadcrumb %} |
| <a href="{%url 'builddashboard' build.pk%}"> |
| {{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"}}) |
| </a> |
| {% endblock %} |
| </li> |
| {% block localbreadcrumb %}{% endblock %} |
| </ul> |
| </div> |
| </div> |
| |
| <!-- begin left sidebar container for builds which started properly --> |
| {% if build.started %} |
| <div class="row"> |
| <div id="nav" class="col-md-2"> |
| <ul class="nav nav-pills nav-stacked" id="build-menu"> |
| <li id="menu-dashboard" |
| {% if request.resolver_match.url_name == 'builddashboard' %} |
| class="active" |
| {% endif %} > |
| <a href="{% url 'builddashboard' build.pk %}">Build summary</a> |
| </li> |
| {% if build.has_images and build.outcome == build.SUCCEEDED %} |
| <li class="nav-header" data-menu-heading="images">Images</li> |
| {% block nav-target %} |
| {% for t in build.get_sorted_target_list %} |
| {% if t.has_images %} |
| <li id="menu-{{t.target}}"><a href="{% url 'target' build.pk t.pk %}">{{t.target}}</a><li> |
| {% endif %} |
| {% endfor %} |
| {% endblock %} |
| {% endif %} |
| <li class="nav-header">Build</li> |
| <li id="menu-configuration"><a href="{% url 'configuration' build.pk %}">Configuration</a></li> |
| <li id="menu-tasks"><a href="{% url 'tasks' build.pk %}">Tasks</a></li> |
| <li id="menu-recipes"><a href="{% url 'recipes' build.pk %}">Recipes</a></li> |
| <li id="menu-packages"><a href="{% url 'packages' build.pk %}">Packages</a></li> |
| <li class="nav-header">Performance</li> |
| <li id="menu-time"><a href="{% url 'buildtime' build.pk %}">Time</a></li> |
| <li id="menu-cpu-time"><a href="{% url 'cputime' build.pk %}">CPU usage</a></li> |
| <li id="menu-disk-io"><a href="{% url 'diskio' build.pk %}">Disk I/O</a></li> |
| |
| <li class="nav-header">Actions</li> |
| <li id="menu-download-build-log"> |
| <a href="{% url 'build_artifact' build.id 'cookerlog' build.id %}"> |
| <span class="glyphicon glyphicon-download-alt"></span> |
| Download build log |
| </a> |
| </li> |
| |
| {% with build.get_custom_image_recipes as custom_image_recipes %} |
| {% if custom_image_recipes.count > 0 %} |
| <!-- edit custom image built during this build --> |
| <li id="menu-edit-custom-image"> |
| <a href="#" data-role="edit-custom-image-trigger"> |
| <span class="glyphicon glyphicon-edit"></span> |
| Edit custom image |
| </a> |
| {% include 'editcustomimage_modal.html' %} |
| <script> |
| var editableCustomImageRecipes = {{ custom_image_recipes | objects_to_dictionaries:"id,name" | json }}; |
| |
| $(document).ready(function () { |
| var editCustomImageTrigger = $('[data-role="edit-custom-image-trigger"]'); |
| var editCustomImageModal = $('#edit-custom-image-modal'); |
| |
| // edit custom image which was built during this build |
| editCustomImageTrigger.click(function () { |
| // single editable custom image: redirect to the edit page |
| // for that image |
| if (editableCustomImageRecipes.length === 1) { |
| var url = '{% url "customrecipe" build.project.id custom_image_recipes.first.id %}'; |
| document.location.href = url; |
| } |
| // multiple editable custom images: show modal to select |
| // one of them for editing |
| else { |
| editCustomImageModal.modal('show'); |
| } |
| }); |
| }); |
| </script> |
| </li> |
| {% endif %} |
| {% endwith %} |
| |
| <!-- new custom image from image recipe in this build --> |
| {% if build.has_image_recipes %} |
| <li id="menu-new-custom-image"> |
| <a href="#" data-role="new-custom-image-trigger"> |
| <span class="glyphicon glyphicon-plus"></span> |
| New custom image |
| </a> |
| {% include 'newcustomimage_modal.html' %} |
| <script> |
| // imageRecipes includes both custom image recipes and built-in |
| // image recipes, any of which can be used as the basis for a |
| // new custom image |
| var imageRecipes = {{ build.get_image_recipes | objects_to_dictionaries:"id,name" | json }}; |
| |
| $(document).ready(function () { |
| var newCustomImageModal = $('#new-custom-image-modal'); |
| var newCustomImageTrigger = $('[data-role="new-custom-image-trigger"]'); |
| |
| // show create new custom image modal to select an image built |
| // during this build as the basis for the custom recipe |
| newCustomImageTrigger.click(function () { |
| if (!imageRecipes.length) { |
| return; |
| } |
| |
| newCustomImageModalSetRecipes(imageRecipes); |
| newCustomImageModal.modal('show'); |
| }); |
| }); |
| </script> |
| {% endif %} |
| |
| <li id="menu-delete-build"> |
| <a href="#delete-build-modal" id="delete-build" data-toggle="modal" data-target="#delete-build-modal" class="text-danger"> |
| <span class="glyphicon glyphicon-trash"></span> |
| Delete build |
| </a> |
| </ul> |
| </div> |
| <!-- end left sidebar container --> |
| {% endif %} |
| |
| <!-- right container; need class="row" for builds without left-hand menu --> |
| <div{% if not build.started %} class="row"{% endif %}> |
| {% block buildinfomain %}{% endblock %} |
| </div> |
| </div> |
| {% endblock %} |