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