diff options
Diffstat (limited to 'bitbake/lib/toaster/toastergui/templates/project.html')
| -rw-r--r-- | bitbake/lib/toaster/toastergui/templates/project.html | 652 |
1 files changed, 320 insertions, 332 deletions
diff --git a/bitbake/lib/toaster/toastergui/templates/project.html b/bitbake/lib/toaster/toastergui/templates/project.html index c3a470c54a..9399b312ca 100644 --- a/bitbake/lib/toaster/toastergui/templates/project.html +++ b/bitbake/lib/toaster/toastergui/templates/project.html | |||
| @@ -1,366 +1,354 @@ | |||
| 1 | {% extends "base.html" %} | 1 | {% extends "baseprojectpage.html" %} |
| 2 | <!-- | ||
| 3 | vim: expandtab tabstop=2 | ||
| 4 | --> | ||
| 2 | {% load projecttags %} | 5 | {% load projecttags %} |
| 3 | {% load humanize %} | 6 | {% load humanize %} |
| 4 | {% block pagecontent %} | 7 | {% load static %} |
| 5 | |||
| 6 | <script> | ||
| 7 | |||
| 8 | var buildrequests = []; | ||
| 9 | |||
| 10 | function targetInPage(targetname) { | ||
| 11 | return targetname in $("ul#target-list > li > a").map(function (i, x) {return x.text}); | ||
| 12 | } | ||
| 13 | |||
| 14 | function setEventHandlers() { | ||
| 15 | $("i#del-target-icon").unbind().click(function (evt) { | ||
| 16 | console.log("del target", evt.target.attributes["x-data"].value); | ||
| 17 | postEditAjaxRequest({"targetDel": evt.target.attributes["x-data"].value}); | ||
| 18 | }); | ||
| 19 | $("button#add-target-button").unbind().click( function (evt) { | ||
| 20 | if ( $("input#target")[0].value.length == 0) { | ||
| 21 | alert("cannot add empty target"); | ||
| 22 | return; | ||
| 23 | } | ||
| 24 | postEditAjaxRequest({"targetAdd" : $("input#target")[0].value}); | ||
| 25 | }); | ||
| 26 | } | ||
| 27 | |||
| 28 | function onEditPageUpdate(data) { | ||
| 29 | // update targets | ||
| 30 | var i; var orightml = ""; | ||
| 31 | |||
| 32 | $("span#target-count").html(data.targets.length); | ||
| 33 | for (i = 0; i < data.targets.length; i++) { | ||
| 34 | if (! targetInPage(data.targets[i].target)) { | ||
| 35 | orightml += '<li><a href="#">'+data.targets[i].target; | ||
| 36 | if (data.targets[i].task != "" && data.targets[i].task !== null) { | ||
| 37 | orightml += " ("+data.targets[i].task+")"; | ||
| 38 | } | ||
| 39 | orightml += '</a><i title="" data-original-title="" class="icon-trash" id="del-target-icon" x-data="'+data.targets[i].pk+'"></i></li>'; | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | $("ul#target-list").html(orightml); | ||
| 44 | |||
| 45 | // update recent builds | ||
| 46 | |||
| 47 | setEventHandlers(); | ||
| 48 | } | ||
| 49 | |||
| 50 | function onEditAjaxSuccess(data, textstatus) { | ||
| 51 | console.log("XHR returned:", data, "(" + textstatus + ")"); | ||
| 52 | if (data.error != "ok") { | ||
| 53 | alert("error on request:\n" + data.error); | ||
| 54 | return; | ||
| 55 | } | ||
| 56 | onEditPageUpdate(data); | ||
| 57 | } | ||
| 58 | |||
| 59 | function onEditAjaxError(jqXHR, textstatus, error) { | ||
| 60 | alert("XHR errored:\n" + error + "\n(" + textstatus + ")"); | ||
| 61 | } | ||
| 62 | |||
| 63 | function postEditAjaxRequest(reqdata) { | ||
| 64 | var ajax = $.ajax({ | ||
| 65 | type:"POST", | ||
| 66 | data: $.param(reqdata), | ||
| 67 | url:"{% url 'xhr_projectedit' project.id%}", | ||
| 68 | headers: { 'X-CSRFToken': $.cookie("csrftoken")}, | ||
| 69 | success: onEditAjaxSuccess, | ||
| 70 | error: onEditAjaxError, | ||
| 71 | }) | ||
| 72 | } | ||
| 73 | |||
| 74 | |||
| 75 | |||
| 76 | |||
| 77 | $(document).ready(function () { | ||
| 78 | setEventHandlers(); | ||
| 79 | |||
| 80 | /* Provide XHR calls for the "build" buttons.*/ | ||
| 81 | $("button#build-all-button").click( function (evt) { | ||
| 82 | var ajax = $.ajax({ | ||
| 83 | type:"POST", | ||
| 84 | url:"{% url 'xhr_projectbuild' project.id %}", | ||
| 85 | headers: { 'X-CSRFToken': $.cookie("csrftoken")}, | ||
| 86 | success: function (data, textstatus) { | ||
| 87 | if (data.error != "ok") { | ||
| 88 | alert("XHR fail: " + data.error ); | ||
| 89 | } | ||
| 90 | }, | ||
| 91 | error: function (jqXHR, textstatus, error) { alert("XHR errored:" + error + "(" + textstatus + ")"); }, | ||
| 92 | }) | ||
| 93 | }); | ||
| 94 | }); | ||
| 95 | |||
| 96 | |||
| 97 | </script> | ||
| 98 | 8 | ||
| 99 | 9 | ||
| 100 | <div class="page-header"> | 10 | {% block projectinfomain %} |
| 101 | <h1> | 11 | <script src="{% static "js/angular.min.js" %}"></script> |
| 102 | {{project.name}} | 12 | <script src="{% static "js/angular-cookies.min.js" %}"></script> |
| 103 | {% if project.build_set.all.count == 0 %} | 13 | <script src="{% static "js/ui-bootstrap-tpls-0.11.0.js" %}"></script> |
| 104 | <small>No builds yet</small> | ||
| 105 | {% else %} | ||
| 106 | <small><a href="#">{{project.build_set.all.count}} builds</a></small> | ||
| 107 | {% endif %} | ||
| 108 | </h1> | ||
| 109 | </div> | ||
| 110 | 14 | ||
| 111 | 15 | ||
| 112 | <div class="well"> | 16 | <div id="main" role="main" ng-app="project" ng-controller="prjCtrl" class="top-padded"> |
| 113 | <form class="build-form"> | ||
| 114 | <div class="input-append input-prepend controls"> | ||
| 115 | <input type="text" class="huge span7" placeholder="Type the target(s) you want to build" autocomplete="off" data-minLength="1" data-autocomplete="off" | ||
| 116 | data-provide="typeahead" data-source='["core-image-base [meta | daisy]", | ||
| 117 | "core-image-clutter [meta | daisy]", | ||
| 118 | "core-image-directfb [meta | daisy]", | ||
| 119 | "core-image-myimage [meta-imported-layer | 3e1dbabbf3…]", | ||
| 120 | "core-image-anotherimage [meta-imported-layer | master]", | ||
| 121 | "core-image-full-cmdline [meta | daisy]", | ||
| 122 | "core-image-lsb [meta | daisy]", | ||
| 123 | "core-image-lsb-dev [meta | daisy]", | ||
| 124 | "core-image-lsb-sdk [meta| daisy]", | ||
| 125 | "core-image-minimal [meta| daisy]" | ||
| 126 | ]'> | ||
| 127 | <a href="#" id="build-button" class="btn btn-large btn-primary" disabled> | ||
| 128 | Build | ||
| 129 | <i class="icon-question-sign get-help heading-help" style="margin-left: 5px;" title="Type the name of one or more targets you want to build, separated by a space. You can also specify a task by appending a semicolon and a task name to a target name, like so: <code>core-image-minimal:do_build</code>"></i> | ||
| 130 | </a> | ||
| 131 | </div> | ||
| 132 | <p> | ||
| 133 | <a href="all-targets.html" style="padding-right: 5px;"> | ||
| 134 | View all targets | ||
| 135 | </a> | ||
| 136 | | | ||
| 137 | <a href="{% url 'projectbuilds' project.id%}" style="padding-left:5px;"> | ||
| 138 | View all project builds ({{project.build_set.count}}) | ||
| 139 | </a> | ||
| 140 | </form> | ||
| 141 | </div> | ||
| 142 | 17 | ||
| 143 | 18 | ||
| 19 | <!-- project name --> | ||
| 20 | <div class="page-header"> | ||
| 21 | <h1>{[project.name]}</h1> | ||
| 22 | </div> | ||
| 144 | 23 | ||
| 24 | <!-- alerts section 1--> | ||
| 25 | <div ng-repeat="a in zone1alerts"> | ||
| 26 | <div class="alert alert-dismissible lead" role="alert" ng-class="a.type"><button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span></button> | ||
| 27 | <span ng-bind-html="a.text"></span> | ||
| 28 | </div> | ||
| 29 | </div> | ||
| 145 | 30 | ||
| 31 | <!-- custom templates for ng --> | ||
| 146 | 32 | ||
| 147 | {% if builds|length > 0 or buildrequests|length > 0 %} | 33 | <script type="text/ng-template" id="suggestion_details"> |
| 148 | <h2 class="air">Recent Builds</h2> | 34 | <a> {[match.model.name]} {[match.model.detail]} </a> |
| 35 | </script> | ||
| 149 | 36 | ||
| 150 | <div id="scheduled-builds"> | 37 | <!-- modal dialogs --> |
| 151 | {% for br in buildrequests %} | 38 | <script type="text/ng-template" id="dependencies_modal"> |
| 152 | <div class="alert {% if br.0.state == br.0.REQ_FAILED%}alert-error{%else%}alert-info{%endif%}" id="build-request"> | 39 | <div class="modal-header"> |
| 153 | <div class="row-fluid"> | 40 | <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button> |
| 154 | <div class="lead span4"> | 41 | <h3><span ng-bind="layerAddName"></span> dependencies</h3> |
| 155 | <span> | 42 | </div> |
| 156 | {{br.0.brtarget_set.all.0.target}} {%if br.brtarget_set.all.count > 1%}(+ {{br.brtarget_set.all.count|add:"-1"}}){%endif%} {{br.1.machine.value}} (Created {{br.0.created}}) | 43 | <div class="modal-body"> |
| 157 | </span> | 44 | <p><strong>{[layerAddName]}</strong> depends on some layers that are not added to your project. Select the ones you want to add:</p> |
| 45 | <ul class="unstyled"> | ||
| 46 | <li ng-repeat="ld in items"> | ||
| 47 | <label class="checkbox"> | ||
| 48 | <input type="checkbox" ng-model="selectedItems[ld.id]"> {[ld.name]} | ||
| 49 | </label> | ||
| 50 | </li> | ||
| 51 | </ul> | ||
| 52 | </div> | ||
| 53 | <div class="modal-footer"> | ||
| 54 | <button class="btn btn-primary" ng-click="ok()">Add layers</button> | ||
| 55 | <button class="btn" ng-click="cancel()">Cancel</button> | ||
| 56 | </div> | ||
| 57 | </form> | ||
| 58 | </script> | ||
| 59 | |||
| 60 | |||
| 61 | <script type="text/ng-template" id="change_version_modal"> | ||
| 62 | <div class="modal-header"> | ||
| 63 | <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button> | ||
| 64 | <h3>Changing release to {[releaseName]}</h3> | ||
| 65 | </div> | ||
| 66 | <div class="modal-body"> | ||
| 67 | <p>The following project layers do not exist for {[releaseName]}:</p> | ||
| 68 | <ul> | ||
| 69 | <li ng-repeat="i in items"><span class="layer-info" data-toggle="tooltip" tooltip="{[i.detail]}">{[i.name]}</span></li> | ||
| 70 | </ul> | ||
| 71 | <p>If you change the release to {[releaseName]}, the above layers will be deleted from your project layers.</p> | ||
| 72 | </div> | ||
| 73 | <div class="modal-footer"> | ||
| 74 | <button class="btn btn-primary" ng-click="ok()">Change release and delete layers</button> | ||
| 75 | <button class="btn" ng-click="cancel()">Cancel</button> | ||
| 76 | </div> | ||
| 77 | </script> | ||
| 78 | |||
| 79 | <!-- build form --> | ||
| 80 | <div class="well"> | ||
| 81 | <form class="build-form" ng-submit="targetNamedBuild()"> | ||
| 82 | <div class="input-append input-prepend controls"> | ||
| 83 | <input type="text" class="huge span7 " placeholder="Type the target(s) you want to build" autocomplete="off" ng-model="targetName" typeahead="e.name for e in getSuggestions('targets', $viewValue)|filter:$viewValue" typeahead-template-url="suggestion_details" ng-disabled="!layers.length"/> | ||
| 84 | <button type="submit" id="build-button" class="btn btn-large btn-primary" ng-disabled="!targetName.length"> | ||
| 85 | Build | ||
| 86 | <i class="icon-question-sign get-help heading-help" style="margin-left: 5px;" data-toggle="tooltip" title="Type the name of one or more targets you want to build, separated by a space. You can also specify a task by appending a semicolon and a task name to a target name, like so: <code>core-image-minimal:do_build</code>"></i> | ||
| 87 | </button> | ||
| 88 | </div> | ||
| 89 | <p> | ||
| 90 | <a href="{% url 'targets' %}" style="padding-right: 5px;"> | ||
| 91 | View all targets | ||
| 92 | </a> | ||
| 93 | {% if completedbuilds.count %} | ||
| 94 | | <a href="{% url 'projectbuilds' project.id %}">View all project builds ({{completedbuilds.count}})</a> | ||
| 95 | {% endif %} | ||
| 96 | </p> | ||
| 97 | </form> | ||
| 98 | </div> | ||
| 99 | |||
| 100 | <h2 class="air" ng-if="builds.length">Latest builds</h2> | ||
| 101 | |||
| 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]"> | ||
| 103 | <div class="row-fluid"> | ||
| 104 | <switch ng-switch="b.status"> | ||
| 105 | <case ng-switch-when="failed"> | ||
| 106 | <div class="lead span3"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div> | ||
| 107 | <div class="row-fluid"> | ||
| 108 | <div class="air well" ng-repeat="e in b.errors"> | ||
| 109 | {[e.type]}: <pre>{[e.msg]}</pre> | ||
| 110 | </div> | ||
| 111 | </div> | ||
| 112 | </case> | ||
| 113 | <case ng-switch-when="queued"> | ||
| 114 | <div class="lead span5"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div> | ||
| 115 | <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> | ||
| 117 | </div> | ||
| 118 | <button class="btn pull-right btn-info" ng-click="buildCancel(b.id)">Cancel</button> | ||
| 119 | </case> | ||
| 120 | <case ng-switch-when="created"> | ||
| 121 | <div class="lead span3"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div> | ||
| 122 | <div class="span6" > | ||
| 123 | <span class="lead">Creating build</span> | ||
| 158 | </div> | 124 | </div> |
| 159 | <div class="span2"> | 125 | <button class="btn pull-right btn-info" ng-click="buildCancel(b.id)">Cancel</button> |
| 160 | {{br.0.get_state_display}} | 126 | </case> |
| 127 | <case ng-switch-when="deleted"> | ||
| 128 | <div class="lead span3"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div> | ||
| 129 | <div class="span6" id="{[b.id]}-deleted" > | ||
| 130 | <span class="lead">Build deleted</span> | ||
| 161 | </div> | 131 | </div> |
| 162 | <div class="span8"> | 132 | <button class="btn pull-right btn-info" ng-click="builds.splice(builds.indexOf(b), 1)">Close</button> |
| 163 | {% if br.state == br.REQ_FAILED%} | 133 | </case> |
| 164 | {% for bre in br.0.brerror_set.all %} {{bre.errmsg}} ({{bre.errtype}}) <br/><hr/><code>{{bre.traceback}}</code>{%endfor%} | 134 | <case ng-switch-when="in progress"> |
| 165 | {%endif%} | 135 | <div class="lead span3"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div> |
| 136 | <div class="span4" > | ||
| 166 | </div> | 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" > | ||
| 142 | <div class="progress" style="margin-top:5px;" data-toggle="tooltip" tooltip="{[b.completeper]}% of tasks complete"> | ||
| 143 | <div style="width: {[b.completeper]}%;" class="bar"></div> | ||
| 144 | </div> | ||
| 145 | </div> | ||
| 146 | <div class="lead pull-right">ETA: at {[b.eta]}</div> | ||
| 147 | </case> | ||
| 148 | <case ng-switch-default=""> | ||
| 149 | <div class="lead span3"><a href="{[b.build_page_url]}"><span ng-repeat="t in b.targets">{[t.target]} </span> </div></a> | ||
| 150 | <div class="span2 lead"> | ||
| 151 | {[b.completed_on|date:'dd/MM/yy HH:mm']} | ||
| 152 | </div> | ||
| 153 | <div class="span2"><span>{[b.errors.len]}</span></div> | ||
| 154 | <div class="span2"><span>{[b.warnings.len]}</span></div> | ||
| 155 | <div> <span class="lead">Build time: {[b.build_time|date:"HH:mm"]}</span> | ||
| 156 | <button class="btn pull-right" ng-class="{'Succeeded': 'btn-success', 'Failed': 'btn-danger'}[b.status]" | ||
| 157 | ng-click="targetExistingBuild(b.targets)">Run again</button> | ||
| 167 | 158 | ||
| 168 | </div> | 159 | </div> |
| 169 | </div> | 160 | </case> |
| 161 | </switch> | ||
| 162 | <div class="lead pull-right"> | ||
| 163 | </div> | ||
| 164 | </div> | ||
| 165 | </div> | ||
| 170 | 166 | ||
| 171 | {% endfor %} | 167 | <h2 class="air">Project configuration</h2> |
| 172 | 168 | ||
| 169 | <!-- alerts section 2 --> | ||
| 170 | <div ng-repeat="a in zone2alerts"> | ||
| 171 | <div class="alert alert-dismissible lead" role="alert" ng-class="a.type"><button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span></button> | ||
| 172 | <span ng-bind-html="a.text"></span> | ||
| 173 | </div> | ||
| 174 | </div> | ||
| 175 | |||
| 176 | <div class="row-fluid"> | ||
| 177 | |||
| 178 | <!-- project layers --> | ||
| 179 | <div id="layer-container" class="well well-transparent span4"> | ||
| 180 | <h3> | ||
| 181 | Project layers <span class="muted counter">({[layers.length]})</span> | ||
| 182 | <i class="icon-question-sign get-help heading-help" title="OpenEmbedded organises metadata into modules called 'layers'. Layers allow you to isolate different types of customizations from each other. <a href='http://www.yoctoproject.org/docs/current/dev-manual/dev-manual.html#understanding-and-creating-layers' target='_blank'>More on layers</a>"></i> | ||
| 183 | </h3> | ||
| 184 | <div class="alert" ng-if="!layers.length"> | ||
| 185 | <b>You need to add some layers </b> | ||
| 186 | <p> | ||
| 187 | You can: | ||
| 188 | <ul> | ||
| 189 | <li> <a href="{% url 'layers'%}">View all layers available in Toaster</a> | ||
| 190 | <li> <a href="{% url 'importlayer' %}">Import a layer</a> | ||
| 191 | <li> <a href="https://www.yoctoproject.org/docs/1.6.1/dev-manual/dev-manual.html#understanding-and-creating-layers" target="_blank">Read about layers in the manual</a> | ||
| 192 | </ul> | ||
| 193 | Or type a layer name below. | ||
| 194 | </p> | ||
| 195 | </div> | ||
| 196 | <form class="input-append" ng-submit="layerAdd()"> | ||
| 197 | <input type="text" class="input-xlarge" id="layer" autocomplete="off" placeholder="Type a layer name" data-minLength="1" ng-model="layerAddName" typeahead="e.name for e in getSuggestions('layers', $viewValue)|filter:$viewValue" typeahead-template-url="suggestion_details" typeahead-on-select="onLayerSelect($item, $model, $label)" typeahead-editable="false" ng-class="{ 'has-error': layerAddName.$invalid }" /> | ||
| 198 | <input type="submit" id="add-layer" class="btn" value="Add" ng-disabled="!layerAddName.length"/> | ||
| 199 | {% csrf_token %} | ||
| 200 | </form> | ||
| 201 | <p><a href="{% url 'layers' %}">View all layers</a> | <a href="{% url 'importlayer' %}">Import layer</a></p> | ||
| 202 | <ul class="unstyled configuration-list"> | ||
| 203 | <li ng-repeat="l in layers"> | ||
| 204 | <a href="{[l.layerdetailurl]}" target="_#" class="layer-info" data-toggle="tooltip" tooltip="{[l.branch.layersource]} | {[l.branch.name]}">{[l.name]} </a> | ||
| 205 | <i class="icon-trash" ng-click="layerDel(l.id)" tooltip="Delete"></i> | ||
| 206 | </li> | ||
| 207 | </ul> | ||
| 173 | </div> | 208 | </div> |
| 174 | 209 | ||
| 175 | 210 | ||
| 211 | <!-- project targets --> | ||
| 212 | <div id="target-container" class="well well-transparent span4"> | ||
| 213 | <h3> | ||
| 214 | Targets | ||
| 215 | <i class="icon-question-sign get-help heading-help" title="What you build, often a recipe producing a root file system file (an image). Something like <code>core-image-minimal</code> or <code>core-image-sato</code>"></i> | ||
| 216 | </h3> | ||
| 217 | <form ng-submit="targetNamedBuild()" class="input-append"> | ||
| 218 | <input type="text" class="input-xlarge" placeholder="Type the target(s) you want to build" autocomplete="off" data-minLength="1" ng-model="targetName" typeahead="e.name for e in getSuggestions('targets', $viewValue)|filter:$viewValue" typeahead-template-url="suggestion_details" ng-disabled="!layers.length"> | ||
| 219 | <button type="submit" id="build-button" class="btn btn-primary" ng-disabled="!targetName.length"> | ||
| 220 | Build </button> | ||
| 221 | {% csrf_token %} | ||
| 222 | </form> | ||
| 223 | <p><a href="{% url 'targets' %}">View all targets</a></p> | ||
| 224 | <div ng-if="frequenttargets.length"> | ||
| 225 | <h4> | ||
| 226 | Most built targets | ||
| 227 | </h4> | ||
| 228 | <ul class="unstyled configuration-list"> | ||
| 229 | <li ng-repeat="t in frequenttargets"> | ||
| 230 | <label class="checkbox"> | ||
| 231 | <input type="checkbox" ng-model="mostBuiltTargets[t]">{[t]} | ||
| 232 | </label> | ||
| 233 | </li> | ||
| 234 | </ul> | ||
| 235 | <button class="btn btn-large btn-primary" ng-disabled="selectedMostBuildTargets()">Build selected targets</button> | ||
| 236 | </div> | ||
| 237 | </div> | ||
| 176 | 238 | ||
| 177 | <!-- Lifted from build.html --> | 239 | <!-- project configuration --> |
| 178 | {% for build in builds %} | 240 | <div id="machine-distro" class="well well-transparent span4"> |
| 179 | <div class="alert {%if build.outcome == build.SUCCEEDED%}alert-success{%elif build.outcome == build.FAILED%}alert-error{%else%}alert-info{%endif%}"> | 241 | <h3> |
| 180 | <div class="row-fluid"> | 242 | Project machine |
| 181 | <div class="lead span5"> | 243 | <i class="icon-question-sign get-help heading-help" title="The machine is the hardware for which you want to build. You can only set one machine per project"></i> |
| 182 | {%if build.outcome == build.SUCCEEDED%}<i class="icon-ok-sign success"></i>{%elif build.outcome == build.FAILED%}<i class="icon-minus-sign error"></i>{%else%}{%endif%} | 244 | </h3> |
| 183 | {%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %} | 245 | <p class="lead" id="select-machine-opposite"> |
| 184 | <a href="{%url 'builddashboard' build.pk%}" class="{%if build.outcome == build.SUCCEEDED %}success{%else%}error{%endif%}"> | 246 | {[machine.name]}<i id="change-machine" class="icon-pencil" ng-click="toggle('#select-machine')" tooltip="Change"></i> |
| 185 | {% endif %} | 247 | </p> |
| 186 | <span data-toggle="tooltip" {%if build.target_set.all.count > 1%}title="Targets: {%for target in build.target_set.all%}{{target.target}} {%endfor%}"{%endif%}>{{build.target_set.all.0.target}} {%if build.target_set.all.count > 1%}(+ {{build.target_set.all.count|add:"-1"}}){%endif%} {{build.machine}} ({{build.completed_on|naturaltime}})</span> | 248 | <div id="select-machine" style="display: none"> |
| 187 | {%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %} | 249 | <div class="alert alert-info"> |
| 188 | </a> | 250 | <strong>Machine changes have a big impact on build outcome.</strong> |
| 189 | {% endif %} | 251 | You cannot really compare the builds for the new machine with the previous ones. |
| 190 | </div> | ||
| 191 | {%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %} | ||
| 192 | <div class="span2 lead"> | ||
| 193 | {% if build.errors_no %} | ||
| 194 | <i class="icon-minus-sign red"></i> <a href="{%url 'builddashboard' build.pk%}#errors" class="error">{{build.errors_no}} error{{build.errors_no|pluralize}}</a> | ||
| 195 | {% endif %} | ||
| 196 | </div> | ||
| 197 | <div class="span2 lead"> | ||
| 198 | {% if build.warnings_no %} | ||
| 199 | <i class="icon-warning-sign yellow"></i> <a href="{%url 'builddashboard' build.pk%}#warnings" class="warning">{{build.warnings_no}} warning{{build.warnings_no|pluralize}}</a> | ||
| 200 | {% endif %} | ||
| 201 | </div > | ||
| 202 | <div class="lead pull-right"> | ||
| 203 | Build time: <a href="{% url 'buildtime' build.pk %}">{{ build.timespent|sectohms }}</a> | ||
| 204 | </div> | ||
| 205 | {%endif%}{%if build.outcome == build.IN_PROGRESS %} | ||
| 206 | <div class="span4"> | ||
| 207 | <div class="progress" style="margin-top:5px;" data-toggle="tooltip" title="{{build.completeper}}% of tasks complete"> | ||
| 208 | <div style="width: {{build.completeper}}%;" class="bar"></div> | ||
| 209 | </div> | ||
| 210 | </div> | ||
| 211 | <div class="lead pull-right">ETA: in {{build.eta|naturaltime}}</div> | ||
| 212 | {%endif%} | ||
| 213 | </div> | 252 | </div> |
| 253 | <form ng-submit="edit('#select-machine')" class="input-append"> | ||
| 254 | <input type="text" id="machine" autocomplete="off" ng-model="machineName" typeahead="m.name for m in getSuggestions('machines', $viewValue)"/> | ||
| 255 | <input type="submit" id="apply-change-machine" class="btn" type="button" ng-disabled="machineName == machine.name || machineName.length == 0" value="Save"></input> | ||
| 256 | <input type="reset" id="cancel-machine" class="btn btn-link" ng-click="toggle('#select-machine')" value="Cancel"></input> | ||
| 257 | {% csrf_token %} | ||
| 258 | </form> | ||
| 259 | <p><a href="{% url 'machines' %}" class="link">View all machines</a></p> | ||
| 260 | </div> | ||
| 261 | <p class="link-action"> | ||
| 262 | <a href="{% url 'projectconf' project.id %}" class="link">Edit configuration variables</a> | ||
| 263 | <i data-original-title="You can set other project configuration options here. Each option, like everything else in the build system, is a variable - value pair" class="icon-question-sign get-help heading-help" title=""></i> | ||
| 264 | </p> | ||
| 214 | </div> | 265 | </div> |
| 215 | {% endfor %} | 266 | </div> |
| 216 | <!-- end of lift--> | ||
| 217 | {%endif%} | ||
| 218 | 267 | ||
| 219 | <h2 class="air">Project configuration</h2> | ||
| 220 | 268 | ||
| 221 | <div class="row-fluid"> | 269 | <h2>Project details</h2> |
| 222 | 270 | ||
| 223 | <div id="layer-container" class="well well-transparent span4"> | 271 | <!-- alerts section 3 --> |
| 224 | <h3> | 272 | <div ng-repeat="a in zone3alerts"> |
| 225 | Add layers | 273 | <div class="alert alert-dismissible lead" role="alert" ng-class="a.type"><button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span></button> |
| 226 | <i data-original-title="OpenEmbedded organises metadata into modules called 'layers'. Layers allow you to isolate different types of customizations from each other. <a href='http://www.yoctoproject.org/docs/1.6.1/dev-manual/dev-manual.html#understanding-and-creating-layers' target='_blank'>More on layers</a>" class="icon-question-sign get-help heading-help" title=""></i> | 274 | <span ng-bind-html="a.text"></span> |
| 227 | </h3> | 275 | </div> |
| 228 | <form style="margin-top:20px;"> | 276 | </div> |
| 229 | <div class="input-append"> | 277 | |
| 230 | <input class="input-xlarge" id="layer" autocomplete="off" placeholder="Type a layer name" data-provide="typeahead" data-source="" data-minlength="1" data-autocomplete="off" type="text"> | 278 | |
| 231 | <button id="add-layer" class="btn" disabled="">Add</button> | 279 | <div id="project-details" class="well well-transparent"> |
| 232 | </div> | 280 | <h3>Project name</h3> |
| 233 | <div id="import-alert" class="alert alert-info" style="display:none;"> | 281 | <p class="lead" id="change-project-name-opposite"> |
| 234 | Toaster does not know about this layer. Please <a href="#">import it</a> | 282 | <span >{[project.name]}</span> |
| 235 | </div> | 283 | <i class="icon-pencil" ng-click="toggle('#change-project-name')" tooltip="Change"></i> |
| 236 | <div id="dependency-alert" class="alert alert-info" style="display:none;"> | 284 | </p> |
| 237 | <p><strong>meta-tizen</strong> depends on the layers below. Check the ones you want to add: </p> | 285 | <div id="change-project-name" style="display:none;"> |
| 238 | <ul class="unstyled"> | 286 | <form ng-submit="edit('#change-project-name')" class="input-append"> |
| 239 | {% for f in layer_dependency %} | 287 | <input type="text" class="input-xlarge" id="type-project-name" ng-model="projectName"> |
| 240 | <li> | 288 | <input type="submit" class="btn" value="Save" ng-disabled="project.name == projectName"/> |
| 241 | <label class="checkbox"> | 289 | <input type="reset" class="btn btn-link" value="Cancel" ng-click="toggle('#change-project-name')"> |
| 242 | <input checked="checked" type="checkbox"> | 290 | </form> |
| 243 | meta-ruby | 291 | </div> |
| 244 | </label> | ||
| 245 | </li> | ||
| 246 | {% endfor %} | ||
| 247 | </ul> | ||
| 248 | <button id="add-layer-dependencies" class="btn btn-info add-layer">Add layers</button> | ||
| 249 | </div> | ||
| 250 | |||
| 251 | <p><a href="{% url 'importlayer' %}">Import your layer</a> | <a href="{% url 'layers'%}">View all layers</a></p> | ||
| 252 | </form> | ||
| 253 | |||
| 254 | <h4 class="air"> | ||
| 255 | Added layers | ||
| 256 | <span class="muted counter">{{project.projectlayer_set.count}}</span> | ||
| 257 | <i data-original-title="Your added layers will be listed in this same order in your <code>bblayers.conf</code> file" class="icon-question-sign get-help heading-help" title=""></i> | ||
| 258 | </h4> | ||
| 259 | <ul class="unstyled configuration-list"> | ||
| 260 | {% for pl in project.projectlayer_set.all %} | ||
| 261 | <li> | ||
| 262 | <a href="#">{{pl.layercommit.layer.name}} (<span class="layer-version">{{pl.layercommit.layer.layer_index_url}}</span>)</a> | ||
| 263 | {% if pl.optional %} | ||
| 264 | <i title="" data-original-title="" class="icon-trash" id="del-layer-icon" x-data="{{pl.pk}}"></i> | ||
| 265 | {% endif %} | ||
| 266 | </li> | ||
| 267 | {% endfor %} | ||
| 268 | </ul> | ||
| 269 | </div> | ||
| 270 | 292 | ||
| 271 | <div id="target-container" class="well well-transparent span4"> | ||
| 272 | <h3> | ||
| 273 | Add targets | ||
| 274 | <i data-original-title="A target is what you want to build, usually an image recipe that produces a root file system" class="icon-question-sign get-help heading-help" title=""></i> | ||
| 275 | </h3> | ||
| 276 | <form style="margin-top:20px;"> | ||
| 277 | <div class="input-append"> | ||
| 278 | <input id="target" class="input-xlarge" autocomplete="off" placeholder="Type a target name" data-provide="typeahead" data-source="" data-minlength="1" data-autocomplete="off" type="text"> | ||
| 279 | <button id="add-target-button" class="btn" type="button">Add</button> | ||
| 280 | </div> | ||
| 281 | |||
| 282 | <p><a href="{% url 'targets' %}" class="link">View all targets</a></p> | ||
| 283 | </form> | ||
| 284 | <h4 class="air"> | ||
| 285 | Added targets | ||
| 286 | <span id="target-count" class="muted counter">{{project.projecttarget_set.count}}</span> | ||
| 287 | </h4> | ||
| 288 | <ul class="unstyled configuration-list" id="target-list"> | ||
| 289 | {% for target in project.projecttarget_set.all %} | ||
| 290 | {% if target %} | ||
| 291 | <li> | ||
| 292 | <a href="#">{{target.target}}{% if target.task%} (target.task){%endif%}</a> | ||
| 293 | {% if target.notprovided %} | ||
| 294 | <i title="" data-original-title="" id="msg1" class="icon-exclamation-sign get-help-yellow" data-title="<strong>Target may not be provided</strong>" data-content="From the layer information it currently has, Toaster thinks this target is not provided by any of your added layers. If a target is not provided by one of your added layers, the build will fail.<h5>What Toaster suggests</h5><p>The <a href='#'>meta-abc</a> and <a href='#'>meta-efg</a> layers provide core-image-notprovided. You could add one of them to your project.</p><button class='btn btn-block'>Add meta-abc</button><button class='btn btn-block'>Add meta-efg</button><button id='dismiss1' class='btn btn-block btn-info'>Stop showing this message</button>"></i> | ||
| 295 | {% elif target.notknown %} | ||
| 296 | <i title="" data-original-title="" id="msg2" class="icon-exclamation-sign get-help-yellow" data-title="<strong>Target may not be provided</strong>" data-content="From the layer information it currently has, Toaster thinks this target is not provided by any of your added layers. If a target is not provided by one of your added layers, the build will fail.<h5>What Toaster suggests</h5><p>Review your added layers to make sure one of them provides core-image-unknown. Clicking on a layer name will give you all the information Toaster has about the layer. </p> <button class='btn btn-block btn-info'>Stop showing this message</button>"></i> | ||
| 297 | {% endif %} | ||
| 298 | <i title="" data-original-title="" class="icon-trash" id="del-target-icon" x-data="{{target.pk}}"></i> | ||
| 299 | </li> | ||
| 300 | {% endif %} | ||
| 301 | {% endfor %} | ||
| 302 | |||
| 303 | |||
| 304 | </ul> | ||
| 305 | </div> | ||
| 306 | 293 | ||
| 307 | <div class="well well-transparent span4"> | 294 | <h3> |
| 308 | 295 | Release | |
| 309 | <h3> | 296 | <i class="icon-question-sign get-help heading-help" title="The version of the build system you want to use"></i> |
| 310 | Project machine | 297 | </h3> |
| 311 | <i class="icon-question-sign get-help heading-help" title="The machine is the hardware for which you want to build. You can only set one machine per project"></i> | 298 | <p class="lead" id="change-project-version-opposite"> |
| 312 | </h3> | 299 | <span id="project-version">{[project.release.name]}</span> |
| 313 | <p class="lead" id="selected-machine"> {{machine}} | 300 | <i id="change-version" class="icon-pencil" ng-click="toggle('#change-project-version')" tooltip="Change"></i> |
| 314 | <i id="change-machine" class="icon-pencil"></i> | 301 | </p> |
| 315 | </p> | 302 | <div class="div-inline" id="change-project-version" style="display:none;"> |
| 316 | <form id="select-machine"> | 303 | <form ng-submit="test('#change-project-version')" class="input-append"> |
| 317 | <div class="alert alert-info"> | 304 | <select id="select-version" ng-model="projectVersion"> |
| 318 | <strong>Machine changes have a big impact on build outcome.</strong> | 305 | <option ng-repeat="r in releases" value="{[r.id]}" ng-selected="r.id == project.release.id">{[r.name]}</option> |
| 319 | You cannot really compare the builds for the new machine with the previous ones. | 306 | </select> |
| 320 | </div> | 307 | <input type="submit" class="btn" style="margin-left:5px;" value="Save" ng-disabled="project.release.id == projectVersion"/> |
| 321 | <div class="input-append"> | 308 | <input type="reset" class="btn btn-link" value="Cancel" ng-click="toggle('#change-project-version')" ng-disabled="project.release.id == projectVersion"/> |
| 322 | <input type="text" id="machine" autocomplete="off" value="qemux86" data-provide="typeahead" | 309 | |
| 323 | data-minLength="1" | 310 | </form> |
| 324 | data-autocomplete="off" | 311 | </div> |
| 325 | data-source='[ | 312 | </div> |
| 326 | ]'> | ||
| 327 | <button id="apply-change-machine" class="btn" type="button">Save</button> | ||
| 328 | <a href="#" id="cancel-machine" class="btn btn-link">Cancel</a> | ||
| 329 | </div> | ||
| 330 | <p><a href="{% url 'machines' %}" class="link">View all machines</a></p> | ||
| 331 | </form> | ||
| 332 | <p class="link-action"> | ||
| 333 | <a href="{% url 'projectconf' project.id %}" class="link">Edit configuration variables</a> | ||
| 334 | <i class="icon-question-sign get-help heading-help" title="You can set other project configuration options here. Each option, like everything else in the build system, is a variable - value pair"></i> | ||
| 335 | </p> | ||
| 336 | 313 | ||
| 337 | </div> | 314 | <!-- end main --> |
| 315 | </div> | ||
| 338 | 316 | ||
| 339 | 317 | ||
| 340 | </div> | 318 | <!-- load application logic !--> |
| 319 | <script src="{% static "js/projectapp.js" %}"></script> | ||
| 320 | |||
| 321 | <!-- dump initial data for use in the angular app --> | ||
| 322 | <script> | ||
| 323 | angular.element(document).ready(function() { | ||
| 324 | scope = angular.element("#main").scope(); | ||
| 325 | scope.urls = {}; | ||
| 326 | scope.urls.xhr_build = "{% url 'xhr_projectbuild' project.id %}"; | ||
| 327 | scope.urls.xhr_edit = "{% url 'xhr_projectedit' project.id %}"; | ||
| 328 | scope.urls.xhr_datatypeahead = "{% url 'xhr_datatypeahead' %}"; | ||
| 329 | scope.urls.layers = "{% url 'layers' %}"; | ||
| 330 | scope.urls.targets = "{% url 'targets' %}"; | ||
| 331 | scope.urls.importlayer = "{% url 'importlayer'%}" | ||
| 332 | scope.project = {{prj|safe}}; | ||
| 333 | scope.builds = {{builds|safe}}; | ||
| 334 | scope.layers = {{layers|safe}}; | ||
| 335 | scope.targets = {{targets|safe}}; | ||
| 336 | scope.frequenttargets = {{freqtargets|safe}}; | ||
| 337 | scope.machine = {{machine|safe}}; | ||
| 338 | scope.releases = {{releases|safe}}; | ||
| 339 | |||
| 340 | scope.zone1alerts = []; | ||
| 341 | scope.zone2alerts = []; | ||
| 342 | scope.zone3alerts = []; | ||
| 343 | |||
| 344 | scope.mostBuiltTargets = {}; | ||
| 345 | |||
| 346 | scope.executeCommands(); | ||
| 347 | scope.validateData(); | ||
| 348 | |||
| 349 | scope.$digest(); | ||
| 350 | |||
| 351 | }); | ||
| 352 | </script> | ||
| 341 | 353 | ||
| 342 | <h2>Project details</h2> | ||
| 343 | |||
| 344 | <div class="well well-transparent"> | ||
| 345 | <h3>Project name</h3> | ||
| 346 | <p class="lead"> | ||
| 347 | {{project.name}} | ||
| 348 | <i title="" data-original-title="" class="icon-pencil"></i> | ||
| 349 | </p> | ||
| 350 | <h3>Project owner</h3> | ||
| 351 | <p class="lead"> | ||
| 352 | {{puser.username}} | ||
| 353 | <i title="" data-original-title="" class="icon-pencil"></i> | ||
| 354 | </p> | ||
| 355 | <h3>Owner's email</h3> | ||
| 356 | <p class="lead"> | ||
| 357 | {{puser.email}} | ||
| 358 | <i title="" data-original-title="" class="icon-pencil"></i> | ||
| 359 | </p> | ||
| 360 | <h3>Yocto Project version</h3> | ||
| 361 | <p class="lead"> | ||
| 362 | {{project.release.name}} - {{project.release.description}} | ||
| 363 | <i title="" data-original-title="" class="icon-pencil"></i> | ||
| 364 | </p> | ||
| 365 | </div> | ||
| 366 | {% endblock %} | 354 | {% endblock %} |
