diff options
Diffstat (limited to 'yocto-poky/bitbake/lib/toaster/toastergui/templates')
58 files changed, 5876 insertions, 0 deletions
diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/base.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/base.html new file mode 100644 index 000000000..640bc47bc --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/base.html @@ -0,0 +1,182 @@ +<!DOCTYPE html> +{% load static %} +{% load projecttags %} +<html lang="en"> + <head> + <title>{% if objectname %} {{objectname|title}} - {% endif %}Toaster</title> +<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}" type="text/css"/> +<link rel="stylesheet" href="{% static 'css/bootstrap-responsive.min.css' %}" type='text/css'/> +<link rel="stylesheet" href="{% static 'css/font-awesome.min.css' %}" type='text/css'/> +<link rel="stylesheet" href="{% static 'css/prettify.css' %}" type='text/css'/> +<link rel="stylesheet" href="{% static 'css/default.css' %}" type='text/css'/> + + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> + <script src="{% static 'js/jquery-2.0.3.min.js' %}"> + </script> + <script src="{% static 'js/jquery.cookie.js' %}"> + </script> + <script src="{% static 'js/bootstrap.min.js' %}"> + </script> + <script src="{% static 'js/prettify.js' %}"> + </script> + <script src="{% static 'js/libtoaster.js' %}"> + </script> + {% if DEBUG %} + <script> + libtoaster.debug = true; + </script> + {% endif %} + <script> + libtoaster.ctx = { + jsUrl : "{% static 'js/' %}", + htmlUrl : "{% static 'html/' %}", + projectsUrl : "{% url 'all-projects' %}", + projectsTypeAheadUrl: {% url 'xhr_projectstypeahead' as prjurl%}{{prjurl|json}}, + {% if project.id %} + projectId : {{project.id}}, + projectPageUrl : {% url 'project' project.id as purl%}{{purl|json}}, + projectName : {{project.name|json}}, + recipesTypeAheadUrl: {% url 'xhr_recipestypeahead' project.id as paturl%}{{paturl|json}}, + layersTypeAheadUrl: {% url 'xhr_layerstypeahead' project.id as paturl%}{{paturl|json}}, + machinesTypeAheadUrl: {% url 'xhr_machinestypeahead' project.id as paturl%}{{paturl|json}}, + + projectBuildsUrl: {% url 'projectbuilds' project.id as pburl %}{{pburl|json}}, + projectId : {{project.id}}, + {% else %} + projectId : undefined, + projectPageUrl : undefined, + projectName : undefined, + projectId : undefined, + {% endif %} + }; + </script> + <script src="{% static 'js/base.js' %}"></script> + <script> + $(document).ready(function () { + /* Vars needed for base.js */ + var ctx = {}; + ctx.numProjects = {{projects|length}}; + ctx.currentUrl = "{{request.path|escapejs}}"; + + basePageInit(ctx); + }); + </script> + +{% block extraheadcontent %} +{% endblock %} + </head> + +<body style="height: 100%"> + + {% csrf_token %} + <div id="loading-notification" class="alert lead text-center" style="display:none"> + Loading <i class="fa-pulse icon-spinner"></i> + </div> + + <div id="change-notification" class="alert lead alert-info" style="display:none"> + <button type="button" class="close" id="hide-alert">×</button> + <span id="change-notification-msg"></span> + </div> + + <div class="navbar navbar-fixed-top"> + <div class="navbar-inner"> + <div class="container-fluid"> + <a class="brand logo" href="#"><img src="{% static 'img/logo.png' %}" class="" alt="Yocto logo project"/></a> + <span class="brand"> + <a href="/">Toaster</a> + {% if DEBUG %} + <i class="icon-info-sign" title="<strong>Toaster version information</strong>" data-content="<dl><dt>Branch</dt><dd>{{TOASTER_BRANCH}}</dd><dt>Revision</dt><dd>{{TOASTER_REVISION}}</dd></dl>"></i> + {% endif %} + </span> + {% if request.resolver_match.url_name != 'landing' and request.resolver_match.url_name != 'newproject' %} + <ul class="nav"> + <li {% if request.resolver_match.url_name == 'all-builds' %} + class="active" + {% endif %}> + <a href="{% url 'all-builds' %}"> + <i class="icon-tasks"></i> + All builds + </a> + </li> + <li {% if request.resolver_match.url_name == 'all-projects' %} + class="active" + {% endif %}> + <a href="{% url 'all-projects' %}"> + <i class="icon-folder-open"></i> + All projects + </a> + </li> + </ul> + {% endif %} + <ul class="nav pull-right"> + <li> + <a target="_blank" href="http://www.yoctoproject.org/docs/latest/toaster-manual/toaster-manual.html"> + <i class="icon-book"></i> + Manual + </a> + </li> + </ul> + <span class="pull-right divider-vertical"></span> + <div class="btn-group pull-right"> + <a class="btn" id="new-project-button" href="{% url 'newproject' %}">New project</a> + </div> + <!-- New build popover --> + <div class="btn-group pull-right" id="new-build-button" style="display:none"> + <button class="btn dropdown-toggle" data-toggle="dropdown"> + New build + <i class="icon-caret-down"></i> + </button> + <ul class="dropdown-menu new-build multi-select"> + <li> + <h3>New build</h3> + <h6>Project:</h6> + <span id="project"> + {% if project.id %} + <a class="lead" href="{% url 'project' project.id %}">{{project.name}}</a> + {% else %} + <a class="lead" href="#"></a> + {% endif %} + <i class="icon-pencil"></i> + </span> + <form id="change-project-form" style="display:none;"> + <div class="input-append"> + <input type="text" class="input-medium" id="project-name-input" placeholder="Type a project name" autocomplete="off" data-minLength="1" data-autocomplete="off" data-provide="typeahead"/> + <button id="save-project-button" class="btn" type="button">Save</button> + <a href="#" id="cancel-change-project" class="btn btn-link" style="display: none">Cancel</a> + </div> + <p><a id="view-all-projects" href="{% url 'all-projects' %}">View all projects</a></p> + </form> + </li> + <li> + <div class="alert" style="display:none;"> + <p>This project configuration is incomplete, so you cannot run builds.</p> + <p><a href="{% if project.id %}{% url 'project' project.id %}{% endif %}">View project configuration</a></p> + </div> + </li> + <li id="targets-form"> + <h6>Recipe(s):</h6> + <form> + <input type="text" class="input-xlarge build-target-input" placeholder="Type a recipe name" autocomplete="off" data-minLength="1" data-autocomplete="off" data-provide="typeahead" disabled/> + <div class="row-fluid"> + <button class="btn btn-primary build-button" disabled>Build</button> + </div> + </form> + </li> + </ul> + </div> + + + </div> + </div> +</div> + +<div class="container-fluid top-padded"> +<div class="row-fluid"> +{% block pagecontent %} +{% endblock %} +</div> +</div> +</body> +</html> + diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/basebuilddetailpage.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/basebuilddetailpage.html new file mode 100644 index 000000000..22ca50c0c --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/basebuilddetailpage.html @@ -0,0 +1,29 @@ +{% extends "base.html" %} +{% load humanize %} +{% block pagecontent %} + +<div class="row-fluid"> +<!-- Breadcrumbs --> + <div class="section"> + <ul class="breadcrumb" id="breadcrumb"> + <li class="muted">{{build.project.name}}:</li> + <li><a href="{% url 'projectbuilds' build.project.id %}">Builds</a></li> + <li><a href="{%url 'builddashboard' build.pk%}">{{build.target_set.all.0.target}} {%if build.target_set.all.count > 1%}(+ {{build.target_set.all.count|add:"-1"}}){%endif%} ({{build.completed_on|date:"d/m/y H:i"}})</a></li> + {% block localbreadcrumb %}{% endblock %} + </ul> + <script> + $( function () { + $('#breadcrumb > li').append('<span class="divider">→</span>'); + $('#breadcrumb > li:last').addClass("active"); + $('#breadcrumb > li:last > span, #breadcrumb > li:first > span').remove(); + }); + </script> + </div> <!--section--> + + <!-- Begin container --> + {% block pagedetailinfomain %}{% endblock %} + <!-- End container --> + +</div> + +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/basebuildpage.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/basebuildpage.html new file mode 100644 index 000000000..d441df84e --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/basebuildpage.html @@ -0,0 +1,88 @@ +{% extends "base.html" %} +{% load projecttags %} +{% load humanize %} +{% block pagecontent %} + + + <div class=""> +<!-- Breadcrumbs --> + <div class="section"> + <ul class="breadcrumb" id="breadcrumb"> + <li class="muted">{{build.project.name}}:</li> + <li><a href="{% url 'projectbuilds' build.project.id %}">Builds</a></li> + <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.completed_on|date:"d/m/y H:i"}}) + </a> + {% endblock %} + </li> + {% block localbreadcrumb %}{% endblock %} + </ul> + <script> + $( function () { + $('#breadcrumb > li').append('<span class="divider">→</span>'); + $('#breadcrumb > li:last').addClass("active"); + $('#breadcrumb > li:last > span, #breadcrumb > li:first > span').remove(); + console.log("done"); + }); + </script> + </div> + + <div class="row-fluid"> + + <!-- begin left sidebar container --> + <div id="nav" class="span2"> + <ul class="nav nav-list well"> + <li + {% if request.resolver_match.url_name == 'builddashboard' %} + class="active" + {% endif %} > + <a class="nav-parent" href="{% url 'builddashboard' build.pk %}">Build summary</a> + </li> + {% if build.target_set.all.0.is_image and build.outcome == 0 %} + <li class="nav-header">Images</li> + {% block nav-target %} + {% for t in build.get_sorted_target_list %} + <li><a href="{% url 'target' build.pk t.pk %}">{{t.target}}</a><li> + {% endfor %} + {% endblock %} + {% endif %} + <li class="nav-header">Build</li> + {% block nav-configuration %} + <li><a href="{% url 'configuration' build.pk %}">Configuration</a></li> + {% endblock %} + {% block nav-tasks %} + <li><a href="{% url 'tasks' build.pk %}">Tasks</a></li> + {% endblock %} + {% block nav-recipes %} + <li><a href="{% url 'recipes' build.pk %}">Recipes</a></li> + {% endblock %} + {% block nav-packages %} + <li><a href="{% url 'packages' build.pk %}">Packages</a></li> + {% endblock %} + <li class="nav-header">Performance</li> + {% block nav-buildtime %} + <li><a href="{% url 'buildtime' build.pk %}">Time</a></li> + {% endblock %} + {% block nav-cpuusage %} + <li><a href="{% url 'cpuusage' build.pk %}">CPU usage</a></li> + {% endblock %} + {% block nav-diskio %} + <li><a href="{% url 'diskio' build.pk %}">Disk I/O</a></li> + {% endblock %} + </ul> + </div> + <!-- end left sidebar container --> + + <!-- Begin right container --> + {% block buildinfomain %}{% endblock %} + <!-- End right container --> + + + </div> + </div> + + +{% endblock %} + diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/baseprojectbuildspage.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/baseprojectbuildspage.html new file mode 100644 index 000000000..229cd17ba --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/baseprojectbuildspage.html @@ -0,0 +1,15 @@ +{% extends "base.html" %} +{% load projecttags %} +{% load humanize %} +{% block pagecontent %} + +{% include "projecttopbar.html" %} + +<!-- Begin main page container --> +<div> + {% block projectinfomain %}{% endblock %} +</div> +<!-- End main container --> + +{% endblock %} + diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/baseprojectpage.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/baseprojectpage.html new file mode 100644 index 000000000..668e0bf5e --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/baseprojectpage.html @@ -0,0 +1,40 @@ +{% extends "base.html" %} +{% load projecttags %} +{% load humanize %} +{% block pagecontent %} + +{% include "projecttopbar.html" %} +<script type="text/javascript"> + $(document).ready(function(){ + $("#config-nav .nav li a").each(function(){ + if (window.location.pathname === $(this).attr('href')) + $(this).parent().addClass('active'); + else + $(this).parent().removeClass('active'); + }); + + $("#topbar-configuration-tab").addClass("active") + }); +</script> + +<div class="row-fluid"> + <!-- only on config pages --> + <div id="config-nav" class="span2"> + <ul class="nav nav-list well"> + <li><a class="nav-parent" href="{% url 'project' project.id %}">Configuration</a></li> + <li class="nav-header">Compatible metadata</li> +<!-- <li><a href="all-image-recipes.html">Image recipes</a></li> --> + <li><a href="{% url 'projecttargets' project.id %}">Recipes</a></li> + <li><a href="{% url 'projectmachines' project.id %}">Machines</a></li> + <li><a href="{% url 'projectlayers' project.id %}">Layers</a></li> + <li class="nav-header">Extra configuration</li> + <li><a href="{% url 'projectconf' project.id %}">BitBake variables</a></li> + </ul> + </div> + <div class="span10"> + {% block projectinfomain %}{% endblock %} + </div> +</div> + +{% endblock %} + diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html new file mode 100644 index 000000000..ce023f51a --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html @@ -0,0 +1,94 @@ + </tbody> + </table> + +<!-- Show pagination controls --> +<div class="pagination pagination-centered"> + <div class="pull-left"> + Showing {{objects.start_index}} to {{objects.end_index}} out of {{objects.paginator.count}} entries. + </div> + + <ul class="pagination" style="display: block-inline"> +{%if objects.has_previous %} + <li><a href="javascript:reload_params({'page':{{objects.previous_page_number}}})">«</a></li> +{%else%} + <li class="disabled"><a href="#">«</a></li> +{%endif%} +{% for i in objects.page_range %} + <li{%if i == objects.number %} class="active" {%endif%}><a href="javascript:reload_params({'page':{{i}}})">{{i}}</a></li> +{% endfor %} +{%if objects.has_next%} + <li><a href="javascript:reload_params({'page':{{objects.next_page_number}}})">»</a></li> +{%else%} + <li class="disabled"><a href="#">»</a></li> +{%endif%} + </ul> + <div class="pull-right"> + <span class="help-inline" style="padding-top:5px;">Show rows:</span> + <select style="margin-top:5px;margin-bottom:0px;" class="pagesize"> + {% with "10 25 50 100 150" as list%} + {% for i in list.split %} + <option value="{{i}}">{{i}}</option> + {% endfor %} + {% endwith %} + </select> + </div> +</div> + +<!-- Update page display settings --> + +<script> + $(document).ready(function() { + + // we load cookies for the column display + save = $.cookie('_displaycols_{{objectname}}'); + if (save != undefined) { + setting = save.split(';'); + for ( i = 0; i < setting.length; i++) { + if (setting[i].length > 0) { + splitlist = setting[i].split(':'); + id = splitlist[0], v = splitlist[1]; + if (v == 'true') { + $('.chbxtoggle#'+id).prop('checked', true); + } + else { + $('.chbxtoggle#'+id).prop('checked', false); + } + } + } + } + + // load data for number of entries to be displayed on page + if ({{request.GET.count}} != "") { + pagesize = {{request.GET.count}}; + } + + $('.pagesize option').prop('selected', false) + .filter('[value="' + pagesize + '"]') + .attr('selected', true); + + $('.chbxtoggle').each(function () { + showhideTableColumn($(this).attr('id'), $(this).is(':checked')) + }); + + //turn edit columns dropdown into a multi-select menu + $('.dropdown-menu input, .dropdown-menu label').click(function(e) { + e.stopPropagation(); + }); + + //show tooltip with applied filter + $('#filtered').tooltip({container:'table', placement:'bottom', delay:{hide:1500}, html:true}); + + //progress bar tooltip + $('.progress, .lead span').tooltip({container:'table', placement:'top'}); + + $(".pagesize").change(function () { + reload_params({"count":$(this).val()}); + }); +}); +</script> + +<!-- modal filter boxes --> + {% for tc in tablecols %}{% if tc.filter %}{% with objectname=objectname f=tc.filter %} + {% include "filtersnippet.html" %} + {% endwith %}{% endif %} {% endfor %} +<!-- end modals --> diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/basetable_top.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/basetable_top.html new file mode 100644 index 000000000..33ede6687 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/basetable_top.html @@ -0,0 +1,239 @@ +{% load projecttags %} +<!-- component to display a generic table --> + <script> + + // + // most of the following javascript is for managing the 'Edit Columns' + // pop-up dialog and actions. the idea is that there are 2 types + // of actions: immediate - performed while the dialog is still + // visible - hide/show columns, and delayed - performed when the + // dialog becomes invisible - any resorting if necessary. + // + // When the dialog is open, an interval timer is set up to + // determine if the dialog is still visible. when the dialog + // closes - goes invisible, the delayed actions are performed. + // + // the interval timer and interrupt handler is a way of simulating + // an onclose event. there is probably a simpler way to do this + // however the pop-up window id was elusive. + // + + var editColTimer; + var editColAction; + + // + // this is the target function of the interval timeout. + // check to see if the dialog is visible. if the dialog + // has gone invisible since the last check, take any delayed + // actions indicated in the action list and clear the timer. + // + + function checkVisible( ) { + editcol = document.getElementById( 'editcol' ); + if ( editcol.offsetWidth <= 0 ) { + clearInterval( editColTimer ); + editColTimer = false; + hideshowColumns( ); + editColAction = [ ]; + } + } + + function filterTableRows(test) { + if (test.length > 0) { + var r = test.split(/[ ,]+/).map(function (e) { return new RegExp(e, 'i') }); + $('tr.data').map( function (i, el) { + (! r.map(function (j) { return j.test($(el).html())}).reduce(function (c, p) { return c && p;} )) ? $(el).hide() : $(el).show(); + }); + } else + { + $('tr.data').show(); + } + } + + // + // determine the value of the indicated url arg. + // this is needed to determine whether a resort + // is necessary. it looks like a lot of gorp stuff + // but its actually pretty simple. + // + + function getURLParameter( name ) { + return decodeURIComponent((new RegExp('[?|&]' + name + '=' + + '([^&;]+?)(&|#|;|$)').exec(location.search)||[,""])[1].replace(/\+/g, + '%20'))||null + } + + // + // when the dialog box goes invisible + // this function is called to interpret + // the action list and take any delayed actions necessary. + // the editColAction list is a hash table with + // the column name as the hash key, the hash value + // is a 2 element list. the first element is a flag + // indicating whether the column is on or off. the + // 2nd element is the sort order indicator for the column. + // + + function hideshowColumns( ) { + for( var k in editColAction ) { + showhideDelayedTableAction( k, editColAction[ k ][ 0 ], editColAction[ k ][ 1 ]); + } + } + + // + // this function actually performs the delayed table actions + // namely any resorting if necessary + // + + function showhideDelayedTableAction( clname, sh, orderkey ) { + if ( !sh ) { + p = getURLParameter( "orderby" ).split( ":" )[ 0 ]; + if ( p == orderkey ) { + reload_params({ 'orderby' : '{{default_orderby}}'}); + } + } + } + + // + // this function actually performs the immediate table actions + // namely any colums that need to be hidden/shown + // + + function showhideImmediateTableAction( clname, sh, orderkey ) { + if ( sh ) { + $( '.' + clname ).show( 100 ); + } + else { + $( '.' + clname ).hide( 100 ); + } + + // save cookie for all checkboxes + save = ''; + $( '.chbxtoggle' ).each(function( ) { + if ( $( this ).attr( 'id' ) != undefined ) { + save += ';' + $( this ).attr( 'id' ) +':'+ $( this ).is( ':checked' ) + } + }); + $.cookie( '_displaycols_{{objectname}}', save ); + save = ''; + } + + // + // this is the onclick handler for all of the check box + // items in edit columns dialog + // + + function showhideTableColumn( clname, sh, orderkey ) { + editcol = document.getElementById( 'editcol' ); + if ( editcol.offsetWidth <= 0 ) { + + // + // this path is taken when the page is first + // getting initialized - no dialog visible, + // perform both the immediate and delayed actions + // + + showhideImmediateTableAction( clname, sh, orderkey ); + showhideDelayedTableAction( clname, sh, orderkey ); + return; + } + if ( !editColTimer ) { + + // + // we don't have a timer active so set one up + // and clear the action list + // + + editColTimer = setInterval( checkVisible, 250 ); + editColAction = [ ]; + } + + // + // save the action to be taken when the dialog closes + // + + editColAction[ clname ] = [ sh, orderkey ]; + showhideImmediateTableAction( clname, sh, orderkey ); + } + + </script> + +<!-- control header --> +<div class="navbar"> + <div class="navbar-inner"> + <form class="navbar-search input-append pull-left" id="searchform"> + <input class="input-xxlarge" id="search" name="search" type="text" placeholder="Search {%if object_search_display %}{{object_search_display}}{%else%}{{objectname}}{%endif%}" value="{%if request.GET.search %}{{request.GET.search}}{% endif %}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{%endif%} + <input type="hidden" name="orderby" value="{{request.GET.orderby}}"> + <input type="hidden" name="page" value="1"> + <button class="btn" id="search-button" type="submit" value="Search">Search</button> + </form> + <div class="pull-right"> +{% if tablecols %} + <div class="btn-group"> + <button id="edit-columns-button" class="btn dropdown-toggle" data-toggle="dropdown">Edit columns + <span class="caret"></span> + </button> +<!-- + {{tablecols|sortcols}} +--> + <ul id='editcol' class="dropdown-menu"> + {% for i in tablecols|sortcols %} + <li> + <label {% if not i.clclass %} class="checkbox muted" {%else%} class="checkbox" {%endif%}> + <input type="checkbox" class="chbxtoggle" + {% if i.clclass %} + id="{{i.clclass}}" + value="ct{{i.name}}" + {% if not i.hidden %} + checked="checked" + {%endif%} + onclick="showhideTableColumn( + $(this).attr('id'), + $(this).is(':checked'), + {% if i.ordericon %} + '{{i.orderkey}}' + {% else %} + undefined + {% endif %} + )" + {%else%} + checked disabled + {% endif %}/> {{i.name}} + </label> + </li> + {% endfor %} + </ul> + </div> +{% endif %} + <div style="display:inline"> + <span class="divider-vertical"></span> + <span class="help-inline" style="padding-top:5px;">Show rows:</span> + <select style="margin-top:5px;margin-bottom:0px;" class="pagesize"> + {% with "10 25 50 100 150" as list%} + {% for i in list.split %} + <option value="{{i}}">{{i}}</option> + {% endfor %} + {% endwith %} + </select> + </div> + </div> + </div> <!-- navbar-inner --> +</div> + +<!-- the actual rows of the table --> + <table class="table table-bordered table-hover tablesorter" id="otable"> + <thead> + <!-- Table header row; generated from "tablecols" entry in the context dict --> + <tr> + {% for tc in tablecols %}<th class="{%if tc.dclass%}{{tc.dclass}}{%endif%} {% if tc.clclass %}{{tc.clclass}}{% endif %}"> + {%if tc.qhelp%}<i class="icon-question-sign get-help" title="{{tc.qhelp}}"></i>{%endif%} + {%if tc.orderfield%}<a {%if tc.ordericon%} class="sorted" {%endif%}href="javascript:reload_params({'page': 1, 'orderby' : '{{tc.orderfield}}' })">{{tc.name}}</a>{%else%}<span class="muted">{{tc.name}}</span>{%endif%} + {%if tc.ordericon%} <i class="icon-caret-{{tc.ordericon}}"></i>{%endif%} + {%if tc.filter%}<div class="btn-group pull-right"> + <a href="#filter_{{tc.filter.class}}" role="button" class="btn btn-mini {%if request.GET.filter%}{{tc.filter.options|filtered_icon:request.GET.filter}} {%endif%}" {%if request.GET.filter and tc.filter.options|filtered_tooltip:request.GET.filter %} title="<p>{{tc.filter.options|filtered_tooltip:request.GET.filter}}</p><p><a class='btn btn-small btn-primary' href=javascript:reload_params({'filter':''})>Show all {% if filter_search_display %}{{filter_search_display}}{% else %}{{objectname}}{% endif %}</a></p>" {%endif%} data-toggle="modal"> <i class="icon-filter filtered"></i> </a> + </div>{%endif%} + </th>{% endfor %} + </tr> + </thead> + <tbody> + diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/basetable_top_layers.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/basetable_top_layers.html new file mode 100644 index 000000000..722091b2d --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/basetable_top_layers.html @@ -0,0 +1,5 @@ +{% extends "basetable_top.html" %} + +{%block custombuttons %} + <a class="btn" href="{% url 'importlayer' project.id %}" style="margin-right:5px;">Import layer</a> +{%endblock%} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/bfile.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/bfile.html new file mode 100644 index 000000000..c7f59434a --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/bfile.html @@ -0,0 +1,24 @@ +{% extends "basebuildpage.html" %} + +{% block pagetitle %}Files for package {{objects.0.bpackage.name}} {% endblock %} +{% block pagetable %} + {% if not objects %} + <p>No files were recorded for this package!</p> + {% else %} + + <tr> + <th>Name</th> + <th>Size (Bytes)</th> + </tr> + + {% for file in objects %} + + <tr class="data"> + <td>{{file.path}}</td> + <td>{{file.size}}</td> + + {% endfor %} + + {% endif %} + +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/bpackage.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/bpackage.html new file mode 100644 index 000000000..d775fec73 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/bpackage.html @@ -0,0 +1,107 @@ +{% extends "basebuildpage.html" %} + +{% load projecttags %} + +{% block localbreadcrumb %} +<li>Packages</li> +{% endblock %} + +{% block nav-packages %} + <li class="active"><a href="{% url 'packages' build.pk %}">Packages</a></li> +{% endblock %} + +{% block buildinfomain %} +<div class="span10"> + +{% if not request.GET.filter and not request.GET.search and not objects.paginator.count %} + +<!-- Empty - no data in database --> +<div class="page-header"> + <h1> + Packages + </h1> +</div> +<div class="alert alert-info lead"> + <strong>No packages were built.</strong> How did this happen? Well, BitBake reuses as much stuff as possible. + If all of the packages needed were already built and available in your build infrastructure, BitBake + will not rebuild any of them. This might be slightly confusing, but it does make everything faster. +</div> + +{% else %} + +<div class="page-header"> + <h1> + {% if request.GET.search and objects.paginator.count > 0 %} + {{objects.paginator.count}} package{{objects.paginator.count|pluralize}} found + {%elif request.GET.search and objects.paginator.count == 0%} + No packages found + {%else%} + Packages + {%endif%} + </h1> +</div> + + {% if objects.paginator.count == 0 %} + <div class="row-fluid"> + <div class="alert"> + <form class="no-results input-append" id="searchform"> + <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 %} + <button class="btn" type="submit" value="Search">Search</button> + <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all packages</button> + </form> + </div> + </div> + + {% else %} + {% include "basetable_top.html" %} + + {% for package in objects %} + + <tr class="data"> + + <!-- Package --> + <td class="package_name"><a href="{% url "package_built_detail" build.pk package.pk %}">{{package.name}}</a></td> + <!-- Package Version --> + <td class="package_version">{%if package.version%}<a href="{% url "package_built_detail" build.pk package.pk %}">{{package.version}}-{{package.revision}}</a>{%endif%}</td> + <!-- Package Size --> + <td class="size sizecol">{{package.size|filtered_filesizeformat}}</td> + <!-- License --> + <td class="license">{{package.license}}</td> + + {%if package.recipe%} + <!-- Recipe --> + <td class="recipe__name"><a href="{% url "recipe" build.pk package.recipe.pk %}">{{package.recipe.name}}</a></td> + <!-- Recipe Version --> + <td class="recipe__version"><a href="{% url "recipe" build.pk package.recipe.pk %}">{{package.recipe.version}}</a></td> + + <!-- Layer --> + <td class="recipe__layer_version__layer__name">{{package.recipe.layer_version.layer.name}}</td> + <!-- Layer branch --> + <td class="recipe__layer_version__branch">{{package.recipe.layer_version.branch}}</td> + <!-- Layer commit --> + <td class="recipe__layer_version__layer__commit"> + <a class="btn" + data-content="<ul class='unstyled'> + <li>{{package.recipe.layer_version.commit}}</li> + </ul>"> + {{package.recipe.layer_version.commit|truncatechars:13}} + </a> + </td> + <!-- Layer directory --> + {%else%} + <td class="recipe__name"></td> + <td class="recipe__version"></td> + <td class="recipe__layer_version__layer__name"></td> + <td class="recipe__layer_version__branch"></td> + <td class="recipe__layer_version__layer__commit"></td> + <td class="recipe__layer_version__local_path"></td> + {%endif%} + + </tr> + {% endfor %} + + {% include "basetable_bottom.html" %} + {% endif %} {# objects.paginator.count #} +{% endif %} {# Empty #} +</div> +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/brtargets.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/brtargets.html new file mode 100644 index 000000000..4ebd05879 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/brtargets.html @@ -0,0 +1,20 @@ +<span data-toggle="tooltip" + {% if buildrequest.brtarget_set.all.count > 1 %} + title="Targets: + {% for target in buildrequest.brtarget_set.all %} + {% if target.task %} + {{target.target}}:{{target.task}} + {% else %} + {{target.target}} + {% endif %} + {%endfor%}" + {%endif%}> + {% if buildrequest.brtarget_set.all.0.task %} + {{buildrequest.brtarget_set.all.0.target}}:{{buildrequest.brtarget_set.all.0.task}} + {% else %} + {{buildrequest.brtarget_set.all.0.target}} + {% endif %} + {% if buildrequest.brtarget_set.all.count > 1 %} + (+ {{buildrequest.brtarget_set.all.count|add:"-1"}}) + {% endif %} +</span> diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/builddashboard.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/builddashboard.html new file mode 100644 index 000000000..bab8e388f --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/builddashboard.html @@ -0,0 +1,307 @@ +{% extends "basebuildpage.html" %} +{% load humanize %} +{% load projecttags %} + +{% block parentbreadcrumb %} +{{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"}}) +{% endblock %} + +{% block buildinfomain %} +<!-- page title --> +<div class="row-fluid span10"> + <div class="page-header"> + <h1>{{build.target_set.all|dictsort:"target"|join:", "}} {{build.machine}}</h1> + </div> +</div> + +<!-- build result bar --> +<div class="row-fluid span10 pull-right"> + <div class="alert {%if build.outcome == build.SUCCEEDED%}alert-success{%elif build.outcome == build.FAILED%}alert-error{%else%}alert-info{%endif%}"> + <div class="row-fluid lead"> + <span class="pull-left"><strong> + {%if build.outcome == build.SUCCEEDED%}Completed{%elif build.outcome == build.FAILED%}Failed{%else%}{%endif%} + </strong> on + {{build.completed_on|date:"d/m/y H:i"}} +</span> +{% if build.warnings.count or build.errors.count %} + with +{% endif %} +{%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %} +{% if build.errors.count %} + <span > <i class="icon-minus-sign red"></i><strong><a href="#errors" class="error show-errors"> {{build.errors.count}} error{{build.errors.count|pluralize}}</a></strong></span> +{% endif %} +{% if build.warnings.count %} +{% if build.errors.count %} + and +{% endif %} + <span > <i class="icon-warning-sign yellow"></i><strong><a href="#warnings" class="warning show-warnings"> {{build.warnings.count}} warning{{build.warnings.count|pluralize}}</a></strong></span> +{% endif %} + <span class="pull-right">Build time: <a href="{% url 'buildtime' build.pk %}">{{ build.timespent_seconds|sectohms }}</a> + <a class="btn {%if build.outcome == build.SUCCEEDED%}btn-success{%else%}btn-danger{%endif%} pull-right log" href="{% url 'build_artifact' build.id "cookerlog" build.id %}">Download build log</a> + </span> + +{%endif%} + </div> + {% if build.toaster_exceptions.count > 0 %} + <div class="row"> + <small class="pull-right"> + <i class="icon-question-sign get-help get-help-blue" title="" data-original-title="Toaster exceptions do not affect your build: only the operation of Toaster"></i> + <a class="show-exceptions" href="#exceptions">Toaster threw {{build.toaster_exceptions.count}} exception{{build.toaster_exceptions.count|pluralize}}</a> + </small> + </div> + {% endif %} + </div> +</div> + +{% if build.errors.count %} +<div class="accordion span10 pull-right" id="errors"> + <div class="accordion-group"> + <div class="accordion-heading"> + <a class="accordion-toggle error toggle-errors"> + <h2 id="error-toggle"> + <i class="icon-minus-sign"></i> + {{build.errors.count}} error{{build.errors.count|pluralize}} + </h2> + </a> + </div> + <div class="accordion-body collapse in" id="collapse-errors"> + <div class="accordion-inner"> + <div class="span10"> + {% for error in logmessages %}{% if error.level == 2 %} + <div class="alert alert-error"> + <pre>{{error.message}}</pre> + </div> + {% endif %} + {% endfor %} + </div> + </div> + </div> + </div> +</div> +{% endif %} + +{%if build.outcome == build.SUCCEEDED%} +<!-- built images --> +{% if hasImages %} +<div class="row-fluid span10 pull-right"> + <h2>Images</h2> + {% for target in targets %} + {% if target.target.is_image %} + <div class="well dashboard-section"> + <h3><a href="{% url 'target' build.pk target.target.pk %}">{{target.target}}</a> + </h3> + <dl class="dl-horizontal"> + <dt>Packages included</dt> + <dd><a href="{% url 'target' build.pk target.target.pk %}">{{target.npkg}}</a></dd> + <dt>Total package size</dt> + <dd>{{target.pkgsz|filtered_filesizeformat}}</dd> + {% if target.targetHasNoImages %} + </dl> + <div class="row-fluid"> + <div class="alert alert-info span7"> + <p> + <b>This build did not create any image files</b> + </p> + <p> + This is probably because valid image and license manifest + files from a previous build already exist in your + <code>.../poky/build/tmp/deploy</code> + directory. You can + also <a href="{% url 'targetpkg' build.pk target.target.pk %}">view the + license manifest information</a> in Toaster. + </p> + </div> + </div> + {% else %} + <dt> + <i class="icon-question-sign get-help" title="The location in disk of the license manifest, a document listing all packages installed in your image and their licenses"></i> + + License manifest + </dt> + <dd> + <a href="{% url 'targetpkg' build.pk target.target.pk %}">View in Toaster</a> | + <a href="{% url 'build_artifact' build.pk 'licensemanifest' target.target.pk %}">Download</a></dd> + <dt> + <i class="icon-question-sign get-help" title="Image files are stored in <code>/build/tmp/deploy/images/</code>"></i> + Image files + </dt> + <dd> + <ul> + {% for i in target.imageFiles %} + {% if build.project %} + <li><a href="{% url 'build_artifact' build.pk 'imagefile' i.id %}">{{i.path}}</a> + {% else %} + <li>{{i.path}} + {% endif %} + ({{i.size|filtered_filesizeformat}})</li> + {% endfor %} + </ul> + </dd> + </dl> + {% endif %} + </div> + {% endif %} + {% endfor %} +</div> +{% endif %} + +{%else%} +<!-- error dump --> +{%endif%} + +<!-- other artifacts --> +{% if build.buildartifact_set.all.count > 0 %} +<div class="row-fluid span10 pull-right"> +<h2>Other artifacts</h2> + + <div class="well dashboard-section"> + <dl class="dl-horizontal"> + <dt> + <i class="icon-question-sign get-help" title="Build artifacts discovered in <i>tmp/deploy/images</i>. Usually kernel images and kernel modules."></i> + Other artifacts</dt> + <dd><div> + {% for ba in build.buildartifact_set.all|dictsort:"file_name" %} + <a href="{%url 'build_artifact' build.id 'buildartifact' ba.id %}"> + {{ba.get_local_file_name}} + </a> + + ({{ba.file_size|filtered_filesizeformat}}) <br/> + {% endfor %} + </div> + </dd> + </dl> + </div> + +</div> +{% endif %} +<!-- build summary --> +<div class="row-fluid span10 pull-right"> +<h2>Build summary</h2> + <div class="well span4 dashboard-section" style="margin-left:0px;"> + <h4><a href="{%url 'configuration' build.pk%}">Configuration</a></h4> + <dl> + <dt>Machine</dt><dd>{{build.machine}}</dd> + <dt>Distro</dt><dd>{{build.distro}}</dd> + <dt>Layers</dt>{% for i in build.layer_version_build.all|dictsort:"layer.name" %}<dd>{{i.layer.name}}</dd>{%endfor%} + </dl> + </div> + <div class="well span4 dashboard-section"> + <h4><a href="{%url 'tasks' build.pk%}">Tasks</a></h4> + <dl> + {% query build.task_build outcome=4 order__gt=0 as exectask%} + {% if exectask.count > 0 %} + <dt>Failed tasks</dt> + <dd> + {% if exectask.count == 1 %} + <a class="error" href="{% url "task" build.id exectask.0.id %}"> + {{exectask.0.recipe.name}} + <span class="task-name">{{exectask.0.task_name}}</span> + </a> + + <a href="{% url 'build_artifact' build.id "tasklogfile" exectask.0.id %}"> + <i class="icon-download-alt" title="" data-original-title="Download task log file"></i> + </a> + + {% elif exectask.count > 1%} + <a class="error" href="{% url "tasks" build.id %}?filter=outcome%3A4">{{exectask.count}}</a> + {% endif %} + </dd> + {% endif %} + <dt>Total number of tasks</dt><dd><a href="{% url 'tasks' build.pk %}">{% query build.task_build order__gt=0 as alltasks %}{{alltasks.count}}</a></dd> + <dt> + Tasks executed + <i class="icon-question-sign get-help" title="'Executed' tasks are those that need to be run in order to generate the task output"></i> + </dt> + <dd><a href="{% url 'tasks' build.pk %}?filter=task_executed%3A1&count=25&search=&page=1&orderby=order%3A%2B">{% query build.task_build task_executed=1 order__gt=0 as exectask%}{{exectask.count}}</a></dd> + <dt> + Tasks not executed + <i class="icon-question-sign get-help" title="'Not executed' tasks don't need to run because their outcome is provided by another task"></i> + </dt> + <dd><a href="{% url 'tasks' build.pk %}?filter=task_executed%3A0&count=25&search=&page=1&orderby=order%3A%2B">{% query build.task_build task_executed=0 order__gt=0 as noexectask%}{{noexectask.count}}</a></dd> + <dt> + Reuse + <i class="icon-question-sign get-help" title="The percentage of 'not executed' tasks over the total number of tasks, which is a measure of the efficiency of your build"></i> + </dt> + <dd> +{% query build.task_build order__gt=0 as texec %} +{% if noexectask.count|multiply:100|divide:texec.count < 0 %} +0 +{% else %} +{{noexectask.count|multiply:100|divide:texec.count}} +{% endif %} +% + </dd> + </dl> + </div> + <div class="well span4 dashboard-section"> + <h4><a href="{% url 'recipes' build.pk %}">Recipes</a> & <a href="{% url 'packages' build.pk %}">Packages</a></h4> + <dl> + <dt>Recipes built</dt><dd><a href="{% url 'recipes' build.pk %}">{{recipecount}}</a></dd> + <dt>Packages built</dt><dd><a href="{% url 'packages' build.pk %}">{{packagecount}}</a></dd> + </dl> + </div> +</div> + +{% if build.warnings.count %} +<div class="accordion span10 pull-right" id="warnings"> + <div class="accordion-group"> + <div class="accordion-heading"> + <a class="accordion-toggle warning toggle-warnings"> + <h2 id="warning-toggle"> + <i class="icon-warning-sign"></i> + {{build.warnings.count}} warning{{build.warnings.count|pluralize}} + </h2> + </a> + </div> + <div class="accordion-body collapse" id="collapse-warnings"> + <div class="accordion-inner"> + <div class="span10"> + {% for warning in logmessages %}{% if warning.level == 1 %} + <div class="alert alert-warning"> + <pre>{{warning.message}}</pre> + </div> + {% endif %}{% endfor %} + </div> + </div> + </div> + </div> +</div> +{% endif %} + + +{% if build.toaster_exceptions.count > 0 %} +<div class="accordion span10 pull-right" id="exceptions"> + <div class="accordion-group"> + <div class="accordion-heading"> + <a class="accordion-toggle exception toggle-exceptions"> + <h2 id="exception-toggle"> + <i class="icon-warning-sign"></i> + {{build.toaster_exceptions.count}} Toaster exception{{build.toaster_exceptions.count|pluralize}} + </h2> + </a> + </div> + <div class="accordion-body collapse" id="collapse-exceptions"> + <div class="accordion-inner"> + <div class="span10"> + {% for exception in build.toaster_exceptions %} + <div class="alert alert-exception"> + <pre>{{exception.message}}</pre> + </div> + {% endfor %} + </div> + </div> + </div> + </div> +</div> +{% endif %} + +<script type="text/javascript"> + $(document).ready(function() { + //show warnings section when requested from the previous page + if (location.href.search('#warnings') > -1) { + $('#collapse-warnings').addClass('in'); + } + }); +</script> + +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/buildrequestdetails.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/buildrequestdetails.html new file mode 100644 index 000000000..70fa1fb9a --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/buildrequestdetails.html @@ -0,0 +1,64 @@ +{% extends "baseprojectpage.html" %} + +{% load static %} +{% load projecttags %} +{% load humanize %} + + +{% block projectinfomain %} + <!-- begin content --> + + <div class="row-fluid"> + + <!-- end left sidebar container --> + <!-- Begin right container --> + <div class="span10"> + <div class="page-header"> + <h1> + <span data-toggle="tooltip" {%if buildrequest.brtarget_set.all.count > 1%}title="Targets: {%for target in buildrequest.brtarget_set.all%}{{target.target}} {%endfor%}"{%endif%}>{{buildrequest.brtarget_set.all.0.target}} {%if buildrequest.brtarget_set.all.count > 1%}(+ {{buildrequest.brtarget_set.all.count|add:"-1"}}){%endif%} {{buildrequest.get_machine}} </span> + + </h1> + </div> + <div class="alert alert-error"> + <p class="lead"> + <strong>Failed</strong> + on {{ buildrequest.updated|date:'d/m/y H:i' }} + with + + <i class="icon-minus-sign error" style="margin-left:6px;"></i> + <strong><a class="error accordion-toggle toggle-errors" href="#errors"> + {{buildrequest.brerror_set.all.count}} error{{buildrequest.brerror_set.all.count|pluralize}} + </a></strong> + <span class="pull-right">Build time: {{buildrequest.get_duration|sectohms}}</span> + </p> + </div> + + <div class="accordion" id="errors"> + <div class="accordion-group"> + <div class="accordion-heading"> + <a class="accordion-toggle error toggle-errors"> + <h2> + <i class="icon-minus-sign"></i> + {{buildrequest.brerror_set.all.count}} error{{buildrequest.brerror_set.all.count|pluralize}} + </h2> + </a> + </div> + <div class="accordion-body collapse in" id="collapse-errors"> + <div class="accordion-inner"> + <div class="span10"> + {% for error in buildrequest.brerror_set.all %} + <div class="alert alert-error"> + ERROR: <div class="air well"><pre>{{error.errmsg}}</pre></div> + </div> + {% endfor %} + </div> + </div> + </div> + + </div> + </div> + </div> + </div> <!-- end of row-fluid --> + + +{%endblock%} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/builds.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/builds.html new file mode 100644 index 000000000..c0d0c64c2 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/builds.html @@ -0,0 +1,109 @@ +{% extends "base.html" %} + +{% load static %} +{% load projecttags %} +{% load humanize %} + +{% block extraheadcontent %} +<link rel="stylesheet" href="/static/css/jquery-ui.min.css" type='text/css'> +<link rel="stylesheet" href="/static/css/jquery-ui.structure.min.css" type='text/css'> +<link rel="stylesheet" href="/static/css/jquery-ui.theme.min.css" type='text/css'> +<script src="/static/js/jquery-ui.min.js"></script> +<script src="/static/js/filtersnippet.js"></script> +{% endblock %} + +{% block pagecontent %} + +{% if last_date_from and last_date_to %} +<script> + // initialize the date range controls + $(document).ready(function () { + date_init('started_on','{{last_date_from}}','{{last_date_to}}','{{dateMin_started_on}}','{{dateMax_started_on}}','{{daterange_selected}}'); + date_init('completed_on','{{last_date_from}}','{{last_date_to}}','{{dateMin_completed_on}}','{{dateMax_completed_on}}','{{daterange_selected}}'); + }); +</script> +{%endif%} {# last_date_from and last_date_to #} + +<div class="row-fluid"> + + {% include "mrb_section.html" %} + + + {% if 1 %} + <div class="page-header top-air"> + <h1> + {% if request.GET.filter and objects.paginator.count > 0 or request.GET.search and objects.paginator.count > 0 %} + {{objects.paginator.count}} build{{objects.paginator.count|pluralize}} found + {%elif request.GET.filter and objects.paginator.count == 0 or request.GET.search and objects.paginator.count == 0 %} + No builds found + {%else%} + All builds + {%endif%} + </h1> + </div> + + {% if objects.paginator.count == 0 %} + <div class="row-fluid"> + <div class="alert"> + <form class="no-results input-append" id="searchform"> + <input id="search" name="search" class="input-xxlarge" type="text" value=" + {% if request.GET.search %} + {{request.GET.search}} + {% endif %}"/> + {% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %} + <button class="btn" type="submit" value="Search">Search</button> + <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all builds</button> + </form> + </div> + </div> + + + {% else %} + {% include "basetable_top.html" %} + <!-- Table data rows; the order needs to match the order of "tablecols" definitions; and the <td class value needs to match the tablecols clclass value for show/hide buttons to work --> + {% for build in objects %} + <tr class="data"> + <td class="outcome"> + <a href="{% url "builddashboard" build.id %}">{%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%}</a> + </td> + <td class="target">{% for t in build.target_set.all %} <a href="{% url "builddashboard" build.id %}"> {{t.target}} </a> <br />{% endfor %}</td> + <td class="machine"><a href="{% url "builddashboard" build.id %}">{{build.machine}}</a></td> + <td class="started_on"><a href="{% url "builddashboard" build.id %}">{{build.started_on|date:"d/m/y H:i"}}</a></td> + <td class="completed_on"><a href="{% url "builddashboard" build.id %}">{{build.completed_on|date:"d/m/y H:i"}}</a></td> + <td class="failed_tasks error"> + {% query build.task_build outcome=4 order__gt=0 as exectask%} + {% if exectask.count == 1 %} + <a href="{% url "task" build.id exectask.0.id %}">{{exectask.0.recipe.name}}.{{exectask.0.task_name}}</a> + <a href="{% url 'build_artifact' build.id "tasklogfile" exectask.0.id %}"> + <i class="icon-download-alt" title="" data-original-title="Download task log file"></i> + </a> + {% elif exectask.count > 1%} + <a href="{% url "tasks" build.id %}?filter=outcome%3A4">{{exectask.count}} task{{exectask.count|pluralize}}</a> + {%endif%} + </td> + <td class="errors.count errors_no"> + {% if build.errors.count %} + <a class="errors.count error" href="{% url "builddashboard" build.id %}#errors">{{build.errors.count}} error{{build.errors.count|pluralize}}</a> + {%endif%} + </td> + <td class="warnings.count warnings_no">{% if build.warnings.count %}<a class="warnings.count warning" href="{% url "builddashboard" build.id %}#warnings">{{build.warnings.count}} warning{{build.warnings.count|pluralize}}</a>{%endif%}</td> + <td class="time"><a href="{% url "buildtime" build.id %}">{{build.timespent_seconds|sectohms}}</a></td> + <td class="output"> + {% if build.outcome == build.SUCCEEDED %} + <a href="{%url "builddashboard" build.id%}#images">{{fstypes|get_dict_value:build.id}}</a> + {% endif %} + </td> + <td> + <a href="{% url 'project' build.project.id %}">{{build.project.name}}</a> + </td> + </tr> + + {% endfor %} + + + {% include "basetable_bottom.html" %} + {% endif %} {# objects.paginator.count #} +{% endif %} {# empty #} +</div><!-- end row-fluid--> + +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/buildtime.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/buildtime.html new file mode 100644 index 000000000..ea84ae797 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/buildtime.html @@ -0,0 +1,4 @@ +{% extends "basebuildpage.html" %} +{% block localbreadcrumb %} +<li>Build Time</li> +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/configuration.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/configuration.html new file mode 100644 index 000000000..3e489918d --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/configuration.html @@ -0,0 +1,71 @@ +{% extends "basebuildpage.html" %} +{% load projecttags %} + +{% block localbreadcrumb %} +<li>Configuration</li> +{% endblock %} + +{% block nav-configuration %} + <li class="active"><a href="{% url 'configuration' build.pk %}">Configuration</a></li> +{% endblock %} + +{% block buildinfomain %} +<!-- page title --> +<div class="row-fluid span10"> + <div class="page-header"> + <h1>Configuration</h1> + </div> +</div> + +<!-- configuration table --> +<div class="row-fluid pull-right span10" id="navTab"> +<ul class="nav nav-pills"> + <li class="active"><a href="#">Summary</a></li> + <li class=""><a href="{% url 'configvars' build.id %}">BitBake variables</a></li> +</ul> + + <!-- summary --> + <div id="summary" class="tab-pane active"> + <h3>Build configuration</h3> + <dl class="dl-horizontal"> + {%if BB_VERSION %}<dt>BitBake version</dt><dd>{{BB_VERSION}}</dd> {% endif %} + {%if BUILD_SYS %}<dt>Build system</dt><dd>{{BUILD_SYS}}</dd> {% endif %} + {%if NATIVELSBSTRING %}<dt>Host distribution</dt><dd>{{NATIVELSBSTRING}}</dd> {% endif %} + {%if TARGET_SYS %}<dt>Target system</dt><dd>{{TARGET_SYS}}</dd> {% endif %} + {%if MACHINE %}<dt>Machine</dt><dd>{{MACHINE}}</dd> {% endif %} + {%if DISTRO %}<dt>Distro</dt><dd>{{DISTRO}}</dd> {% endif %} + {%if DISTRO_VERSION %}<dt>Distro version</dt><dd>{{DISTRO_VERSION}}</dd> {% endif %} + {%if TUNE_FEATURES %}<dt>Tune features</dt><dd>{{TUNE_FEATURES}}</dd> {% endif %} + {%if TARGET_FPU %}<dt>Target FPU</dt><dd>{{TARGET_FPU}}</dd> {% endif %} + {%if targets.all %}<dt>Target(s)</dt> + <dd> <ul> {% for target in targets.all %} + <li>{{target.target}}{%if forloop.counter > 1 %}<br>{% endif %}</li> + {% endfor %} </ul> </dd> {% endif %} + </dl> + <h3>Layers</h3> + <div class="span9" style="margin-left:0px;"> + <table class="table table-bordered table-hover"> + <thead> + <tr> + <th>Layer</th> + <th>Layer branch</th> + <th>Layer commit</th> + </tr> + </thead> + <tbody>{% for lv in build.layer_version_build.all|dictsort:"layer.name" %} + <tr> + <td>{{lv.layer.name}}</td> + <td>{{lv.branch}}</td> + <td> <a class="btn" data-content="<ul class='unstyled'> + <li>{{lv.commit}}</li> </ul>"> + {{lv.commit|truncatechars:13}} + </a></td> + </tr>{% endfor %} + </tbody> + </table> + </div> + </div> + + +</div> +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/configvars.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/configvars.html new file mode 100644 index 000000000..8a572ae39 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/configvars.html @@ -0,0 +1,132 @@ +{% extends "basebuildpage.html" %} +{% load projecttags %} + +{% block localbreadcrumb %} +<li>Configuration</li> +{% endblock %} + +{% block nav-configuration %} + <li class="active"><a href="{% url 'configuration' build.pk %}">Configuration</a></li> +{% endblock %} + +{% block buildinfomain %} +<!-- page title --> +<div class="row-fluid span10"> + <div class="page-header"> + <h1> + {% if request.GET.filter and objects.paginator.count > 0 or request.GET.search and objects.paginator.count > 0 %} + {{objects.paginator.count}} variable{{objects.paginator.count|pluralize}} found + {%elif request.GET.filter and objects.paginator.count == 0 or request.GET.search and objects.paginator.count == 0 %} + No variables found + {%else%} + Configuration + {%endif%} + </h1> + </div> +</div> + +<!-- configuration table --> +<div class="row-fluid pull-right span10" id="navTab"> + <ul class="nav nav-pills"> + <li class=""><a href="{% url 'configuration' build.id %}">Summary</a></li> + <li class="active"><a href="#" >BitBake variables</a></li> + </ul> + + <!-- variables --> + <div id="variables" class="tab-pane"> + + {% if objects.paginator.count == 0 %} + <div class="row-fluid"> + <div class="alert"> + <form class="no-results input-append" id="searchform"> + <input id="search" name="search" class="input-xxlarge" type="text" value="{% if request.GET.search %}{{request.GET.search}}{% endif %}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %} + <button class="btn" type="submit" value="Search">Search</button> + <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all variables</button> + </form> + </div> + </div> + + {% else %} + {% include "basetable_top.html" %} + + {% for variable in objects %} + <tr class="data"> + <td class="variable_name"><a data-toggle="modal" href="#variable-{{variable.pk}}">{{variable.variable_name}}</a></td> + <td class="variable_value"><a data-toggle="modal" href="#variable-{{variable.pk}}">{{variable.variable_value|truncatechars:153}}</a></td> + <td class="file"><a data-toggle="modal" href="#variable-{{variable.pk}}"> + {% if variable.vhistory.all %} + {% for path in variable.vhistory.all|filter_setin_files:file_filter %} + {{path}}<br/> + {% endfor %} + {% endif %} + </a></td> + <td class="description"> + {% if variable.description %} + {{variable.description}} + <a href="http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-{{variable.variable_name|variable_parent_name}}" target="_blank"> + <i class="icon-share get-info"></i></a> + {% endif %} + </td> + </tr> +{% endfor %} + +{% include "basetable_bottom.html" %} +{% endif %} +</div> <!-- endvariables --> + +<!-- file list popups --> +{% for variable in objects %} + {% if variable.vhistory.count %} + <div id="variable-{{variable.pk}}" class="modal hide fade" tabindex="-1" role="dialog"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button> + <h3>History of {{variable.variable_name}}</h3> + </div> + <div class="modal-body"> + {% if variable.variable_value %} + {% if variable.variable_value|length < 570 %} + <h4>{{variable.variable_name}} value is:</h4> + <p> + {{variable.variable_value}} + </p> + {% else %} + <h4>{{variable.variable_name}} value is:</h4> + <p> + <span>{{variable.variable_value|string_slice:':570'}} + <span class="full"> {{variable.variable_value|string_slice:'570:'}} + </span> + <a class="btn btn-mini full-show">...</a> + </span> + </p> + <a class="btn btn-mini full-hide">Collapse variable value <i class="icon-caret-up"></i> + </a> + {% endif %} + {% else %} + <div class="alert alert-info">The value of <strong>{{variable.variable_name}}</strong> is an empty string</div> + {% endif %} + <h4>The value was set in the following configuration files:</h4> + <table class="table table-bordered table-hover"> + <thead> + <tr> + <th>Order</th> + <th>Configuration file</th> + <th>Operation</th> + <th>Line number</th> + </tr> + </thead> + <tbody> + {% for vh in variable.vhistory.all %} + <tr> + <td>{{forloop.counter}}</td><td>{{vh.file_name}}</td><td>{{vh.operation}}</td><td>{{vh.line_number}}</td> + </tr> + {%endfor%} + </tbody> + </table> + </div> + </div> + {% endif %} +{% endfor %} + +</div> <!-- buildinfomain --> + +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/cpuusage.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/cpuusage.html new file mode 100644 index 000000000..02f07b760 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/cpuusage.html @@ -0,0 +1,4 @@ +{% extends "basebuildpage.html" %} +{% block localbreadcrumb %} +<li>Cpu Usage</li> +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_pagination_bottom.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_pagination_bottom.html new file mode 100644 index 000000000..f40c21d99 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_pagination_bottom.html @@ -0,0 +1,55 @@ +{% comment %} + Show pagination controls as per search/pagination table detail spec. + Input: objects, setup for pagination using the standard method in views. + object_count, count for complete list of objects, (all pages, no pattern) +{% endcomment %} + +{# only paginate if 10 or more rows unfiltered, all pages #} +{% if object_count >= 10 %} +<div class="pagination"> + <ul> +{%if objects.has_previous %} + <li><a href="javascript:reload_params({'page':{{objects.previous_page_number}}})">«</a></li> +{%else%} + <li class="disabled"><a href="#">«</a></li> +{%endif%} +{% for i in objects.page_range %} + <li{%if i == objects.number %} class="active" {%endif%}><a href="javascript:reload_params({'page':{{i}}})">{{i}}</a></li> +{% endfor %} +{%if objects.has_next%} + <li><a href="javascript:reload_params({'page':{{objects.next_page_number}}})">»</a></li> +{%else%} + <li class="disabled"><a href="#">»</a></li> +{%endif%} + </ul> + + <div class="pull-right"> + <span class="help-inline" style="padding-bottom:10px;">Show rows:</span> + <select class="pagesize"> + {% with "10 25 50 100 150" as list%} + {% for i in list.split %} + <option value="{{i}}">{{i}}</option> + {% endfor %} + {% endwith %} + </select> + </div> +</div> + +<!-- Update page display settings --> +<script> + $(document).ready(function() { + // load data for number of entries to be displayed on page + if ({{request.GET.count}} != "") { + pagesize = {{request.GET.count}}; + } + $('.pagesize option').prop('selected', false) + .filter('[value="' + pagesize + '"]') + .attr('selected', true); + + $(".pagesize").change(function () { + reload_params({"count":$(this).val()}); + }); +}); +</script> +{% endif %} + diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_search_header.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_search_header.html new file mode 100644 index 000000000..7bea3f47f --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_search_header.html @@ -0,0 +1,68 @@ +{% comment %} + Show a detail table Search field and Rows per page. + Input: + objects, our boilerplated paginated with search fields set. + object_count, count of full, unfiltered, objects list + search_what, fills in "Search ___" + Only show the search form if we have more than 10 results, + or if return from a previous search. +{% endcomment %} + + +<script> +$(document).ready(function() { + /* Clear the current search selection and reload the results */ + $(".search-clear").click(function(){ + $("#search").val(""); + $(this).parents("form").submit(); + }); +}); +</script> +<div class="row-fluid"> +{% if objects.paginator.count > 10 or request.GET.search %} + {% if objects.paginator.count == 0 %} + <div class="alert"> + <h3>No {{search_what}} found</h3> + <form id="searchform" class="input-append"> + {% else %} + <form id="searchform" class="navbar-search input-append pull-left"> + {% endif %} + + <input id="search" class="input-xlarge" type="text" placeholder="Search {{search_what}}" name="search" value="{% if request.GET.search %}{{request.GET.search}}{% endif %}"> + <input type="hidden" value="name:+" name="orderby"> + <input type="hidden" value="l" name="page"> + {% if request.GET.search %} + <a class="add-on btn search-clear"> + <i class="icon-remove"></i> + </a> + {% endif %} + <button type="submit" class="btn">Search</button> + {% if objects.paginator.count == 0 %} + <button type="submit" class="btn btn-link search-clear"> + Show all {{search_what}} + </button> + {% endif %} + </form> +{% endif %} + +{% if objects.paginator.count == 0 %} + </div> {# end alert #} +{% else %} + {% if object_count > 10 %} + <div class="pull-right"> + <span class="help-inline" style="padding-top:5px;">Show rows:</span> + <select style="margin-top:5px;margin-bottom:0px;" class="pagesize"> + {% with "10 25 50 100 150" as list%} + {% for i in list.split %} + {% if request.session.limit == i %} + <option value="{{i}}" selected>{{i}}</option> + {% else %} + <option value="{{i}}">{{i}}</option> + {% endif %} + {% endfor %} + {% endwith %} + </select> + </div> + {% endif %} +{% endif %} +</div> {# row-fluid #} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_sorted_header.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_sorted_header.html new file mode 100644 index 000000000..6ce292e5a --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_sorted_header.html @@ -0,0 +1,25 @@ +{% comment %} + Adds sorted columns to a detail table. + Must be preceded by <table class="table table-bordered table-hover tablesorter" id="otable"> + Must be followed by <tbody>...</tbody></table>. + Requires tablecols setup column fields dclass, clclass, qhelp, orderfield. +{% endcomment %} +{% load projecttags %} +{# <table class="table table-bordered table-hover tablesorter" id="otable"> #} + <thead> + <!-- Table header row; generated from "tablecols" entry in the context dict --> + <tr> + {% for tc in tablecols %}<th class="{%if tc.dclass%}{{tc.dclass}}{% endif %} {%if tc.class %}{{tc.clclass}}{% endif %}"> + {%if tc.qhelp%}<i class="icon-question-sign get-help" title="{{tc.qhelp}}"></i>{%endif%} + {%if tc.orderfield%}<a {%if tc.ordericon%} class="sorted" {%endif%}href="javascript:reload_params({'page': 1, 'orderby' : '{{tc.orderfield}}' })">{{tc.name}}</a>{%else%}<span class="muted">{{tc.name}}</span>{%endif%} + {%if tc.ordericon%} <i class="icon-caret-{{tc.ordericon}}"></i>{%endif%} + {% if request.GET.search and forloop.first %} + <span class="badge badge-info">{{objects.paginator.count}}</span> + {% endif %} + {%if tc.filter%}<div class="btn-group pull-right"> + <a href="#filter_{{tc.filter.class}}" role="button" class="btn btn-mini {%if request.GET.filter%}{{tc.filter.options|filtered_icon:request.GET.filter}} {%endif%}" {%if request.GET.filter and tc.filter.options|filtered_tooltip:request.GET.filter %} title="<p>{{tc.filter.options|filtered_tooltip:request.GET.filter}}</p><p><a class='btn btn-small btn-primary' href=javascript:reload_params({'filter':''})>Show all {% if filter_search_display %}{{filter_search_display}}{% else %}{{objectname}}{% endif %}</a></p>" {%endif%} data-toggle="modal"> <i class="icon-filter filtered"></i> </a> + </div>{%endif%} + </th>{% endfor %} + </tr> + </thead> + diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/dirinfo.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/dirinfo.html new file mode 100644 index 000000000..a5bc48127 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/dirinfo.html @@ -0,0 +1,236 @@ +{% extends "basebuildpage.html" %} +{% block extraheadcontent %} +{% load static %} +<link rel="stylesheet" href="{% static 'css/jquery.treetable.css' %}" type="text/css"> +<link rel="stylesheet" href="{% static 'css/jquery.treetable.theme.toaster.css' %}" type="text/css"> +{% endblock extraheadcontent %} + +{% block localbreadcrumb %} +<li>{{target.target}}</li> +{% endblock localbreadcrumb%} + +{% block buildinfomain %} + +{% load static %} +<script src="{% static 'js/jquery.treetable.js' %}"> +</script> +{% load projecttags %} + +<script type='text/javascript'> + function setupTreetable() { + $("#dirtable").treetable({ + expandable: true, + branchAttr: "ttBranch", + clickableNodeNames: true, + onNodeCollapse: function() { + /* Do nothing, keep cached */ + }, + onNodeExpand: function() { + var start = this.id; + var n = $("#dirtable").treetable("node", start); + if (this.children.length > 0) { + /* already was expanded once */ + $("#dirtable").treetable("reveal", start); + } + else { + var url = "{% url "dirinfo_ajax" build.id target.id %}"; + $.ajax({ + async: false, + type : "GET", + url : url, + data : "start=" + start, + success : function(response) { + addRows(n, response) + }, + error : function(jqXHR, textStatus, errorThrown ) {alert(textStatus + ":" + errorThrown)}, + }); + } + }, + }); + } + function td(data) { + if (data == null) { + data = ''; + } + return '<td>' + data + '</td>' + } + + function formatRow(o) { + /* setup tr-wide formatting */ + var tr = '<tr class="'; + if (o.link_to != null) { + tr += 'muted '; + } + if (o.isdir && o.childcount) { + tr += 'branch" data-tt-branch="true" '; + } + else { + tr += 'leaf" data-tt-branch="false" '; + } + tr += ' data-tt-id="' + o.fullpath +'" '; + if (o.parent != "/") { + tr += ' data-tt-parent-id="' + o.parent +'" '; + } + tr += '>'; + + /* setup td specific formatting */ + var link_to = td(o.link_to); + var size = '<td class = "sizecol">' + o.size + '</td>' + var permission = td(o.permission); + var owner = td(o.owner); + var group = td(o.group); + + /* handle the name column */ + var name = null;; + var namespan=1; + if (o.isdir) { + if (o.link_to == null) { + namespan = 2; + if (o.package == null) { + namespan = 3; + } + } + var colspan = 'colspan="' + namespan + '"'; + name = '<td class="content-directory"' + colspan + '>'; + if (o.childcount) { + name += '<a href="">'; + } + name += '<i class="icon-folder-close"></i>'; + name += ' ' + o.name; + if (o.childcount) { + name += '</a>'; + } + name += '</td>'; + } + else { + name = '<td>'; + if (o.link_to == null) { + name += '<i class="icon-file"></i>'; + } + else { + name += '<i class="icon-hand-right"></i>'; + } + name += ' ' + o.name; + name += '</td>'; + } + + /* handle the package column */ + var package = null; + if (o.package != null) { + /* add link to included package page */ + build_id = {{ build.id }}; + target_id = {{ target.id }}; + /* Create a url for a dummy package id of 0 */ + dummy = "{% url 'package_included_detail' build.id target.id 0 %}" + /* fill in the package id */ + url = dummy.substr(0, dummy.length-1) + o.package_id; + package = '<a href=' + url + '>' ; + package += o.package; + package += '</a>'; + if (o.installed_package != o.package) { + /* make class muted and add hover help */ + package += '<span class="muted"> as ' + o.installed_package + ' </span>'; + package += '<i class="icon-question-sign get-help hover-help" '; + package += 'title="' + o.package + ' was renamed at packaging time and was installed in your image as ' + o.installed_package + '">'; + package += '</i>'; + } + } + package = td(package); + + var cols1to3; + switch (namespan) { + case 3: + cols1to3 = name; + break; + case 2: + cols1to3 = name + package; + break; + default: + cols1to3 = name + link_to + package; + } + r = tr + cols1to3 + size + permission + owner + group + "</tr>" + return r; + } + + function addRows(n, objs) { + rows = ""; + for (i=0; i<objs.length; i++) { + rows += formatRow(objs[i]); + } + $("#dirtable").treetable("loadBranch", n, rows); + } + + $.fn.isOffScreen = function(){ + var win = $(window); + viewportBottom = win.scrollTop() + win.height(); + + var bounds = this.offset(); + bounds.bottom = bounds.top + this.outerHeight(); + + return (bounds.bottom > viewportBottom); + }; + + function selectRow(path) { + var row = $('tr[data-tt-id="' + path + '"]'); + row.addClass(" highlight"); + if (row.isOffScreen()) { + $('html, body').animate({ scrollTop: row.offset().top - 150}, 2000); + } + } +</script> + +<div class="span10"> + + <div class="page-header"> + <h1> {{target.target}} </h1> + </div> + + <ul class="nav nav-pills"> + <li class=""> + <a href="{% url 'target' build.id target.id %}"> + <i class="icon-question-sign get-help" title="Of all the packages built, the subset installed in the root file system of this image"></i> + Packages included ({{target.package_count}} - {{packages_sum|filtered_filesizeformat}}) + </a> + </li> + <li class="active"> + <a href="{% url 'dirinfo' build.id target.id %}"> + <i class="icon-question-sign get-help" title="The directories and files in the root file system of this image"></i> + Directory structure + </a> + </li> + </ul> + + <div id="directory-structure" class="tab-pane active"> + <table id="dirtable" class="table table-bordered table-hover treetable"> + <thead> + <tr> + <th>Directory / File</th> + <th>Symbolic link to</th> + <th>Source package</th> + <th>Size</th> + <th>Permissions</th> + <th>Owner</th> + <th>Group</th> + </tr> + </thead> + <tbody> + <script type='text/javascript'> + setupTreetable(); + addRows(null, {{ objects|safe }} ); + {% if file_path %} + {% comment %} + link from package_included_detail specifies file path + {% endcomment %} + {% for dir_elem in dir_list %} + $("#dirtable").treetable("expandNode", "{{dir_elem}}"); + {% endfor %} + selectRow("{{file_path}}"); + {% endif %} + </script> + </tbody> + </table> + </div> <!-- directory-structure --> +</div> <!-- span10 --> + +{% endblock buildinfomain %} + diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/diskio.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/diskio.html new file mode 100644 index 000000000..c5cef6f38 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/diskio.html @@ -0,0 +1,4 @@ +{% extends "basebuildpage.html" %} +{% block localbreadcrumb %} +<li>Disk I/O</li> +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/filtersnippet.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/filtersnippet.html new file mode 100644 index 000000000..1101aa810 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/filtersnippet.html @@ -0,0 +1,57 @@ +{% load projecttags %} +<!-- '{{f.class}}' filter --> +{% with f.class as key %} +<form id="filter_{{f.class}}" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true"> + <input type="hidden" name="search" value="{%if request.GET.search %}{{request.GET.search}}{%endif%}"/> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button> + {% if search_term %} + <h3>Filter {{total_count}} {%if filter_search_display%}{{filter_search_display|title}}{%else%}{{objectname|title}}{%endif%} matching '{{search_term}}' by '{{tc.name}}'</h3> + {% else %} + <h3>Filter {%if filter_search_display%}{{filter_search_display|title}}{%else%}{{objectname|title}}{%endif%} by '{{tc.name}}'</h3> + {% endif %} + </div> + <div class="modal-body"> + <p>{{f.label}}</p> + <label class="radio"> + <input type="radio" name="filter" {%if request.GET.filter%}{{f.options|check_filter_status:request.GET.filter}} {%else%} checked {%endif%} value="" data-key="{{key}}"> All {%if filter_search_display%}{{filter_search_display|title}}{%else%}{{objectname|title}}{%endif%} + </label> + {% for option in f.options %} + {% if option.1 == 'daterange' %} + <div class="form-inline"> + <label class="radio"> + <input type="radio" name="filter" id="filter_value_{{key}}" {%if key == daterange_selected %}checked{%endif%} value="{{option.1}}" data-key="{{key}}"> {{option.0}} + {% else %} + {% if 1 %} + <label class="radio"> + <input type="radio" name="filter" {%if request.GET.filter == option.1 %}checked{%endif%} value="{{option.1}}" data-key="{{key}}"> {{option.0}} + {% comment "do not disable radio selections by count for now" %}{% else %} + <label class="radio muted"> + <input type="radio" name="filter" disabled {%if request.GET.filter == option.1 %}checked{%endif%} value="{{option.1}}" data-key="{{key}}"> {{option.0}} + {% endcomment %}{% endif %} + {% endif %} + {% if option.3 %}<i class="icon-question-sign get-help" data-placement="right" title="{{option.3}}"></i>{% endif %} + </label> + {% if option.1 == 'daterange' %} + <input type="text" id="date_from_{{key}}" name="date_from_{{key}}" disabled class="input-small" /><label class="help-inline">to</label> + <input type="text" id="date_to_{{key}}" name="date_to_{{key}}" disabled class="input-small" /> + <label class="help-inline get-help" >(dd/mm/yyyy)</label> + </div> + {% endif %} + {% endfor %} + <!-- daterange persistence --> + {% if last_date_from and last_date_to %} + <input type="hidden" id="last_date_from_{{key}}" name="last_date_from" value="{{last_date_from}}"/> + <input type="hidden" id="last_date_to_{{key}}" name="last_date_to" value="{{last_date_to}}"/> + {% endif %} + </div> + <div class="modal-footer"> + <button type="submit" class="btn btn-primary" data-key="{{key}}">Apply</button> + {% if request.GET.filter %} + {% if request.GET.filter|string_remove_regex:':.*' != f.options.0.1|string_remove_regex:':.*' %} + <span class="help-inline pull-left">You can only apply one filter to the table. This filter will override the current filter.</span> + {% endif %} + {% endif %} + </div> +</form> +{% endwith %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/generic-toastertable-page.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/generic-toastertable-page.html new file mode 100644 index 000000000..33aa8ce0d --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/generic-toastertable-page.html @@ -0,0 +1,17 @@ +{% extends "baseprojectpage.html" %} +{% load projecttags %} +{% load humanize %} +{% load static %} + +{% block projectinfomain %} + +<h2>{{title}} (<span class="table-count-{{table_name}}"></span>) + {% if project.release %} + <i class="icon-question-sign get-help heading-help" title="This page lists {{title}} compatible with the release selected for this project, which is {{project.release.description}}"></i> + {% endif %} +</h2> + +{% url table_name project.id as xhr_table_url %} +{% include "toastertable.html" %} + +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/importlayer.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/importlayer.html new file mode 100644 index 000000000..ce3d724c8 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/importlayer.html @@ -0,0 +1,138 @@ +{% extends "base.html" %} +{% load projecttags %} +{% load humanize %} +{% load static %} +{% block pagecontent %} + +{% include "projecttopbar.html" %} + + + {% if project and project.release %} + <script src="{% static 'js/layerDepsModal.js' %}"></script> + <script src="{% static 'js/importlayer.js' %}"></script> + <script> + $(document).ready(function (){ + var ctx = { + xhrImportLayerUrl : "{% url 'xhr_importlayer' %}", + }; + + try { + importLayerPageInit(ctx); + } catch (e) { + document.write("Sorry, An error has occurred loading this page"); + console.warn(e); + } + }); + </script> + + <form class="span11"> + <fieldset> + <legend>Layer repository information</legend> + <span class="help-block">The layer you are importing must be compatible with <strong>{{project.release.description}}</strong>, which is the release you are using in this project.</span> + <div class="alert alert-error" id="import-error" style="display:none"> + <button type="button" class="close" data-dismiss="alert">×</button> + <h3> </h3> + <p></p> + <ul></ul> + </div> + + <div class="control-group" id="layer-name-ctrl"> + <label class="control-label air" for="import-layer-name"> + Layer name + <span class="icon-question-sign get-help" title="Something like 'meta-mylayer'. Your layer name must be unique and can only include letters, numbers and dashes"></span> + </label> + <div class="controls"> + <input id="import-layer-name" type="text" required autofocus data-autocomplete="off" data-provide="typeahead"> + <span class="help-inline" style="display: none;" id="invalid-layer-name-hint">A valid layer name can only include letters, numbers and dashes</span> + <span class="help-inline" style="display: none;" id="duplicated-layer-name-hint"></span> + </div> + + </div> + <div id="duplicate-layer-info" style="display:none"> + <div class="alert warning"> + <h3>A layer called <a href="" class="dup-layer-link"><span class="dup-layer-name"></span></a> already exists</h3> + <p>Layer names must be unqiue. Please use a different layer name.</p> + </div> + <dl> + <dt> + The <span class="dup-layer-name"></span> repository url is + </dt> + <dd> + <span id="dup-layer-vcs-url"></span> + </dd> + + <dt> + The <span class="dup-layer-name"></span> revision is + </dt> + <dd> + <span id="dup-layer-revision"></span> + </dd> + </dl> + + <p><a href="" class="dup-layer-link">View the <span class="dup-layer-name"></span> layer information</a></p> + + </div> + + <div class="fields-apart-from-layer-name"> + <label for="layer-git-repo-url" class="project-form"> + Git repository URL + <span class="icon-question-sign get-help" title="Fetch/clone URL of the repository. Currently, Toaster only supports Git repositories." ></span> + </label> + + <input type="text" id="layer-git-repo-url" class="input-xxlarge" required> + <label class="project-form" for="layer-subdir"> + Repository subdirectory + <span class="muted">(optional)</span> + <span class="icon-question-sign get-help" title="Subdirectory within the repository where the layer is located, if not in the root (usually only used if the repository contains more than one layer)"></span> + </label> + <input type="text" id="layer-subdir"> + + <div class="control-group" id="layer-revision-ctrl"> + <label class="control-label project-form" for="layer-git-ref">Revision + <span class="icon-question-sign get-help" title="You can provide a Git branch, a tag or a commit SHA as the revision"></span> + </label> + <div class="controls"> + <input type="text" class="span3" id="layer-git-ref" required> + <span class="help-inline" style="diaply:none;" id="invalid-layer-revision-hint"></span> + </div> + </div> + </div> + + </fieldset> + + <div class="fields-apart-from-layer-name"> + <fieldset class="air"> + <legend> + Layer dependencies + <span class="muted">(optional)</span> + <span class="icon-question-sign get-help heading-help" title="Other layers this layer depends upon"></span> + </legend> + <ul class="unstyled configuration-list" id="layer-deps-list"> + </ul> + <div class="input-append"> + <input type="text" autocomplete="off" data-minLength="1" data-autocomplete="off" data-provide="typeahead" placeholder="Type a layer name" id="layer-dependency" class="input-xlarge"> + <a class="btn" id="add-layer-dependency-btn"> + Add layer + </a> + </div> + <span class="help-inline">You can only add layers Toaster knows about</span> + </fieldset> + <div class="air" id="form-actions"> + <button class="btn btn-primary btn-large" data-toggle="modal" id="import-and-add-btn" data-target="#dependencies-message" disabled>Import and add to project</button> + <span class="help-inline" id="import-and-add-hint" style="vertical-align: middle;">To import a layer you need to enter a layer name, a Git repository URL and a revision (branch, tag or commit)</span> + </div> + </div> + </form> + + {% else %} {#project and project release#} + <div class="page-header"> + <h1>Import layer</h1> + </div> + <div class="alert alert-info" id="import-error" > + <h3>Unsupported project type</h3> + <p>This project does not support importing layers.</p> + <ul></ul> + </div> + + {% endif %} +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/js-unit-tests.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/js-unit-tests.html new file mode 100644 index 000000000..5b8fd8447 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/js-unit-tests.html @@ -0,0 +1,39 @@ +{% extends "base.html" %} +{% load projecttags %} +{% load humanize %} +{% load static %} +{% block pagecontent %} + +<link rel="stylesheet" href="//code.jquery.com/qunit/qunit-1.18.0.css" /> + +<script src="//code.jquery.com/qunit/qunit-1.18.0.js"></script> + +<script src="{% static 'js/layerDepsModal.js' %}"></script> +<script src="{% static 'js/projectpage.js' %}"></script> + +<script src="{% static 'js/bootstrap.min.js' %}"></script> +<script src="{% static 'js/filtersnippet.js' %}"></script> +<script src="{% static 'js/importlayer.js' %}"></script> +<script src="{% static 'js/prettify.js' %}"></script> +<script src="{% static 'js/layerBtn.js' %}"></script> +<script src="{% static 'js/layerDepsModal.js' %}"></script> +<script src="{% static 'js/projectpage.js' %}"></script> +<script src="{% static 'js/layerdetails.js' %}"></script> +<script src="{% static 'js/table.js' %}"></script> + +<script> + var tableUrl = '{% url 'projectlayers' project.pk %}'; +</script> + +<script src="{% static 'js/tests/test.js' %}"></script> + +<div id="qunit"></div> + +<input type="text" id="layers" placeholder="layers" ></input> +<input type="text" id="recipes" placeholder="recipes"></input> +<input type="text" id="projects" placeholder="projects"></input> +<input type="text" id="machines" placeholder="machines"></input> + +{% endblock %} + + diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/landing.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/landing.html new file mode 100644 index 000000000..45e95322d --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/landing.html @@ -0,0 +1,58 @@ +{% extends "base.html" %} + +{% load static %} +{% load projecttags %} +{% load humanize %} + +{% block pagecontent %} + + <div class="container-fluid"> + <div class="row-fluid"> + <!-- Empty - no data in database --> + <div class="hero-unit span12 well-transparent"> + <div class="row-fluid"> + <div class="span6"> + <h1> + This is Toaster + </h1> + <p>A web interface to <a href="http://www.openembedded.org">OpenEmbedded</a> and <a href="http://www.yoctoproject.org/tools-resources/projects/bitbake">BitBake</a>, the <a href="http://www.yoctoproject.org">Yocto Project</a> build system.</p> + + + {% if lvs_nos %} + <p class="hero-actions"> + <a class="btn btn-primary btn-large" href="{% url 'newproject' %}"> + To start building, create your first Toaster project + </a> + </p> + {% else %} + <div class="alert alert-info lead air"> + Toaster has no layer information. Without layer information, you cannot run builds. To generate layer information you can: + <ul> + <li> + <a href="http://www.yoctoproject.org/docs/latest/toaster-manual/toaster-manual.html#layer-source">Configure a layer source</a> + </li> + <li> + <a href="{% url 'newproject' %}">Create a project</a>, then import layers + </li> + </ul> + </div> + {% endif %} + + <ul class="unstyled"> + <li> + <a href="http://www.yoctoproject.org/docs/latest/toaster-manual/toaster-manual.html">Read the Toaster manual</a> + </li> + <li> + <a href="https://wiki.yoctoproject.org/wiki/Contribute_to_Toaster">Contribute to Toaster</a> + </li> + </ul> + + </div> + <div class="span6"> + <img alt="Yocto Project" class="thumbnail" src="{% static 'img/toaster_bw.png' %}"/> + </div> + </div> + </div> + </div> + +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/landing_not_managed.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/landing_not_managed.html new file mode 100644 index 000000000..5bc435d14 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/landing_not_managed.html @@ -0,0 +1,32 @@ +{% extends "base.html" %} + +{% load static %} +{% load projecttags %} +{% load humanize %} + +{% block pagecontent %} + + <div class="container-fluid"> + <div class="row-fluid"> + <!-- Empty - no build module --> + <div class="page-header top-air"> + <h1> + This page only works with Toaster in 'Build' mode + </h1> + </div> + <div class="alert alert-info lead"> + <p"> + The 'Build' mode allows you to configure and run your Yocto Project builds from Toaster. + <ul> + <li><a href="http://www.yoctoproject.org/docs/latest/toaster-manual/toaster-manual.html#intro-modes"> + Read about the 'Build' mode + </a></li> + <li><a href="/"> + View your builds + </a></li> + </ul> + </p> + </div> + </div> + +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/layer_btn.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/layer_btn.html new file mode 100644 index 000000000..a2e93934d --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/layer_btn.html @@ -0,0 +1,9 @@ +<button class="btn btn-danger btn-block layer-exists-{{data.pk}} layerbtn" style="display:none;" data-layer='{ "id": {{data.pk}}, "name": "{{data.layer.name}}", "layerdetailurl": "{%url 'layerdetails' extra.pid data.pk%}"}' data-directive="remove" > + <i class="icon-trash"></i> + Delete layer +</button> +<button class="btn btn-block layer-add-{{data.pk}} layerbtn" data-layer='{ "id": {{data.pk}}, "name": "{{data.layer.name}}", "layerdetailurl": "{%url 'layerdetails' extra.pid data.pk%}"}' data-directive="add"> + <i class="icon-plus"></i> + Add layer +</button> + diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/layerdetails.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/layerdetails.html new file mode 100644 index 000000000..7dd3db27a --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/layerdetails.html @@ -0,0 +1,276 @@ +{% extends "base.html" %} +{% load projecttags %} +{% load humanize %} +{% load static %} + +{% block pagecontent %} + +<div class="section"> + <ul class="breadcrumb"> + <li class="muted">{{project.name}}:</li> + <li> + <a href="{% url 'project' project.id %}">Configuration</a> + <span class="divider">→</span> + </li> + <li><a href="{% url 'projectlayers' project.id %}">Compatible layers</a> + <span class="divider">→</span> + </li> + <li class="active"> + {{layerversion.layer.name}} ({{layerversion.get_vcs_reference|truncatechars:13}}) + </li> + </ul> +</div> + +{# If this is not an imported layer then hide the edit ui #} +{% if not layerversion.layer_source_id or layerversion.layer_source.sourcetype != layerversion.layer_source.TYPE_IMPORTED %} +<style scoped> + .icon-pencil { + display:none; + } +.delete-current-value{ + display: none; +} + li .icon-trash { + display:none; + } + .add-deps { + display:none; + } +</style> +{% endif %} + + +<script src="{% static 'js/layerdetails.js' %}"></script> +<script> + + $(document).ready(function (){ + var ctx = { + projectBuildsUrl : "{% url 'projectbuilds' project.id %}", + xhrUpdateLayerUrl : "{% url 'xhr_updatelayer' %}", + layerVersion : { + name : "{{layerversion.layer.name}}", + id : {{layerversion.id}}, + commit: "{{layerversion.get_vcs_reference}}", + {%if layerversion.id in projectlayers %} + inCurrentPrj : true, + {% else %} + inCurrentPrj : false, + {% endif %} + layerdetailurl : "{% url 'layerdetails' project.id layerversion.id %}", + sourceId: {{layerversion.layer_source_id|json}}, + } + }; + + try { + layerDetailsPageInit(ctx); + } catch (e) { + document.write("Sorry, An error has occurred loading this page"); + console.warn(e); + } + }); +</script> + +<div class="row-fluid span11"> + <div class="page-header"> + <h1>{{layerversion.layer.name}} <small class="commit" + {% if layerversion.get_vcs_reference|length > 13 %} + data-toggle="tooltip" title="{{layerversion.get_vcs_reference}}" + {% endif %}> + ({{layerversion.get_vcs_reference|truncatechars:13}})</small></h1> + </div> +</div> + +<!-- container for tabs --> +<div class="row-fluid span7 tabbable"> + <div class="alert alert-info lead" id="alert-area" style="display:none"> + <button type="button" class="close" id="dismiss-alert">×</button> + <span id="alert-msg"></span> + </div> + <ul class="nav nav-pills"> + <li class="active"> + <a data-toggle="tab" href="#information" id="details-tab">Layer details</a> + </li> + <li> + <a data-toggle="tab" href="#recipes" class="muted" id="targets-tab">Recipes (<span class="table-count-recipestable"></span>)</a> + </li> + <li> + <a data-toggle="tab" href="#machines" class="muted" id="machines-tab">Machines (<span class="table-count-machinestable"></span>)</a> + </li> + </ul> + <div class="tab-content"> + <span class="button-place"> + {% if layerversion.id not in projectlayers %} + <button id="add-remove-layer-btn" data-directive="add" class="btn btn-large btn-block"> + <span class="icon-plus"></span> + Add the {{layerversion.layer.name}} layer to your project + </button> + {% else %} + <button id="add-remove-layer-btn" data-directive="remove" class="btn btn-block btn-large btn-danger"> + <span class="icon-trash"></span> + Delete the {{layerversion.layer.name}} layer from your project + </button> + {% endif %} + </span> + + <!-- layer details pane --> + <div id="information" class="tab-pane active"> + <dl class="dl-horizontal"> + <dt class=""> + <i class="icon-question-sign get-help" title="Fetch/clone URL of the repository"></i> + Repository URL + </dt> + <dd> + <span class="current-value">{{layerversion.layer.vcs_url}}</span> + {% if layerversion.get_vcs_link_url %} + <a href="{{layerversion.get_vcs_link_url}}/" class="icon-share get-info" target="_blank"></a> + {% endif %} + <form id="change-repo-form" class="control-group" style="display:none"> + <div class="input-append"> + <input type="text" class="input-xlarge" value="{{layerversion.layer.vcs_url}}"> + <button data-layer-prop="vcs_url" class="btn change-btn" type="button">Save</button> + <a href="#" style="display:none" class="btn btn-link cancel">Cancel</a> + </div> + </form> + <i class="icon-pencil" ></i> + </dd> + <dt> + <i class="icon-question-sign get-help" title="Subdirectory within the repository where the layer is located, if not in the root (usually only used if the repository contains more than one layer)"></i> + Repository subdirectory + </dt> + <dd> + <span class="muted" style="display:none">Not set</span> + <span class="current-value">{{layerversion.dirpath}}</span> + {% if layerversion.get_vcs_dirpath_link_url %} + <a href="{{layerversion.get_vcs_dirpath_link_url}}" class="icon-share get-info" target="_blank"></a> + {% endif %} + <form id="change-subdir-form" style="display:none;"> + <div class="input-append"> + <input type="text" value="{{layerversion.dirpath}}"> + <button data-layer-prop="dirpath" class="btn change-btn" type="button">Save</button> + <a href="#" style="display:none" class="btn btn-link cancel">Cancel</a> + </div> + </form> + <i id="change-subdir" class="icon-pencil"></i> + <span class="icon-trash delete-current-value" data-toggle="tooltip" title="Delete"></span> + </dd> + <dt> + <i class="icon-question-sign get-help" title="The Git branch, tag or commit"></i> + Revision + </dt> + <dd> + <span class="current-value">{{layerversion.get_vcs_reference}}</span> + <form style="display:none;"> + <div class="input-append"> + <input type="text" value="{{layerversion.get_vcs_reference}}"> + <button data-layer-prop="commit" class="btn change-btn" type="button">Save</button> + <a href="#" style="display:none" class="btn btn-link cancel">Cancel</a> + </div> + </form> + <i class="icon-pencil"></i> + </dd> + <dt> + <i class="icon-question-sign get-help" title="Other layers this layer depends upon"></i> + Layer dependencies + </dt> + <dd> + <ul class="unstyled current-value" id="layer-deps-list"> + {% for ld in layerversion.dependencies.all %} + <li data-layer-id="{{ld.depends_on.id}}"> + <a data-toggle="tooltip" title="{{ld.depends_on.layer.vcs_url}} | {{ld.depends_on.get_vcs_reference}}" href="{% url 'layerdetails' project.id ld.depends_on.id %}">{{ld.depends_on.layer.name}}</a> + <span class="icon-trash " data-toggle="tooltip" title="Delete"></span> + </li> + {% endfor %} + </ul> + <div class="input-append add-deps"> + <input type="text" autocomplete="off" data-minLength="1" data-autocomplete="off" placeholder="Type a layer name" id="layer-dep-input"> + <a class="btn" id="add-layer-dependency-btn" > + Add layer + </a> + </div> + <span class="help-block add-deps">You can only add layers Toaster knows about</span> + </dd> + </dl> + </div> + <!-- end layerdetails tab --> + <!-- targets tab --> + <div id="recipes" class="tab-pane"> + <!-- Recipe table --> + <div id="no-recipes-yet" class="alert alert-info" style="display:none"> + <p>Toaster does not have recipe information for the <strong> {{layerversion.layer.name}} </strong> layer.</p> + <p>Toaster learns about layers when you build them. If this layer provides any recipes, they will be listed here after you build the <strong> {{layerversion.layer.name}} </strong> layer.</p> + </div> + + + + {% url 'layerrecipestable' project.id layerversion.id as xhr_table_url %} + {% with "recipestable" as table_name %} + {% with "Recipes" as title %} + {% include 'toastertable-simple.html' %} + {% endwith %} + {% endwith %} + </div> + + <div id="machines" class="tab-pane"> + + <div id="no-machines-yet" class="alert alert-info" style="display:none"> + <p>Toaster does not have machine information for the <strong> {{layerversion.layer.name}} </strong> layer.</p> + <p>Toaster learns about layers when you build them. If this layer provides any machines, they will be listed here after you build the <strong> {{layerversion.layer.name}} </strong> layer.</p> + </div> + + + <!-- Machines table --> + {% url 'layermachinestable' project.id layerversion.id as xhr_table_url %} + {% with "machinestable" as table_name %} + {% with "Machines" as title %} + {% include 'toastertable-simple.html' %} + {% endwith %} + {% endwith %} + </div> + </div> <!-- end tab content --> + </div> <!-- end tabable --> + + <div class="row-fluid span4 well"> <!-- info side panel --> + <h2>About {{layerversion.layer.name}}</h2> + <dl class="item-info"> + + <dt> + Summary + <i class="icon-question-sign get-help" title="One-line description of the layer"></i> + </dt> + <dd> + <span class="muted" style="display:none">Not set</span> + <span class="current-value">{{layerversion.layer.summary|default_if_none:''}}</span> + <form style="display:none; margin-bottom:20px"> + <textarea class="span12" rows="2">{% if layerversion.layer.summary %}{{layerversion.layer.summary}}{% endif %}</textarea> + <button class="btn change-btn" data-layer-prop="summary" type="button">Save</button> + <a href="#" class="btn btn-link cancel">Cancel</a> + </form> + <i class="icon-pencil"></i> + <span class="icon-trash delete-current-value" data-toggle="tooltip" title="Delete"></span> + </dd> + <dt> + Description + </dt> + <dd> + <span class="muted" style="display:none">Not set</span> + <span class="current-value">{{layerversion.layer.description|default_if_none:''}}</span> + <form style="display:none; margin-bottom:20px"> + <textarea class="span12" rows="6">{% if layerversion.layer.description %}{{layerversion.layer.description}}{% endif %}</textarea> + <button class="btn change-btn" data-layer-prop="description" type="button" >Save</button> + <a href="#" class="btn btn-link cancel">Cancel</a> + </form> + <i class="icon-pencil"></i> + <span class="icon-trash delete-current-value" data-toggle="tooltip" title="Delete"></span> + </dd> + {% if layerversion.layer.up_id %} + <dt>Layer index</dt> + <dd> + <a href="http://layers.openembedded.org/layerindex/branch/{{layerversion.up_branch.name}}/layer/{{layerversion.layer.name}}">layer index link</a> + + </dd> + {% endif %} + + </dl> + </div> + + {% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/machine_btn.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/machine_btn.html new file mode 100644 index 000000000..d2cb55bab --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/machine_btn.html @@ -0,0 +1,8 @@ +<a href="{% url 'project' extra.pid %}?setMachine={{data.name}}" class="btn btn-block layer-exists-{{data.layer_version.id}}" style="margin-top: 5px; display:none"> + Select machine</a> +<button class="btn btn-block layerbtn layer-add-{{data.layer_version.id}}" data-layer='{ "id": {{data.layer_version.id}}, "name": "{{data.layer_version.layer.name}}", "layerdetailurl": "{%url 'layerdetails' extra.pid data.layer_version.id %}"}' data-directive="add"> + <i class="icon-plus"></i> + Add layer + <i title="" class="icon-question-sign get-help" data-original-title="To enable this machine, you must first add the {{data.layer_version.layer.name}} layer to your project"></i> +</button> + diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/mrb_section.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/mrb_section.html new file mode 100644 index 000000000..396fb8edf --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/mrb_section.html @@ -0,0 +1,121 @@ +{% load static %} +{% load projecttags %} +{% load humanize %} + + +{%if mru.count > 0%} + + <div class="page-header"> + <h1> + Latest builds + </h1> + </div> + <div id="latest-builds"> + {% for build in mru %} + <div class="alert {%if build.outcome == build.SUCCEEDED%}alert-success{%elif build.outcome == build.FAILED%}alert-error{%else%}alert-info{%endif%} project-name "> + <span class="label {%if build.outcome == build.SUCCEEDED%}label-success{%elif build.outcome == build.FAILED%}label-important{%else%}label-info{%endif%}"> + <a href={% url 'project' build.project.pk %}> + {{build.project.name}} + </a> + </span> + + <div class="row-fluid"> + <div class="span3 lead"> + {%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %} + <a href="{%url 'builddashboard' build.pk%}" class="{%if build.outcome == build.SUCCEEDED %}success{%else%}error{%endif%}"> + {% endif %} + {% if build.target_set.all.count > 0 %} + <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%} + </span> + {% endif %} + {%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %} + </a> + {% endif %} + </div> + <div class="span2 lead"> + {% if build.completed_on|format_build_date %} + {{ build.completed_on|date:'d/m/y H:i' }} + {% else %} + {{ build.completed_on|date:'H:i' }} + {% endif %} + </div> + {%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %} + <div class="span2 lead"> + {% if build.errors.count %} + <i class="icon-minus-sign red"></i> <a href="{%url 'builddashboard' build.pk%}#errors" class="error">{{build.errors.count}} error{{build.errors.count|pluralize}}</a> + {% endif %} + </div> + <div class="span2 lead"> + {% if build.warnings.count %} + <i class="icon-warning-sign yellow"></i> <a href="{%url 'builddashboard' build.pk%}#warnings" class="warning">{{build.warnings.count}} warning{{build.warnings.count|pluralize}}</a> + {% endif %} + </div> + <div class="lead "> + <span class="lead"> + Build time: <a href="{% url 'buildtime' build.pk %}">{{ build.timespent_seconds|sectohms }}</a> + </span> + <button 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 'projectbuilds' build.project.id as bpi %}{{bpi|json}}, + {{build.project.name|json}}, + {% url 'project' build.project.id as bpurl %}{{bpurl|json}}, + {{build.target_set.all|get_tasks|json}})'> + + Run again + </button> + </div> + {%endif%} + {%if build.outcome == build.IN_PROGRESS %} + <div class="span4"> + <div class="progress" style="margin-top:5px;" data-toggle="tooltip" title="{{build.completeper}}% of tasks complete"> + <div style="width: {{build.completeper}}%;" class="bar"></div> + </div> + </div> + <div class="lead pull-right">{{build.completeper}}% of tasks complete</div> + {%endif%} + </div> + </div> + + {% endfor %} + </div> + +<script> + +function scheduleBuild(url, projectName, projectUrl, buildlist) { + console.log("scheduleBuild"); + libtoaster.startABuild(url, null, buildlist.join(" "), function(){ + console.log("reloading page"); + window.location.reload(); + }, null); +} + +$(document).ready(function(){ + + $(".cancel-build-btn").click(function (){ + var url = $(this).data('request-url'); + var buildIds = $(this).data('build-id'); + var btn = $(this); + + libtoaster.cancelABuild(url, buildIds, function(){ + btn.parents(".alert").fadeOut(); + }, null); + }); +}); + +</script> + +{%endif%} + diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/newproject.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/newproject.html new file mode 100644 index 000000000..997390bcf --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/newproject.html @@ -0,0 +1,130 @@ +{% extends "base.html" %} +{% load projecttags %} +{% load humanize %} +{% block pagecontent %} +<div class="row-fluid"> + <div class="page-header"> + <h1>Create a new project</h1> + </div> + <div class="container-fluid"> + {% if alert %} + <div class="alert alert-error row-fluid" role="alert">{{alert}}</div> + {% endif %} + </div> + + <div class="row-fluid"> + <div class="span6"> + <form method="POST">{% csrf_token %} + + <fieldset> + <label>Project name <span class="muted">(required)</span></label> + <input type="text" class="input-xlarge" required id="new-project-name" name="projectname"> + </fieldset> +<!-- + <fieldset> + <label class="project-form">Project type</label> + <label class="project-form radio"><input type="radio" name="ptype" value="analysis" checked/> Analysis Project</label> + + {% if releases.count > 0 %} + <label class="project-form radio"><input type="radio" name="ptype" value="build" checked /> Build Project</label> + {% endif %} + </fieldset> --> + <input type="hidden" name="ptype" value="build" /> + + {% if releases.count > 0 %} + <fieldset class="release"> + {% if releases.count > 1 %} + <label class="project-form"> + Release + <i class="icon-question-sign get-help" title="The version of the build system you want to use"></i> + </label> + <select name="projectversion" id="projectversion"> + {% for release in releases %} + <option value="{{release.id}}" + {%if defaultbranch == release.name %} + selected + {%endif%} + >{{release.description}}</option> + {% endfor %} + </select> + {% for release in releases %} + <div class="row-fluid helptext" id="description-{{release.id}}" style="display: none"> + <span class="help-block span5">{{release.helptext|safe}}</span> + </div> + {% endfor %} + {% else %} + <input type="hidden" name="projectversion" value="{{releases.0.id}}"/> + {% endif %} + </fieldset> + {% endif %} + + <div class="form-actions"> + <input type="submit" id="create-project-button" class="btn btn-primary btn-large" value="Create project"/> + <span class="help-inline" style="vertical-align:middle;">To create a project, you need to enter a project name</span> + </div> + </form> + </div> + <!-- + <div class="span5 well"> + <span class="help-block"> + <h4>Toaster project types</h4> + <p>With a <strong>build project</strong> you configure and run your builds from Toaster.</p> + <p>With an <strong>analysis project</strong>, the builds are configured and run by another tool + (something like Buildbot or Jenkins), and the project only collects the information about the + builds (packages, recipes, dependencies, logs, etc). </p> + <p>You can read more on <a href="#">how to set up an analysis project</a> + in the Toaster manual.</p> + <h4>Release</h4> + <p>If you create a <strong>build project</strong>, you will need to select a <strong>release</strong>, + which is the version of the build system you want to use to run your builds.</p> + </div> --> + </div> + </div> + + <script type="text/javascript"> + $(document).ready(function () { + // hide the new project button + $("#new-project-button").hide(); + $('.btn-primary').attr('disabled', 'disabled'); + + // enable submit button when all required fields are populated + $("input#new-project-name").on('input', function() { + if ($("input#new-project-name").val().length > 0 ){ + $('.btn-primary').removeAttr('disabled'); + $(".help-inline").css('visibility','hidden'); + } + else { + $('.btn-primary').attr('disabled', 'disabled'); + $(".help-inline").css('visibility','visible'); + } + }); + + // show relevant help text for the selected release + var selected_release = $('select').val(); + $("#description-" + selected_release).show(); + + + $('select').change(function(){ + var new_release = $('select').val(); + $(".helptext").hide(); + $('#description-' + new_release).fadeIn(); + }); + +/* // Hide the project release when you select an analysis project + function projectType() { + if ($("input[type='radio']:checked").val() == 'build') { + $('.release').fadeIn(); + } + else { + $('.release').fadeOut(); + } + } + projectType(); + + $('input:radio').change(function(){ + projectType(); + }); */ + }); + </script> + +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_built_dependencies.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_built_dependencies.html new file mode 100644 index 000000000..e6f20c330 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_built_dependencies.html @@ -0,0 +1,99 @@ +{% extends "package_detail_base.html" %} +{% load projecttags %} + +{% block tabcontent %} + <ul class="nav nav-pills"> + <li class=""> + <a href="{% url 'package_built_detail' build.id package.id %}"> + <i class="icon-question-sign get-help" title="Shows the files produced by this package."></i> + Generated files ({{package.buildfilelist_package.count}}) + </a> + </li> + <li class="active"> + <a href="{% url 'package_built_dependencies' build.id package.id %}"> + <i class="icon-question-sign get-help" title="Shows the runtime packages required by this package."></i> + Runtime dependencies ({{dependency_count}}) + </a> + </li> + </ul> + <div class="tab-content"> + <div class="tab-pane active" id="dependencies"> + {% ifequal runtime_deps|length 0 %} + <div class="alert alert-info"> + <strong>{{package.fullpackagespec}}</strong> has no runtime dependencies. + </div> + {% else %} + <div class="alert alert-info"> + <strong>{{package.fullpackagespec}}</strong> is <strong>not included</strong> in any image. This page shows you the projected runtime dependencies if you include <strong>{{package.fullpackagespec}}</strong> in future builds. + </div> + <table class="table table-bordered table-hover"> + <thead> + <tr> + <th>Package</th> + <th>Version</th> + <th class="sizecol span2">Size</th> + </tr> + </thead> + <tbody> + {% for runtime_dep in runtime_deps %} + <tr {{runtime_dep.size|format_vpackage_rowclass}} > + {% if runtime_dep.size != -1 %} + <td> + <a href="{% url 'package_built_detail' build.id runtime_dep.depends_on_id %}"> + {{runtime_dep.name}} + </a> + </td> + {% else %} + <td> + {{runtime_dep.name|format_vpackage_namehelp}} + </td> + {% endif %} + <td>{{runtime_dep.version}}</td> + <td class="sizecol">{{runtime_dep.size|filtered_filesizeformat}}</td> + </tr> + {% endfor %} + </tbody> + </table> + {% endifequal %} + {% ifnotequal other_deps|length 0 %} + <h3>Other runtime relationships</h3> + <table class="table table-bordered table-hover"> + <thead> + <tr> + <th>Package</th> + <th>Version</th> + <th class="sizecol span2">Size</th> + <th> + <i class="icon-question-sign get-help" title="Five relationship types exist: recommends, suggests, provides, replaces and conflicts"></i> + Relationship type + </th> + </tr> + </thead> + <tbody> + {% for other_dep in other_deps %} + <tr {{other_dep.size|format_vpackage_rowclass}} > + {% if other_dep.size != -1 %} + <td> + <a href="{% url 'package_built_detail' build.id other_dep.depends_on_id %}"> + {{other_dep.name}} + </a> + </td> + {% else %} + <td> + {{other_dep.name|format_vpackage_namehelp}} + </td> + {% endif %} + <td>{{other_dep.version}}</td> + <td class="sizecol">{{other_dep.size|filtered_filesizeformat}}</td> + <td> + {{other_dep.dep_type_display}} + <i class="icon-question-sign get-help hover-help" title="{{other_dep.dep_type_help}}" ></i> + </td> + </tr> + {% endfor %} + </tbody> + </table> + {% endifnotequal %} + </div> <!-- tab-pane --> + </div> <!-- tab-content --> +{% endblock tabcontent %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_built_detail.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_built_detail.html new file mode 100644 index 000000000..9be8ccb85 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_built_detail.html @@ -0,0 +1,65 @@ +{% extends "package_detail_base.html" %} +{% load projecttags %} + +{% block tabcontent %} + {% with packageFileCount=package.buildfilelist_package.count %} + <!-- Generated Files --> + {% if package.buildtargetlist_package.count == 0 %} + {# Not included case #} + <ul class="nav nav-pills"> + <li class="active"> <a href="#"> + <i class="icon-question-sign get-help" title="Files added to a root file system when you include {{package.name}} in an image"></i> + Generated files ({{packageFileCount}}) + </a></li> + <li class=""><a href="{% url 'package_built_dependencies' build.id package.id %}"> + <i class="icon-question-sign get-help" title="Projected runtime dependencies when you include {{package.name}} in an image"></i> + Runtime dependencies ({{dependency_count}}) + </a></li> + </ul> + <div class="tab-content"> + <div class="tab-pane active" id="files"> + <!-- Package file list or if empty, alert pane --> + {% if packageFileCount > 0 %} + <div class="alert alert-info"> + <strong>{{package.fullpackagespec}}</strong> is <strong>not included</strong> in any image. This page shows you the files added to an image root file system if you include <strong>{{package.fullpackagespec}}</strong> in future builds. + </div> + {% include "tablesort.html" %} + <tbody> + {% for file in objects %} + <tr> + <td class="path">{{file.path}}</td> + <td class="filesize sizecol">{{file.size|filtered_filesizeformat}}</td> + </tr> + {% endfor %} + </tbody> + </table> + + {% else %} + <div class="alert alert-info"> + <strong>{{package.fullpackagespec}}</strong> does not generate any files. + </div> + {% endif %} + + </div> <!-- tab-pane active --> + </div> <!-- tab-content --> + {% else %} + {# Included case #} + <div class="tab-content"> + <div class="tab-pane active"> + <div class="lead well"> + Package included in: + {% for itarget in package.buildtargetlist_package.all|dictsort:"target.target" %} + <a href="{% url 'package_included_detail' build.id itarget.target.id package.id %}"> + {% if forloop.counter0 > 0 %} + , + {% endif %} + {{itarget.target.target}} + </a> + {% endfor %} + </div> + </div> <!-- tab-pane active --> + </div> <!-- tab-content --> + {% endif %} + + {% endwith %} +{% endblock tabcontent %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_detail_base.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_detail_base.html new file mode 100644 index 000000000..a24bc8e43 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_detail_base.html @@ -0,0 +1,142 @@ +{% extends "basebuilddetailpage.html" %} +{% load projecttags %} + +{% block extraheadcontent %} + <!-- functions to format package 'installed_package' alias --> + <script> + function fmtAliasHelp(package_name, alias, hover) { + var r = null; + if (alias != null && alias != '') { + r = '<span class="muted"> as ' + alias + ' '; + r += '<i class="icon-question-sign get-help'; + if (hover) { + r+= ' hover-help'; + } + else { + r+= ' heading-help'; + } + r += '"'; + title = package_name + ' was renamed at packaging time and was installed on your system as ' + alias; + r += ' title="' + title + '">'; + r += '</i>'; + r += '</span>'; + document.write(r); + } + } + </script> +{% endblock extraheadcontent %} +{% block localbreadcrumb %} + {% if target %} + <li><a href="{% url "target" build.id target.id %}">{{target.target}}</a></li> + <li>{{package.fullpackagespec}} {% if package.alias %} as {{package.alias}}{% endif %}</li> + {% else %} + <li><a href="{% url "packages" build.id %}"> Packages </a></li> + <li>{{package.fullpackagespec}}</li> + {% endif %} +{% endblock localbreadcrumb %} + +{% block pagedetailinfomain %} + <div class="row span11"> + <div class="page-header"> + {% block title %} + <h1>{{package.fullpackagespec}}</h1> + {% endblock title %} + </div> <!-- page-header --> + </div> <!-- row span11 page-header --> + + {% block twocolumns %} + <div class="row span7 tabbable"> + {% block tabcontent %} + {% endblock tabcontent %} + </div> <!-- row span7 --> + + <div class="row span4 well"> + <h2>Package information</h2> + + <!-- info presented as definition list --> + <dl class="item-info"> + <dt> + Size + <i class="icon-question-sign get-help" title="The size of the package"></i> + </dt> + <dd> + {% comment %} + if recipe is absent, filesize is not 0 + {% endcomment %} + {% if package.recipe_id > 0 %} + {{package.size|filtered_filesizeformat}} + {% if target.file_size %} + ({{package.size|multiply:100|divide:target.file_size}}% of included package size) + {% endif %} + + {% endif %} + </dd> + + <dt> + License + <i class="icon-question-sign get-help" title="The license under which this package is distributed"></i> + </dt> + <dd>{{package.license}}</dd> + + {% comment %} + # Removed per review on 1/18/2014 until license data population + # problemse are resolved. + <dt> + License files + <i class="icon-question-sign get-help" title="Path to the license files that apply to the package"></i> + </dt> + <dd></dd> + {% endcomment %} + + <dt> + Recipe + <i class="icon-question-sign get-help" title="The name of the recipe building this package"></i> + </dt> + <dd> + {% if package.recipe_id > 0 %} + <a href="{% url "recipe" build.id package.recipe_id %}"> {{package.recipe.name}} </a> + {% else %} + {{package.recipe.name}} + {% endif %} + </dd> + + <dt> + Recipe version + <i class="icon-question-sign get-help" title="The version of the recipe building this package"></i> + </dt> + <dd>{{package.recipe.version}}</dd> + + <dt> + Layer + <i class="icon-question-sign get-help" title="The name of the layer providing the recipe that builds this package"></i> + </dt> + <dd> + {{package.recipe.layer_version.layer.name}} + {% if package.recipe.layer_version.layer.name|format_none_and_zero != "" %} + {% comment %} + # Removed per team meeting of 1/29/2014 until + # decision on index search algorithm + <a href="http://layers.openembedded.org" target="_blank"> + <i class="icon-share get-info"></i> + </a> + {% endcomment %} + {% endif %} + </dd> + {% if package.recipe.layer_version.branch %} + <dt> + Layer branch + <i class="icon-question-sign get-help" title="The Git branch of the layer providing the recipe that builds this package"></i> + </dt> + <dd>{{package.recipe.layer_version.branch}}</dd> + {% endif %} + <dt> + Layer commit + <i class="icon-question-sign get-help" title="The Git commit of the layer providing the recipe that builds this package"></i> + </dt> + + <dd class="iscommit">{{package.recipe.layer_version.commit}}</dd> + + </dl> + </div> <!-- row4 well --> + {% endblock twocolumns %} +{% endblock pagedetailinfomain %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_dependencies.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_dependencies.html new file mode 100644 index 000000000..642ca6956 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_dependencies.html @@ -0,0 +1,110 @@ +{% extends "package_detail_base.html" %} +{% load projecttags %} + +{% block title %} + <h1> + {{package.fullpackagespec}} + <script> fmtAliasHelp("{{package.name}}", "{{package.alias}}", false) </script> + <small>({{target.target}})</small> + </h1> +{% endblock title %} + +{% block tabcontent %} + {% with packageFileCount=package.buildfilelist_package.count %} + {% include "package_included_tabs.html" with active_tab="dependencies" %} + <div class="tab-content"> + <div class="tab-pane active" id="dependencies"> + {% ifnotequal runtime_deps|length 0 %} + <table class="table table-bordered table-hover"> + <thead> + <tr> + <th>Package</th> + <th>Version</th> + <th class='sizecol span2'>Size</th> + </tr> + </thead> + <tbody> + {% for runtime_dep in runtime_deps %} + <tr {{runtime_dep.size|format_vpackage_rowclass}} > + {% if runtime_dep.size != -1 %} + <td> + <a href="{% url 'package_included_detail' build.id target.id runtime_dep.depends_on_id %}"> + {{runtime_dep.name}} + </a> + <script>fmtAliasHelp("{{runtime_dep.name}}", "{{runtime_dep.alias}}", true)</script> + </td> + {% else %} + <td> + {{runtime_dep.name|format_vpackage_namehelp}} + </td> + {% endif %} + <td>{{runtime_dep.version}} </td> + <td class='sizecol'>{{runtime_dep.size|filtered_filesizeformat}} </td> + </tr> + {% endfor %} + </tbody> + </table> + {% else %} + <div class="alert alert-info"> + <strong>{{package.fullpackagespec}}</strong> has no runtime dependencies. + </div> + {% endifnotequal %} + + {% ifnotequal other_deps|length 0 %} + <h3>Other runtime relationships</h3> + <table class="table table-bordered table-hover"> + <thead> + <tr> + <th>Package</th> + <th>Version</th> + <th class='sizecol span2'>Size</th> + <th> + <i class="icon-question-sign get-help" title="Five relationship types exist: recommends, suggests, provides, replaces and conflicts"></i> + Relationship type + </th> + </tr> + </thead> + <tbody> + {% for other_dep in other_deps %} + {% if other_dep.installed %} + <tr {{other_dep.size|format_vpackage_rowclass}}> + {% if other_dep.size != -1 %} + <td> + <a href="{% url 'package_included_detail' build.id target.id other_dep.depends_on_id %}"> + {{other_dep.name}} + <script> + fmtAliasHelp("{{other_dep.name}}","{{other_dep.alias}}", true) + </script> + </a> + </td> + {% else %} + <td> + {{other_dep.name|format_vpackage_namehelp}} + </td> + {% endif %} + <td>{{other_dep.version}} </td> + <td class='sizecol'>{{other_dep.size|filtered_filesizeformat}} </td> + <td> + {{other_dep.dep_type_display}} + <i class="icon-question-sign get-help hover-help" title="{{other_dep.dep_type_help}}" ></i> + </td> + </tr> + {% else %} + <tr class="muted"> + <td>{{other_dep.name}}</td> + <td>{{other_dep.version}}</td> + <td></td> + <td> + {{other_dep.dep_type_display}} + <i class="icon-question-sign get-help hover-help" title="{{other_dep.dep_type_help}}" ></i> + </td> + </tr> + {% endif %} + {% endfor %} + </tbody> + </table> + {% endifnotequal %} + </div> <!-- end tab-pane --> + </div> <!-- end tab content --> + {% endwith %} +{% endblock tabcontent %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_detail.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_detail.html new file mode 100644 index 000000000..d2aa26eef --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_detail.html @@ -0,0 +1,44 @@ +{% extends "package_detail_base.html" %} +{% load projecttags %} + +{% block title %} + <h1> + {{package.fullpackagespec}} + <script> + fmtAliasHelp("{{package.name}}", "{{package.alias}}", false) + </script> + <small>({{target.target}})</small> + </h1> +{% endblock title %} + +{% block tabcontent %} +{% with packageFileCount=package.buildfilelist_package.count %} + {% include "package_included_tabs.html" with active_tab="detail" %} + <div class="tab-content"> + <div class="tab-pane active" id="files"> + {% if packageFileCount > 0 %} + {% include "tablesort.html" %} + <tbody> + {% for file in objects %} + <tr> + <td class="path"> + <a href="{% url 'dirinfo_filepath' build.id target.id file.path %}"> + {{file.path}} + </a> + </td> + <td class="filesize sizecol" >{{file.size|filtered_filesizeformat}}</td> + </tr> + {% endfor %} + </tbody> + </table> + + {% else %} + <div class="alert alert-info"> + <strong>{{package.fullpackagespec}}</strong> does not generate any files. + </div> + {% endif %} + </div> <!-- end tab-pane --> + </div> <!-- end tab content --> + +{% endwith %} +{% endblock tabcontent %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_reverse_dependencies.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_reverse_dependencies.html new file mode 100644 index 000000000..5cc8b47a6 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_reverse_dependencies.html @@ -0,0 +1,50 @@ +{% extends "package_detail_base.html" %} +{% load projecttags %} + +{% block title %} + <h1> + {{package.fullpackagespec}} + <script> fmtAliasHelp("{{package.name}}", "{{package.alias}}", false) </script> + <small>({{target.target}})</small> + </h1> +{% endblock title %} + +{% block tabcontent %} + {% with packageFileCount=package.buildfilelist_package.count %} + {% include "package_included_tabs.html" with active_tab="reverse" %} + <div class="tab-content"> + <div class="tab-pane active" id="brought-in-by"> + + {% ifequal reverse_count 0 %} + <div class="alert alert-info"> + <strong>{{package.fullpackagespec}}</strong> has no reverse runtime dependencies. + </div> + {% else %} + {% include "tablesort.html" %} + <tbody> + {% for reverse_dep in objects %} + <tr {% if reverse_dep.size %}{{reverse_dep.size|format_vpackage_rowclass}}{%endif%} > + {% if reverse_dep.size != -1 %} + <td> + <a href="{% url 'package_included_detail' build.id target.id reverse_dep.package_id %}"> + {{reverse_dep.package.name}} + </a> + <script>fmtAliasHelp("{{reverse_dep.package.name}}", "{{reverse_dep.alias}}", true)</script> + </td> + {% else %} + <td> + {{reverse_dep.name|format_vpackage_namehelp}} + </td> + {% endif %} + + <td>{{reverse_dep.package.version}} </td> + <td class='sizecol'>{{reverse_dep.package.size|filtered_filesizeformat}} </td> + </tr> + {% endfor %} + </tbody> + </table> + {% endifequal %} + </div> <!-- end tab-pane --> + </div> <!-- end tab content --> + {% endwith %} +{% endblock tabcontent %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_tabs.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_tabs.html new file mode 100644 index 000000000..958aa8827 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_tabs.html @@ -0,0 +1,33 @@ + + <ul class="nav nav-pills"> + {% if active_tab == "detail" %} + <li class="active"> + {% else %} + <li class=""> + {% endif %} + <a href="{% url 'package_included_detail' build.id target.id package.id %}"> + <i class="icon-question-sign get-help" title="The files this package adds to the image root file system"></i> + Files in root file system ({{packageFileCount}}) + </a> + </li> + {% if active_tab == "dependencies" %} + <li class="active"> + {% else %} + <li class=""> + {% endif %} + <a href="{% url 'package_included_dependencies' build.id target.id package.id %}"> + <i class="icon-question-sign get-help" title="Package runtime dependencies"></i> + Runtime dependencies ({{dependency_count}}) + </a> + </li> + {% if active_tab == "reverse" %} + <li class="active"> + {% else %} + <li class=""> + {% endif %} + <a href="{% url 'package_included_reverse_dependencies' build.id target.id package.id %}"> + <i class="icon-question-sign get-help" title="The package runtime reverse dependencies (i.e. the packages in this image that depend on this package). Reverse dependencies reflect only the 'depends' dependency type"></i> + Reverse runtime dependencies ({{reverse_count}}) + </a> + </li> + </ul> diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/project.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/project.html new file mode 100644 index 000000000..e8354fd67 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/project.html @@ -0,0 +1,130 @@ +{% extends "baseprojectpage.html" %} + +{% load projecttags %} +{% load humanize %} +{% load static %} + +{% block projectinfomain %} + +<script src="{% static 'js/layerDepsModal.js' %}"></script> +<script src="{% static 'js/projectpage.js' %}"></script> +<script> + $(document).ready(function (){ + var ctx = { + testReleaseChangeUrl: "{% url 'xhr_testreleasechange' project.id %}", + }; + + try { + projectPageInit(ctx); + } catch (e) { + document.write("Sorry, An error has occurred loading this page"); + console.warn(e); + } + }); +</script> + +<div id="change-release-modal" class="modal hide fade in" tabindex="-1" role="dialog" aria-labelledby="change-release-modal" aria-hidden="false"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button> + <h3>Changing Yocto Project release to <span class="proposed-release-change-name"></span></h3> + </div> + <div class="modal-body"> + <p>The following added layers do not exist for <span class="proposed-release-change-name"></span>: </p> + <ul id="layers-to-remove-list"> + </ul> + <p>If you change the Yocto Project release to <span class="proposed-release-change-name"></span>, the above layers will be deleted from your added layers.</p> + </div> + <div class="modal-footer"> + <button id="change-release-and-rm-layers" data-dismiss="modal" type="submit" class="btn btn-primary">Change release and delete layers</button> + <button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button> + </div> +</div> + + +<div class="row-fluid" id="project-page" style="display:none"> + <div class="span6"> + <div class="well well-transparent" id="machine-section"> + <h3>Machine</h3> + + <p class="lead"><span id="project-machine-name"></span> <i title="" data-original-title="" id="change-machine-toggle" class="icon-pencil"></i></p> + + <form id="select-machine-form" style="display:none;"> + <div class="alert alert-info"> + <strong>Machine changes have a big impact on build outcome.</strong> You cannot really compare the builds for the new machine with the previous ones. + </div> + + <div class="input-append"> + <input id="machine-change-input" autocomplete="off" value="" data-provide="typeahead" data-minlength="1" data-autocomplete="off" type="text"> + <button id="machine-change-btn" class="btn" type="button">Save</button> <a href="#" id="cancel-machine-change" class="btn btn-link">Cancel</a> + </div> + + <p><a href="{% url 'projectmachines' project.id %}" class="link">View compatible machines</a></p> + </form> + </div> + + <div class="well well-transparent"> + <h3>Most built recipes</h3> + + <div class="alert alert-info" style="display:none" id="no-most-built"> + <span class="lead">You haven't built any recipes yet</span> + <p style="margin-top: 10px;"><a href="{% url 'projecttargets' project.id %}">Choose a recipe to build</a></p> + </div> + + <ul class="unstyled configuration-list" id="freq-build-list"> + </ul> + <button class="btn btn-primary" id="freq-build-btn" disabled="disabled">Build selected recipes</button> + </div> + + <div class="well well-transparent"> + <h3>Project release</h3> + + <p class="lead"><span id="project-release-title"></span> <i title="" data-original-title="" id="release-change-toggle" class="icon-pencil"></i></p> + + <form class="form-inline" id="change-release-form" style="display:none;"> + <select></select> + <button class="btn" style="margin-left:5px;" id="change-release-btn">Change</button> <a href="#" id="cancel-release-change" class="btn btn-link">Cancel</a> + </form> + </div> + </div> + + <div class="span6"> + <div class="well well-transparent" id="layer-container"> + <h3>Layers <span class="muted counter">(<span id="project-layers-count"></span>)</span> + <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/current/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> + </h3> + + <div class="alert lead" id="no-layers-in-project" style="display:none"> + You need to add some layers. For that you can: + <ul> + <li><a href="{% url 'projectlayers' project.id %}">View all layers compatible with this project</a></li> + <li><a href="{% url 'importlayer' project.id %}">Import a layer</a></li> + <li><a href="http://www.yoctoproject.org/docs/current/dev-manual/dev-manual.html#understanding-and-creating-layers" target="_blank">Read about layers in the documentation</a></li> + </ul> + <p>Or type a layer name below.</p> + </div> + + <form style="margin-top:20px"> + <!--div class="control-group error"--> + + <div class="input-append"> + <input id="layer-add-input" autocomplete="off" placeholder="Type a layer name" data-minlength="1" data-autocomplete="off" data-provide="typeahead" data-source="" type="text"> + <button id="add-layer-btn" class="btn" disabled>Add</button> + </div> + + <div id="import-alert" class="alert alert-info" style="display:none;"> + Toaster does not know about this layer. Please <a href="#">import it</a> + </div> + + <p> + <a href="{% url 'projectlayers' project.id %}" id="view-compatible-layers">View compatible layers</a> + <i data-original-title="View all the layers you can build with the release selected for this project, which is Yocto Project master" class="icon-question-sign get-help" title=""></i> + | <a href="{% url 'importlayer' project.id %}">Import layer</a> + </p> + </form> + + <ul class="unstyled configuration-list" id="layers-in-project-list"> + </ul> + </div> + </div> +</div> +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectbuilds.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectbuilds.html new file mode 100644 index 000000000..df809de40 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectbuilds.html @@ -0,0 +1,103 @@ +{% extends "baseprojectbuildspage.html" %} +{% load projecttags %} +{% load humanize %} + + +{% block extraheadcontent %} +<link rel="stylesheet" href="/static/css/jquery-ui.min.css" type='text/css'> +<link rel="stylesheet" href="/static/css/jquery-ui.structure.min.css" type='text/css'> +<link rel="stylesheet" href="/static/css/jquery-ui.theme.min.css" type='text/css'> +<script src="/static/js/jquery-ui.min.js"></script> +<script src="/static/js/filtersnippet.js"></script> +{% endblock %} + +{% block projectinfomain %} + +<script> + // initialize the date range controls + $(document).ready(function () { + date_init('created','{{last_date_from}}','{{last_date_to}}','{{dateMin_started_on}}','{{dateMax_started_on}}','{{daterange_selected}}'); + date_init('updated','{{last_date_from}}','{{last_date_to}}','{{dateMin_completed_on}}','{{dateMax_completed_on}}','{{daterange_selected}}'); + }); +</script> + + <h2> + {% if request.GET.filter and objects.paginator.count > 0 or request.GET.search and objects.paginator.count > 0 %} + {{objects.paginator.count}} build{{objects.paginator.count|pluralize}} found + {%elif request.GET.filter and objects.paginator.count == 0 or request.GET.search and objects.paginator.count == 0 %} + No builds found + {%else%} + Project builds + {%endif%} + <i class="icon-question-sign get-help heading-help" title="This page lists all the builds for the current project"></i> + </h2> + + + {% if objects.paginator.count == 0 %} + {% if request.GET.filter or request.GET.search %} + <div class="row-fluid"> + <div class="alert"> + <form class="no-results input-append" id="searchform"> + <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 %} + <button class="btn" type="submit" value="Search">Search</button> + <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all builds</button> + </form> + </div> + </div> + {% else %} + <div class="alert alert-info"> + <p class="lead"> + This project has no builds. + </p> + </div> + {% endif %} + + {% else %} + + {% include "basetable_top.html" %} + <!-- Table data rows; the order needs to match the order of "tablecols" definitions; and the <td class value needs to match the tablecols clclass value for show/hide buttons to work --> + {% for build in objects %} {# if we have a build, just display it #} + <tr class="data"> + <td class="outcome"><a href="{% url "builddashboard" build.id %}">{%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%}</a> + {% if build.project %} + <a href="{% url 'build_artifact' build.id "cookerlog" build.id %}"> + <i class="icon-download-alt" title="" data-original-title="Download build log"></i> + </a> + {% endif %} + </td> + + <td class="target">{% for t in build.target_set.all %} <a href="{% url "builddashboard" build.id %}"> {{t.target}} </a> <br />{% endfor %}</td> + <td class="machine"><a href="{% url "builddashboard" build.id %}">{{build.machine}}</a></td> + <td class="started_on"><a href="{% url "builddashboard" build.id %}">{{build.started_on|date:"d/m/y H:i"}}</a></td> + <td class="completed_on"><a href="{% url "builddashboard" build.id %}">{{build.completed_on|date:"d/m/y H:i"}}</a></td> + <td class="failed_tasks error"> + {% query build.task_build outcome=4 order__gt=0 as exectask%} + {% if exectask.count == 1 %} + <a href="{% url "task" build.id exectask.0.id %}">{{exectask.0.recipe.name}}.{{exectask.0.task_name}}</a> + <a href="{% url 'build_artifact' build.id "tasklogfile" exectask.0.id %}"> + <i class="icon-download-alt" title="" data-original-title="Download task log file"></i> + </a> + {% elif exectask.count > 1%} + <a href="{% url "tasks" build.id %}?filter=outcome%3A4">{{exectask.count}} task{{exectask.count|pluralize}}</a> + {%endif%} + </td> + <td class="errors.count"> + {% if build.errors.count %} + <a class="errors.count error" href="{% url "builddashboard" build.id %}#errors">{{build.errors.count}} error{{build.errors.count|pluralize}}</a> + {%endif%} + </td> + <td class="warnings.count">{% if build.warnings.count %}<a class="warnings.count warning" href="{% url "builddashboard" build.id %}#warnings">{{build.warnings.count}} warning{{build.warnings.count|pluralize}}</a>{%endif%}</td> + <td class="time"><a href="{% url "buildtime" build.id %}">{{build.timespent_seconds|sectohms}}</a></td> + <td class="output"> + {% if build.outcome == build.SUCCEEDED %} + <a href="{%url "builddashboard" build.id%}#images">{{fstypes|get_dict_value:build.id}}</a> + {% endif %} + </td> + </tr> + {% endfor %} + + + {% include "basetable_bottom.html" %} +{% endif %} + +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectconf.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectconf.html new file mode 100644 index 000000000..4c5a188a8 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectconf.html @@ -0,0 +1,849 @@ +{% extends "baseprojectpage.html" %} +{% load projecttags %} +{% load humanize %} + + +{% block projectinfomain %} + +<h2>Bitbake variables</h2> + + <div style="padding-left:19px;"> + + <dl class="dl-vertical"> + {% if distro_defined %} + <dt> + <span class="js-config-var-name js-config-var-managed-name">DISTRO</span> + <i class="icon-question-sign get-help" title="The short name of the distribution. If the variable is blank, meta/conf/distro/defaultsetup.conf will be used. <br /><a href='http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-DISTRO' target='_blank'>Read more in the manual</a>"></i> + </dt> + <dd class="lead"> + <span id="distro">{{distro}}</span> + <i class="icon-pencil" id="change-distro-icon"></i> + <form id="change-distro-form" style="display:none;"> + <div class="input-append"> + <span id="edit-distro-name-div" class="control-group"> + <input type="text" id="new-distro" value="{{distro}}"> + <button id="apply-change-distro" class="btn" type="button">Save</button> + <button id="cancel-change-distro" type="button" class="btn btn-link">Cancel</button> + </span> + <span class="help-block error" id="distro-error-message"></span> + </div> + </form> + </dd> + {% endif %} + + {% if fstypes_defined %} + <dt> + <span class="js-config-var-name js-config-var-managed-name">IMAGE_FSTYPES</span> + <i class="icon-question-sign get-help" title="Formats of root file system images that you want to have created <br /><a href='http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-IMAGE_FSTYPES' target='_blank'>Read more in the manual</a>"></i> + </dt> + <dd class="lead"> + <span id="image_fstypes">{{fstypes}}</span> + <i class="icon-pencil" id="change-image_fstypes-icon"></i> + <form id="change-image_fstypes-form" style="display:none;"> + <input id="filter-image_fstypes" type="text" placeholder="Search image types" class="span4"> + <div id="all-image_fstypes" class="scrolling"> + </div> + <button id="apply-change-image_fstypes" type="button" class="btn">Save</button> + <button id="cancel-change-image_fstypes" type="button" class="btn btn-link">Cancel</button> + </form> + </dd> + {% endif %} + + {% if image_install_append_defined %} + <dt> + <span class="js-config-var-name js-config-var-managed-name">IMAGE_INSTALL_append</span> + <i class="icon-question-sign get-help" title="Specifies additional packages to install into an image. If your build creates more than one image, the packages will be installed in <strong>all of them</strong> <br /><a href='http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-IMAGE_INSTALL' target='_blank'>Read more in the manual</a>"></i> + </dt> + <dd class="lead"> + <span id="image_install"{% if image_install_append %}{%else%} class="muted"{%endif%}>{% if image_install_append %}{{image_install_append}}{%else%}Not set{%endif%}</span> + <i class="icon-pencil" id="change-image_install-icon"></i> + <i class="icon-trash" id="delete-image_install-icon" {% if image_install_append %}{%else%}style="display:none;"{%endif%}></i> + <form id="change-image_install-form" style="display:none;"> + <div class="row-fluid"> + <span class="help-block span4">To set IMAGE_INSTALL_append to more than one package, type the package names separated by a space.</span> + </div> + <div class="input-append"> + <input type="text" class="input-xlarge" id="new-image_install" placeholder="Type one or more package names"> + <button id="apply-change-image_install" class="btn" type="button">Save</button> + <button id="cancel-change-image_install" type="button" class="btn btn-link">Cancel</button> + </div> + </form> + </dd> + {% endif %} + + {% if package_classes_defined %} + <dt> + <span class="js-config-var-name js-config-var-managed-name">PACKAGE_CLASSES</span> + <i class="icon-question-sign get-help" title="Specifies the package manager to use when packaging data <br /><a href='http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-PACKAGE_CLASSES' target='_blank'>Read more in the manual</a>"></i> + </dt> + <dd class="lead"> + <span id="package_classes">{{package_classes}}</span> + <i id="change-package_classes-icon" class="icon-pencil"></i> + <form id="change-package_classes-form" style="display:none;"> + <label> + Root file system package format + <i class="icon-question-sign get-help" title="The package format used to generate the root file system. Options are <code>dev</code>, <code>ipk</code> and <code>rpm</code>"></i> + </label> + <select id="package_classes-select"> + <option>package_deb</option> + <option>package_ipk</option> + <option>package_rpm</option> + </select> + <label> + Additional package formats + <i class="icon-question-sign get-help" title="Extra package formats to build"></i> + </label> + <label class="checkbox" id="package_class_1"> + <input type="checkbox" id="package_class_1_input"> package_deb + </label> + <label class="checkbox" id="package_class_2"> + <input type="checkbox" id="package_class_2_input"> package_ipk + </label> + <div style="padding-top:10px;"> + <button id="apply-change-package_classes" type="button" class="btn">Save</button> + <button id="cancel-change-package_classes" type="button" class="btn btn-link">Cancel</button> + </div> + </form> + </dd> + {% endif %} + + {% if sdk_machine_defined %} + <dt> + <span class="js-config-var-name js-config-var-managed-name">SDKMACHINE</span> + <i class="icon-question-sign get-help" title="Specifies the architecture (i.e. i686 or x86_64) for which to build SDK and ADT items <br /><a href='http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-SDKMACHINE' target='_blank'>Read more in the manual</a>"></i> + </dt> + <dd class="lead"> + <span id="sdkmachine">{{sdk_machine}}</span> + <i id="change-sdkmachine-icon" class="icon-pencil"></i> + <form id="change-sdkmachine-form" style="display:none;"> + <label class="radio"> + <input type="radio" name="sdkmachine" value="i686"> + i686 + </label> + <label class="radio"> + <input type="radio" name="sdkmachine" value="x86_64"> + x86_64 + </label> + <div style="padding-top:10px;"> + <button id="apply-change-sdkmachine" type="button" class="btn">Save</button> + <button id="cancel-change-sdkmachine" type="button" class="btn btn-link">Cancel</button> + </div> + </form> + </dd> + {% endif %} + + </dl> + + <!-- <ul class="unstyled configuration-list" id="configvar-list"> --> + <dl id="configvar-list"> + <!-- the added configuration variables are inserted here --> + </dl> + + <!-- pass the fstypes list, black list, and externally managed variables here --> + {% for fstype in vars_fstypes %} + <input type="hidden" class="js-checkbox-fstypes-list" value="{{fstype}}"> + {% endfor %} + {% for b in vars_blacklist %} + <input type="hidden" class="js-config-blacklist-name" value="{{b}}"> + {% endfor %} + {% for b in vars_managed %} + <input type="hidden" class="js-config-managed-name" value="{{b}}"> + {% endfor %} + + <div class="row-fluid"> + <form id="variable-form"> + <fieldset style="padding-left:0px;"> + <legend>Add variable</legend> + <div class="span3" style="margin-left:0px;"> + <span id="add-configvar-name-div" class="control-group"> + <label> + Variable + <i title="" class="icon-question-sign get-help" + data-original-title="Variable names are case sensitive, + cannot have spaces, and can only include letters, numbers, underscores + and dashes"></i> + </label> + <input type="text" placeholder="Type variable name" id="variable"> + <span class="help-block error" id="new-variable-error-message"></span> + </span> + <label>Value</label> + <input id="value" type="text" placeholder="Type variable value"><p> + <div> + <button id="add-configvar-button" class="btn save" type="button" disabled>Add variable</button> + </div> + </div> + <div class="span5 help-block"> + <h5>Some variables are reserved from Toaster</h5> + <p>Toaster cannot set any variables that impact 1) the configuration of the build servers, + or 2) where artifacts produced by the build are stored. Such variables include: </p> + <p> + <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-BB_DISKMON_DIRS" target="_blank">BB_DISKMON_DIRS</a></code> + <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-BB_NUMBER_THREADS" target="_blank">BB_NUMBER_THREADS</a></code> + <code>CVS_PROXY_HOST</code> + <code>CVS_PROXY_PORT</code> + <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-DL_DIR" target="_blank">DL_DIR</a></code> + <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-PARALLEL_MAKE" target="_blank">PARALLEL_MAKE</a></code> + <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-SSTATE_DIR" target="_blank">SSTATE_DIR</a></code> + <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-SSTATE_MIRRORS" target="_blank">SSTATE_MIRRORS</a></code> + <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-TMPDIR" target="_blank">TMPDIR</a></code></p> + <p>Plus the following standard shell environment variables:</p> + <p><code>http_proxy</code> <code>ftp_proxy</code> <code>https_proxy</code> <code>all_proxy</code></p> + </div> + </fieldset> + </form> + </div> + + </div> + + <script> + + // global variables + var do_reload=false; + + // validate new variable name + function validate_new_variable() { + var variable = $("input#variable").val(); + var value = $("input#value").val(); + + // presumed innocence + $('#new-variable-error-message').text(""); + var error_msg = ""; + + var existing_configvars = document.getElementsByClassName('js-config-var-name'); + for (var i = 0, length = existing_configvars.length; i < length; i++) { + if (existing_configvars[i].innerHTML.toUpperCase() == variable.toUpperCase()) { + error_msg = "This variable is already set in this page, edit its value instead"; + } + } + + var blacklist_configvars = document.getElementsByClassName('js-config-blacklist-name'); + for (var i = 0, length = blacklist_configvars.length; i < length; i++) { + if (blacklist_configvars[i].value.toUpperCase() == variable.toUpperCase()) { + error_msg = "You cannot edit this variable in Toaster because it is set by the build servers"; + } + } + + var managed_configvars = document.getElementsByClassName('js-config-managed-name'); + for (var i = 0, length = managed_configvars.length; i < length; i++) { + if (managed_configvars[i].value.toUpperCase() == variable.toUpperCase()) { + error_msg = "You cannot set this variable here. Please set it in the <a href=\"{% url 'project' project.id %}\">project main page</a>"; + } + } + + var bad_chars = /[^a-zA-Z0-9\-_]/.test(variable); + var has_spaces = (0 <= variable.indexOf(" ")); + var only_spaces = (0 < variable.length) && (0 == variable.trim().length); + + if (only_spaces) { + error_msg = "A valid variable name cannot include spaces"; + } else if (bad_chars && has_spaces) { + error_msg = "A valid variable name can only include letters, numbers, underscores, dashes, and cannot include spaces"; + } else if (bad_chars) { + error_msg = "A valid variable name can only include letters, numbers, underscores, and dashes"; + } + + if ("" != error_msg) { + $('#new-variable-error-message').html(error_msg); + $(".save").attr("disabled","disabled"); + + // add one (and only one) error class append + var d = document.getElementById("add-configvar-name-div"); + d.className = d.className.replace(" error",""); + d.className = d.className + " error"; + + return false; + } else if (0 == variable.length) { + $(".save").attr("disabled","disabled"); + return false; + } + + var d = document.getElementById("add-configvar-name-div"); + d.className = d.className.replace(" error",""); + + // now set the "Save" enablement if 'value' also passes + if (value.trim().length > 0) { + $(".save").removeAttr("disabled"); + } else { + $(".save").attr("disabled","disabled"); + } + + return true; + } + + // validate distro name + function validate_distro_name() { + var value = $("input#new-distro").val(); + + // presumed innocence + $('#distro-error-message').text(""); + var error_msg = ""; + + var has_spaces = (0 <= value.indexOf(" ")); + + if (has_spaces) { + error_msg = "A valid distro name cannot include spaces"; + } else if (0 == value.length) { + error_msg = " "; + } + + if ("" != error_msg) { + $('#distro-error-message').text(error_msg); + $("#apply-change-distro").attr("disabled","disabled"); + + // add one (and only one) error class append + var d = document.getElementById("edit-distro-name-div"); + d.className = d.className.replace(" error",""); + d.className = d.className + " error"; + + return false; + } + + var d = document.getElementById("edit-distro-name-div"); + d.className = d.className.replace(" error",""); + $("#apply-change-distro").removeAttr("disabled"); + return true; + } + + // Test to insure at least one FS Type is checked + function enableFsTypesSave() { + var any_checked = 0; + $(".fs-checkbox-fstypes:checked").each(function(){ + any_checked = 1; + }); + if ( 0 == any_checked ) { + $("#apply-change-image_fstypes").attr("disabled","disabled"); + } + else { + $("#apply-change-image_fstypes").removeAttr("disabled"); + } + } + + // Preset or reset the Package Class checkbox labels + function updatePackageClassCheckboxes() { + $('#package_class_1, #package_class_2').hide(); + if ($('select').val() == 'package_deb') { + $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_ipk'); + $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_rpm'); + } + if ($('select').val() == 'package_ipk') { + $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_deb'); + $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_rpm'); + } + if ($('select').val() == 'package_rpm') { + $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_deb'); + $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_ipk'); + } + $('#package_class_1, #package_class_2').fadeIn(1500); + } + + // Re-assert handlers when the page is served and/or refreshed via Ajax + function setEventHandlersForDynamicElements() { + + // change variable value + $('.js-icon-pencil-config_var').click(function (evt) { + var pk = evt.target.attributes["x-data"].value; + var current_val = $("span#config_var_value_"+pk).text(); + $('.js-icon-pencil-config_var, .js-icon-trash-config_var, #config_var_value_'+pk).hide(); + $("#change-config_var-form_"+pk).slideDown(); + $("input#new-config_var_"+pk).val(current_val); + }); + + $('.js-cancel-change-config_var').click(function (evt) { + var pk = evt.target.attributes["x-data"].value; + $("#change-config_var-form_"+pk).slideUp(function() { + $('.js-icon-pencil-config_var, .js-icon-trash-config_var, #config_var_value_'+pk).show(); + }); + }); + + $(".js-new-config_var").on('input', function(){ + if ($(this).val().length == 0) { + $(".js-apply-change-config_var").attr("disabled","disabled"); + } + else { + $(".js-apply-change-config_var").removeAttr("disabled"); + } + }); + + $('.js-apply-change-config_var').click(function (evt) { + var xdata = evt.target.attributes["x-data"].value.split(":"); + var pk = xdata[0]; + var variable = xdata[1]; + var val = $('#new-config_var_'+pk).val(); + postEditAjaxRequest({"configvarChange" : variable+':'+val}); + $('#config_var_value_'+pk).parent().removeClass('muted'); + $("#change-config_var-form_"+pk).slideUp(function() { + $('.js-icon-pencil-config_var, .js-icon-trash-config_var, #config_var_value_'+pk).show(); + }); + }); + + // delete variable + $(".js-icon-trash-config_var").click(function (evt) { + var xdata = evt.target.attributes["x-data"].value.split(":"); + var pk = xdata[0]; + + // hide the dangling trash tooltip + $('#config_var_trash_'+pk).hide(); + + // fade out the variable+value div, then refresh the variable list + $('#config_var_entry_'+pk).parent().parent().fadeOut(1000, function(){ + postEditAjaxRequest({"configvarDel": evt.target.attributes["x-data"].value}); + }); + + }); + + } + + function onEditPageUpdate(data) { + // update targets + var i; var orightml = ""; + + var configvars_sorted = data.configvars.sort(function(a, b){return a[0] > b[0]}); + + var managed_configvars = document.getElementsByClassName('js-config-var-managed-name'); + + for (i = 0; i < configvars_sorted.length; i++) { + // skip if the variable name has a special context (not user defined) + var var_context=undefined; + for (var j = 0, length = managed_configvars.length; j < length; j++) { + if ((managed_configvars[j].innerHTML == configvars_sorted[i][0]) || + (managed_configvars[j].value == configvars_sorted[i][0]) ) { + var_context='m'; + } + } + if (var_context == undefined) { + orightml += '<div> <dt><span id="config_var_entry_'+configvars_sorted[i][2]+'" class="js-config-var-name"></span><i class="icon-trash js-icon-trash-config_var" id="config_var_trash_'+configvars_sorted[i][2]+'" x-data="'+configvars_sorted[i][2]+'"></i> </dt>' + orightml += '<dd class="lead">' + orightml += ' <span id="config_var_value_'+configvars_sorted[i][2]+'"></span>' + orightml += ' <i class="icon-pencil js-icon-pencil-config_var" x-data="'+configvars_sorted[i][2]+'"></i>' + orightml += ' <form id="change-config_var-form_'+configvars_sorted[i][2]+'" style="display:none;">' + orightml += ' <div class="input-append">' + orightml += ' <input type="text" class="input-xlarge js-new-config_var" id="new-config_var_'+configvars_sorted[i][2]+'" value="">' + orightml += ' <button class="btn js-apply-change-config_var" type="button" x-data="'+configvars_sorted[i][2]+':'+configvars_sorted[i][0]+'" disabled>Save</button>' + orightml += ' <button type="button" class="btn btn-link js-cancel-change-config_var" x-data="'+configvars_sorted[i][2]+'">Cancel</button>' + orightml += ' </div>' + orightml += ' </form>' + orightml += '</dd> </div>' + } + } + + // update configvars list HTML framework + $("dl#configvar-list").html(orightml); + + // insert the name/value pairs safely as non-HTML + for (i = 0; i < configvars_sorted.length; i++) { + $('#config_var_entry_'+configvars_sorted[i][2]).text(configvars_sorted[i][0]); + $('#config_var_value_'+configvars_sorted[i][2]).text(configvars_sorted[i][1]); + } + + // Add the tooltips + $(".js-icon-trash-config_var").each( function(){ setDeleteTooltip($(this)); }); + $(".js-icon-pencil-config_var").each(function(){ setChangeTooltip($(this)); }); + + // re-assert these event handlers + setEventHandlersForDynamicElements(); + } + + function onEditAjaxSuccess(data, textstatus) { + // console.log("XHR returned:", data, "(" + textstatus + ")"); + if (data.error != "ok") { + alert("error on request:\n" + data.error); + return; + } + + // delayed page reload? + if (do_reload) { + do_reload=false; + location.reload(true); + } else { + onEditPageUpdate(data); + } + } + + function onEditAjaxError(jqXHR, textstatus, error) { + alert("XHR errored:\n" + error + "\n(" + textstatus + ")"); + // re-assert the event handlers + } + + /* ensure cookie exists {% csrf_token %} */ + function postEditAjaxRequest(reqdata) { + var ajax = $.ajax({ + type:"POST", + data: $.param(reqdata), + url:"{% url 'xhr_configvaredit' project.id%}", + headers: { 'X-CSRFToken': $.cookie("csrftoken")}, + success: onEditAjaxSuccess, + error: onEditAjaxError, + }) + } + + function setDeleteTooltip(object) { + object.tooltip({ container: 'body', html: true, delay: {show: 400}, title: "Delete" }); + } + function setChangeTooltip(object) { + object.tooltip({ container: 'body', html: true, delay: {show: 400}, title: "Change" }); + } + + $(document).ready(function() { + + // + // Register handlers for static elements + // + + {% if distro_defined %} + // change distro variable + $('#change-distro-icon').click(function() { + $('#change-distro-icon, #distro').hide(); + $("#change-distro-form").slideDown(); + $("#new-distro").val( $('#distro').text() ); + }); + + $('#cancel-change-distro').click(function(){ + $("#change-distro-form").slideUp(function() { + $('#distro, #change-distro-icon').show(); + + // reset any dangling error state + $('#distro-error-message').text(""); + var d = document.getElementById("edit-distro-name-div"); + d.className = d.className.replace(" error",""); + }); + }); + + // validate new distro name + $("input#new-distro").on('input', function (evt) { + validate_distro_name(); + }); + + $('#apply-change-distro').click(function(){ + //$('#repo').parent().removeClass('highlight-go'); + var name = $('#new-distro').val(); + postEditAjaxRequest({"configvarChange" : 'DISTRO:'+name}); + $('#distro').text(name); + $("#change-distro-form").slideUp(function () { + $('#distro, #change-distro-icon').show(); + }); + }); + {% endif %} + + + {% if fstypes_defined %} + // change IMAGE_FSTYPES variable + + $('#change-image_fstypes-icon').click(function() { + $('#change-image_fstypes-icon, #image_fstypes').hide(); + $("#change-image_fstypes-form").slideDown(); + // avoid false substring matches by including space separators + var html = ""; + var fstypes = " " + document.getElementById("image_fstypes").innerHTML + " "; + var fstypes_list = document.getElementsByClassName('js-checkbox-fstypes-list'); + // Add the checked boxes first + if (" " != fstypes) { + for (var i = 0, length = fstypes_list.length; i < length; i++) { + if (0 <= fstypes.indexOf(" "+fstypes_list[i].value+" ")) { + html += '<label class="checkbox"><input type="checkbox" class="fs-checkbox-fstypes" value="'+fstypes_list[i].value+'" checked="checked">'+fstypes_list[i].value+'</label>\n'; + } + } + } + // Add the un-checked boxes second + for (var i = 0, length = fstypes_list.length; i < length; i++) { + if (0 > fstypes.indexOf(" "+fstypes_list[i].value+" ")) { + html += '<label class="checkbox"><input type="checkbox" class="fs-checkbox-fstypes" value="'+fstypes_list[i].value+'">'+fstypes_list[i].value+'</label>\n'; + } + } + document.getElementById("all-image_fstypes").innerHTML = html; + + // Watch elements to disable Save when none are checked + $(".fs-checkbox-fstypes").each(function(){ + $(this).click(function() { + enableFsTypesSave(); + }); + }); + + // clear the previous filter values + $("input#filter-image_fstypes").val(""); + }); + + $('#cancel-change-image_fstypes').click(function(){ + $("#change-image_fstypes-form").slideUp(function() { + $('#image_fstypes, #change-image_fstypes-icon').show(); + }); + }); + + $('#filter-image_fstypes').on('input', function(){ + var valThis = $(this).val().toLowerCase(); + $('#all-image_fstypes label').each(function(){ + var text = $(this).text().toLowerCase(); + var match = text.indexOf(valThis); + if (match >= 0) { + $(this).show(); + } + else { + $(this).hide(); + } + }); + }); + + $('#apply-change-image_fstypes').click(function(){ + // extract the selected fstypes and sort them + var fstypes_array = []; + var checkboxes = document.getElementsByClassName('fs-checkbox-fstypes'); + $(".fs-checkbox-fstypes:checked").each(function(){ + fstypes_array.push($(this).val()); + }); + fstypes_array.sort(); + + // now make a string of them + var fstypes = ''; + for (var i = 0, length = fstypes_array.length; i < length; i++) { + fstypes += fstypes_array[i] + ' '; + } + fstypes = fstypes.trim(); + + postEditAjaxRequest({"configvarChange" : 'IMAGE_FSTYPES:'+fstypes}); + $('#image_fstypes').text(fstypes); + $('#image_fstypes').parent().removeClass('muted'); + + $("#change-image_fstypes-form").slideUp(function() { + $('#image_fstypes, #change-image_fstypes-icon').show(); + }); + }); + {% endif %} + + + {% if image_install_append_defined %} + + // init IMAGE_INSTALL_append trash icon + setDeleteTooltip($('#delete-image_install-icon')); + + // change IMAGE_INSTALL_append variable + $('#change-image_install-icon').click(function() { + // preset the edit value + var current_val = $("span#image_install").text().trim(); + if (current_val == "Not set") { + current_val=""; + $("#apply-change-image_install").attr("disabled","disabled"); + } else { + // insure these non-empty values have single space prefix + current_val=" " + current_val; + } + $("input#new-image_install").val(current_val); + + $('#change-image_install-icon, #delete-image_install-icon, #image_install').hide(); + $("#change-image_install-form").slideDown(); + }); + + $('#cancel-change-image_install').click(function(){ + $("#change-image_install-form").slideUp(function() { + $('#image_install, #change-image_install-icon').show(); + if ($("span#image_install").text() != "Not set") { + $('#delete-image_install-icon').show(); + setDeleteTooltip($('#delete-image_install-icon')); + } + }); + }); + + $("#new-image_install").on('input', function(){ + if ($(this).val().trim().length == 0) { + $("#apply-change-image_install").attr("disabled","disabled"); + } + else { + $("#apply-change-image_install").removeAttr("disabled"); + } + }); + + $('#apply-change-image_install').click(function(){ + // insure these non-empty values have single space prefix + var value = " " + $('#new-image_install').val().trim(); + postEditAjaxRequest({"configvarChange" : 'IMAGE_INSTALL_append:'+value}); + $('#image_install').text(value); + $('#image_install').removeClass('muted'); + $("#change-image_install-form").slideUp(function () { + $('#image_install, #change-image_install-icon').show(); + if (value.length > -1) { + $('#delete-image_install-icon').show(); + setDeleteTooltip($('#delete-image_install-icon')); + } + }); + }); + + // delete IMAGE_INSTALL_append variable value + $('#delete-image_install-icon').click(function(){ + $(this).tooltip('hide'); + postEditAjaxRequest({"configvarChange" : 'IMAGE_INSTALL_append:'+''}); + $('#image_install').parent().fadeOut(1000, function(){ + $('#image_install').addClass('muted'); + $('#image_install').text('Not set'); + $('#delete-image_install-icon').hide(); + $('#image_install').parent().fadeIn(1000); + }); + }); + {% endif %} + + + {% if package_classes_defined %} + // change PACKAGE_CLASSES variable + $('#change-package_classes-icon').click(function() { + $('#change-package_classes-icon, #package_classes').hide(); + $("#change-package_classes-form").slideDown(); + + // initialize the pulldown and checkboxes + var value = $("#package_classes").text(); + if ( value.indexOf("package_deb") == 0 ) { + $("#package_classes-select").prop('selectedIndex', 0); + updatePackageClassCheckboxes(); + if ( value.indexOf("_ipk") > 0 ) { + $("#package_class_1_input").attr("checked",true); + } + if ( value.indexOf("_rpm") > 0 ) { + $("#package_class_2_input").attr("checked",true); + } + } + + if ( value.indexOf("package_ipk") == 0 ) { + $("#package_classes-select").prop('selectedIndex', 1); + updatePackageClassCheckboxes(); + if ( value.indexOf("_deb") > 0 ) { + $("#package_class_1_input").attr("checked",true); + } + if ( value.indexOf("_rpm") > 0 ) { + $("#package_class_2_input").attr("checked",true); + } + } + + if ( value.indexOf("package_rpm") == 0 ) { + $("#package_classes-select").prop('selectedIndex', 2); + updatePackageClassCheckboxes(); + if ( value.indexOf("_deb") > 0 ) { + $("#package_class_1_input").attr("checked",true); + } + if ( value.indexOf("_ipk") > 0 ) { + $("#package_class_2_input").attr("checked",true); + } + } + }); + + $('#cancel-change-package_classes').click(function(){ + $("#change-package_classes-form").slideUp(function() { + $('#package_classes, #change-package_classes-icon').show(); + }); + }); + + $('select').change(function() { + updatePackageClassCheckboxes(); + }); + + $('#apply-change-package_classes').click(function(){ + var e = document.getElementById("package_classes-select"); + var val = e.options[e.selectedIndex].text; + + pc1_checked = document.getElementById("package_class_1_input").checked; + pc2_checked = document.getElementById("package_class_2_input").checked; + if (val == "package_deb") { + if (pc1_checked) val = val + " package_ipk"; + if (pc2_checked) val = val + " package_rpm"; + } + if (val == "package_ipk") { + if (pc1_checked) val = val + " package_deb"; + if (pc2_checked) val = val + " package_rpm"; + } + if (val == "package_rpm") { + if (pc1_checked) val = val + " package_deb"; + if (pc2_checked) val = val + " package_ipk"; + } + + $('#package_classes').text(val); + //$('#package_classes').parent().removeClass('muted'); + postEditAjaxRequest({"configvarChange" : 'PACKAGE_CLASSES:'+val}); + $("#change-package_classes-form").slideUp(function() { + $('#package_classes, #change-package_classes-icon').show(); + }); + }); + {% endif %} + + + {% if sdk_machine_defined %} + // change SDKMACHINE variable + $('#change-sdkmachine-icon').click(function() { + var current_value = document.getElementById("sdkmachine").innerHTML; + var radios = document.getElementsByName('sdkmachine'); + for (var i = 0, length = radios.length; i < length; i++) { + radios[i].checked = false; + if (radios[i].value == current_value) { + radios[i].checked = true; + } + } + $('#change-sdkmachine-icon, #sdkmachine').hide(); + $("#change-sdkmachine-form").slideDown(); + }); + + $('#cancel-change-sdkmachine').click(function(){ + $("#change-sdkmachine-form").slideUp(function() { + $('#sdkmachine, #change-sdkmachine-icon').show(); + }); + }); + + $('#apply-change-sdkmachine').click(function(){ + var value=""; + var radios = document.getElementsByName('sdkmachine'); + for (var i = 0, length = radios.length; i < length; i++) { + if (radios[i].checked) { + // do whatever you want with the checked radio + value=radios[i].value; + break; + } + } + postEditAjaxRequest({"configvarChange" : 'SDKMACHINE:'+value}); + $('#sdkmachine').text(value); + $("#change-sdkmachine-form").slideUp(function() { + $('#sdkmachine, #change-sdkmachine-icon').show(); + }); + + }); + {% endif %} + + + // add new variable + $("button#add-configvar-button").click( function (evt) { + var variable = $("input#variable").val(); + var value = $("input#value").val(); + + postEditAjaxRequest({"configvarAdd" : variable+':'+value}); + + // clear the previous values + $("input#variable").val(""); + $("input#value").val(""); + // Disable add button + $(".save").attr("disabled","disabled"); + + // Reload page if admin-removed core managed value is manually added back in + if (0 <= " DISTRO IMAGE_FSTYPES IMAGE_INSTALL_append PACKAGE_CLASSES SDKMACHINE ".indexOf( " "+variable+" " )) { + // delayed reload to avoid race condition with postEditAjaxRequest + do_reload=true; + } + }); + + // validate new variable name and value + $("#variable, #value").on('input', function() { + validate_new_variable(); + }); + + // + // draw and register the dynamic configuration variables and handlers + // + + var data = { + configvars : [] + }; + {% for c in configvars %} + data.configvars.push([ "{{c.name}}","{{c.value}}","{{c.pk}}" ]); + {% if '' != vars_context|get_dict_value:c.name %} + data.vars_context[ "{{c.name}}" ] = "{{vars_context|get_dict_value:c.name }}"; + {% endif %} + {% endfor %} + + // draw these elements and assert their event handlers + onEditPageUpdate(data); + }); + + </script> + +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/projects.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/projects.html new file mode 100644 index 000000000..c2d77b5a3 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/projects.html @@ -0,0 +1,77 @@ +{% extends "base.html" %} + +{% load static %} +{% load projecttags %} +{% load humanize %} + +{% block pagecontent %} + + + <div class="page-header top-air"> + <h1> + {% if request.GET.filter and objects.paginator.count > 0 or request.GET.search and objects.paginator.count > 0 %} + {{objects.paginator.count}} project{{objects.paginator.count|pluralize}} found + {%elif request.GET.filter and objects.paginator.count == 0 or request.GET.search and objects.paginator.count == 0 %} + No projects found + {%else%} + All projects + {%endif%} + </h1> + </div> + + {% if objects.paginator.count == 0 %} + <div class="row-fluid"> + <div class="alert"> + <form class="no-results input-append" id="searchform"> + <input id="search" name="search" class="input-xxlarge" type="text" value=" + {% if request.GET.search %} + {{request.GET.search}} + {% endif %}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %} + <button class="btn" type="submit" value="Search">Search</button> + <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all projects</button> + </form> + </div> + </div> + + {% else %} {# We have builds to display #} + {% include "basetable_top.html" %} + {% for o in objects %} + <tr class="data"> + <td><a href="{% url 'project' o.id %}">{{o.name}}</a></td> + <td class="updated"><a href="{% url 'project' o.id %}">{{o.updated|date:"d/m/y H:i"}}</a></td> + <td> + {% if o.release %} + <a href="{% url 'project' o.id %}#project-details">{{o.release.name}}</a> + {% else %} + No release available + {% endif %} + </td> + <td><a href="{% url 'project' o.id %}#machine-distro">{{o.get_current_machine_name}}</a></td> + {% if o.get_number_of_builds == 0 %} + <td class="muted">{{o.get_number_of_builds}}</td> + <td class="loutcome"></td> + <td class="ltarget"></td> + <td class="lerrors"></td> + <td class="lwarnings"></td> + <td class="limagefiles"></td> + {% else %} + <td><a href="{% url 'projectbuilds' o.id %}">{{o.get_number_of_builds}}</a></td> + <td class="loutcome"><a href="{% url "builddashboard" o.get_last_build_id %}">{%if o.get_last_outcome == build_SUCCEEDED%}<i class="icon-ok-sign success"></i>{%elif o.get_last_outcome == build_FAILED%}<i class="icon-minus-sign error"></i>{%else%}{%endif%}</a></td> + <td class="ltarget"><a href="{% url "builddashboard" o.get_last_build_id %}">{{o.get_last_target}} </a></td> + <td class="lerrors">{% if o.get_last_errors %}<a class="errors.count error" href="{% url "builddashboard" o.get_last_build_id %}#errors">{{o.get_last_errors}} error{{o.get_last_errors|pluralize}}</a>{%endif%}</td> + <td class="lwarnings">{% if o.get_last_warnings %}<a class="warnings.count warning" href="{% url "builddashboard" o.get_last_build_id %}#warnings">{{o.get_last_warnings}} warning{{o.get_last_warnings|pluralize}}</a>{%endif%}</td> + <td class="limagefiles"> + {% if o.get_last_outcome == build_SUCCEEDED %} + <a href="{%url "builddashboard" o.get_last_build_id %}#images">{{fstypes|get_dict_value:o.id}}</a> + {% endif %} + </td> + + {% endif %} + </tr> + {% endfor %} + {% include "basetable_bottom.html" %} + {% endif %} {# empty #} + +{% endblock %} + + diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/projecttopbar.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/projecttopbar.html new file mode 100644 index 000000000..ca2741daf --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/projecttopbar.html @@ -0,0 +1,47 @@ +<div class="alert alert-success lead" id="project-created-notification" style="margin-top:15px; display:none"> + <button type="button" class="close" data-dismiss="alert">×</button> + Your project <strong>{{project.name}}</strong> has been created. You can now <a href="{% url 'projectmachines' project.id %}">select your target machine</a> and <a href="{% url 'projecttargets' project.id %}">choose image recipes</a> to build. +</div> + +<!-- project name --> +<div class="page-header"> + <h1><span id="project-name">{{project.name}}</span> + <i class="icon-pencil" data-original-title="" id="project-change-form-toggle" title=""></i> + </h1> + <form id="project-name-change-form" style="margin-bottom: 0px; display: none;"> + <div class="input-append"> + <input class="huge input-xxlarge" type="text" id="project-name-change-input" autocomplete="off" value="{{project.name}}"> + <button id="project-name-change-btn" class="btn btn-large" type="button">Save</button> + <a href="#" id="project-name-change-cancel" class="btn btn-large btn-link">Cancel</a> + </div> + </form> +</div> + +<div id="project-topbar"> + <ul class="nav nav-pills"> + <li> + <a href="{% url 'projectbuilds' project.id %}"> + Builds (<span class="total-builds">0</span>) + </a> + </li> + <li id="topbar-configuration-tab"> + <a href="{% url 'project' project.id %}"> + Configuration + </a> + </li> + <li> + <a href="{% url 'importlayer' project.id %}"> + Import layer + </a> + </li> + <li class="pull-right"> + <form class="form-inline" style="margin-bottom:0px;"> + <i class="icon-question-sign get-help heading-help" data-placement="left" title="" data-original-title="Type the name of one or more recipes you want to build, separated by a space. You can also specify a task by appending a semicolon and a task name to the recipe name, like so: <code>busybox:clean</code>"></i> + <div class="input-append"> + <input id="build-input" type="text" class="input-xlarge input-lg build-target-input" placeholder="Type the recipe you want to build" autocomplete="off" disabled> + <button id="build-button" class="btn btn-primary btn-large build-button" data-project-id="{{project.id}}" disabled>Build</button> + </div> + </form> + </li> + </ul> +</div> diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe.html new file mode 100644 index 000000000..b5e4192d6 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe.html @@ -0,0 +1,242 @@ +{% extends "basebuilddetailpage.html" %} + +{% load projecttags %} + +{% block localbreadcrumb %} +<li><a href="{% url 'recipes' build.pk %}">Recipes</a></li> +<li>{{object.name}}_{{object.version}} </li> +{% endblock %} + +{% block pagedetailinfomain %} + +<!-- Begin container --> + +<div class="row span11"> + <div class="page-header"> + <h1>{{object.name}}_{{object.version}}</h1> + </div> +</div> + +<div class="row span7 tabbable"> + <ul class="nav nav-pills"> + <li class="{{tab_states.1}}"> + <a href="#information" data-toggle="tab"> + <i class="icon-question-sign get-help" title="Build-related information about the recipe"></i> + Recipe details + </a> + </li> + <li> + <a href="{% url "recipe_packages" build.pk object.id %}"> + <i class="icon-question-sign get-help" title="The packaged output resulting from building the recipe"></i> + Packages ({{package_count}}) + </a> + </li> + <li class="{{tab_states.3}}"> + <a href="#dependencies" data-toggle="tab"> + <i class="icon-question-sign get-help" title="The recipe build-time dependencies (i.e. other recipes)"></i> + Build dependencies ({{object.r_dependencies_recipe.all.count}}) + </a> + </li> + <li class="{{tab_states.4}}"> + <a href="#brought-in-by" data-toggle="tab"> + <i class="icon-question-sign get-help" title="The recipe build-time reverse dependencies (i.e. the recipes that depend on this recipe)"></i> + Reverse build dependencies ({{object.r_dependencies_depends.all.count}}) + </a> + </li> + </ul> + <div class="tab-content"> + <div class="tab-pane {{tab_states.1}}" id="information"> + <dl class="dl-horizontal"> + <dt> + <i class="icon-question-sign get-help" title="The name of the layer providing the recipe"></i> + Layer + </dt> + <dd>{{layer.name}}</dd> + + <dt> + <i class="icon-question-sign get-help" title="Path to the recipe .bb file"></i> + Recipe file + </dt> + <dd><code>{{object.file_path}} {% if object.pathflags %}<i>({{object.pathflags}})</i>{% endif %}</code></dd> + {% if layer_version.branch %} + <dt> + <i class="icon-question-sign get-help" title="The Git branch of the layer providing the recipe"></i> + Layer branch + </dt> + <dd>{{layer_version.branch}}</dd> + {% endif %} + <dt> + <i class="icon-question-sign get-help" title="The Git commit of the layer providing the recipe"></i> + Layer commit + </dt> + <dd class="iscommit">{{layer_version.commit}}</dd> + </dl> + + <h2 class="details">Tasks</h2> + {% if not tasks %} + <div class="alert alert-info"> + <strong>{{object.name}}_{{object.version}}</strong> does not have any tasks in this build. + </div> + {% else %} + <table class="table table-bordered table-hover"> + <thead> + <tr> + <th> + <i class="icon-question-sign get-help" title="The running sequence of each task in the build"></i> + Order + </th> + <th> + <i class="icon-question-sign get-help" title="The name of the task"></i> + Task + </th> + <th> + <i class="icon-question-sign get-help" title="This value tells you if a task had to run (executed) in order to generate the task output, or if the output was provided by another task and therefore the task didn't need to run (not executed)"></i> + Executed + </th> + <th> + <i class="icon-question-sign get-help" title="This column tells you if 'executed' tasks succeeded or failed. The column also tells you why 'not executed' tasks did not need to run"></i> + Outcome + </th> + <th> + <i class="icon-question-sign get-help" title="This column tells you if a task tried to restore output from the <code>sstate-cache</code> directory or mirrors, and reports the result: Succeeded, Failed or File not in cache"></i> + Cache attempt + </th> + </tr> + </thead> + <tbody> + + {% for task in tasks %} + + <tr {{ task|task_color }} > + + <td><a {{ task|task_color }} href="{% url "task" build.pk task.pk %}">{{task.order}}</a></td> + <td> + <a {{ task|task_color }} href="{% url "task" build.pk task.pk %}">{{task.task_name}}</a> + {% if task.get_description %}<i class="icon-question-sign get-help hover-help" title="" data-original-title="{{task.get_description}}"></i> {% endif %} + </td> + + <td><a {{ task|task_color }} href="{% url "task" build.pk task.pk %}">{{task.get_executed_display}}</a></td> + + <td> + <a {{ task|task_color }} href="{% url "task" build.pk task.pk %}">{{task.get_outcome_display}} </a> + {% if task.outcome = task.OUTCOME_FAILED %} + <a href="{% url 'build_artifact' build.pk "tasklogfile" task.pk %}"> + <i class="icon-download-alt" title="Download task log file"></i> + </a> + {% endif %} + <i class="icon-question-sign get-help hover-help" title="{{task.get_outcome_help}}"></i> + </td> + <td> + {% ifnotequal task.sstate_result task.SSTATE_NA %} + <a {{ task|task_color }} href="{% url "task" build.pk task.pk %}">{{task.get_sstate_result_display}}</a> + {% endifnotequal %} + </td> + + </tr> + + {% endfor %} + </tbody> + </table> + {% endif %} + </div> + <div class="tab-pane {{tab_states.3}}" id="dependencies"> + + {% if not object.r_dependencies_recipe.all %} + <div class="alert alert-info"> + <strong>{{object.name}}_{{object.version}}</strong> has no build dependencies. + </div> + {% else %} + <table class="table table-bordered table-hover"> + <thead> + <tr> + <th> + Recipe + </th> + <th> + Version + </th> + </tr> + </thead> + <tbody> + + {% for rr in object.r_dependencies_recipe.all|dictsort:"depends_on.name" %} + <tr> + <td><a href="{% url "recipe" build.pk rr.depends_on.pk %}">{{rr.depends_on.name}}</a></td> + <td><a href="{% url "recipe" build.pk rr.depends_on.pk %}">{{rr.depends_on.version}}</a></td> + </tr> + {% endfor %} + + </tbody> + </table> + {% endif %} + + </div> + <div class="tab-pane {{tab_states.4}}" id="brought-in-by"> + + {% if not object.r_dependencies_depends.all %} + <div class="alert alert-info"> + <strong>{{object.name}}_{{object.version}}</strong> has no reverse build dependencies. + </div> + {% else %} + <table class="table table-bordered table-hover"> + <thead> + <tr> + <th> + Recipe + </th> + <th> + Version + </th> + </tr> + </thead> + <tbody> + + {% for rr in object.r_dependencies_depends.all|dictsort:"recipe.name" %} + <tr> + <td><a href="{% url "recipe" build.pk rr.recipe.pk %}">{{rr.recipe.name}}</a></td> + <td><a href="{% url "recipe" build.pk rr.recipe.pk %}">{{rr.recipe.version}}</a></td> + </tr> + {% endfor %} + + </tbody> + </table> + {% endif %} + + </div> + </div> +</div> + +<div class="row span4 well"> + <h2>About {{object.name}}</h2> + <dl class="item-info"> + {% if object.summary %} + <dt>Summary</dt> + <dd>{{object.summary}}</dd> + {% endif %} + {% if object.description %} + <dt>Description</dt> + <dd>{{object.description}}</dd> + {% endif %} + {% if object.homepage %} + <dt>Homepage</dt> + <dd><a href="{{object.homepage}}">{{object.homepage}}</a></dd> + {% endif %} + {% if object.bugtracker %} + <dt>Bugtracker</dt> + <dd><a href="{{object.bugtracker}}">{{object.bugtracker}}</a></dd> + {% endif %} + {% if object.section %} + <dt> + Section + <i class="icon-question-sign get-help" title="The section in which recipes should be categorized"></i> + </dt> + <dd>{{object.section}}</dd> + {% endif %} + {% if object.license %} + <dt>License</dt> + <dd>{{object.license}}</dd> + {% endif %} + </dl> +</div> + +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe_btn.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe_btn.html new file mode 100644 index 000000000..77c1b235b --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe_btn.html @@ -0,0 +1,8 @@ +<button data-recipe-name="{{data.name}}" class="btn btn-block layer-exists-{{data.layer_version.pk}} build-recipe-btn" style="display:none; margin-top: 5px;" > + Build recipe +</button> +<button class="btn btn-block layerbtn layer-add-{{data.layer_version.pk}}" data-layer='{ "id": {{data.layer_version.pk}}, "name": "{{data.layer_version.layer.name}}", "layerdetailurl": "{%url 'layerdetails' extra.pid data.layer_version.pk%}"}' data-directive="add"> + <i class="icon-plus"></i> + Add layer + <i title="" class="icon-question-sign get-help" data-original-title="To build this target, you must first add the {{data.layer_version.layer.name}} layer to your project"></i> +</button> diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe_packages.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe_packages.html new file mode 100644 index 000000000..d25847bc0 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe_packages.html @@ -0,0 +1,123 @@ +{% extends "basebuilddetailpage.html" %} + +{% load projecttags %} +{% load humanize %} +{% block localbreadcrumb %} +<li><a href="{% url 'recipes' build.pk %}">Recipes</a></li> +<li>{{recipe.name}}_{{recipe.version}} </li> +{% endblock %} + +{% block pagedetailinfomain %} + +<!-- Begin container --> + +<div class="row-fluid span11"> + <div class="page-header"> + <h1>{{recipe.name}}_{{recipe.version}}</h1> + </div> +</div> + +<div class="row-fluid span7 tabbable"> + <ul class="nav nav-pills"> + <li> + <a href="{% url "recipe" build.pk recipe.id "1" %}"> + <i class="icon-question-sign get-help" title="Build-related information about the recipe"></i> + Recipe details + </a> + </li> + <li class="active"> + <a href="#packages-built" data-toggle="tab"> + <i class="icon-question-sign get-help" title="The packaged output resulting from building the recipe"></i> + Packages ({{object_count}}) + </a> + </li> + <li> + <a href="{% url "recipe" build.pk recipe.id "3" %}"> + <i class="icon-question-sign get-help" title="The recipe build-time dependencies (i.e. other recipes)"></i> + Build dependencies ({{recipe.r_dependencies_recipe.all.count}}) + </a> + </li> + <li> + <a href="{% url "recipe" build.pk recipe.id "4" %}"> + <i class="icon-question-sign get-help" title="The recipe build-time reverse dependencies (i.e. the recipes that depend on this recipe)"></i> + Reverse build dependencies ({{recipe.r_dependencies_depends.all.count}}) + </a> + </li> + </ul> + <div class="tab-content"> +{# <div class="tab-pane active" id="packages-built" name="packages-built">#} + <div class="tab-pane active" id="packages-built"> + {% if not objects and not request.GET.search %} + <div class="alert alert-info"> + <strong>{{recipe.name}}_{{recipe.version}}</strong> does not build any packages. + </div> + + {% elif not objects %} + {# have empty search results, no table nor pagination #} + {% with "packages" as search_what %} + {% include "detail_search_header.html" %} + {% endwith %} + + {% else %} + + + {% with "packages" as search_what %} + {% include "detail_search_header.html" %} + {% endwith %} + <table class="table table-bordered table-hover tablesorter" id="otable"> + {% include "detail_sorted_header.html" %} + + <tbody> + {% for package in objects %} + + <tr> + <td><a href="{% url "package_built_detail" build.pk package.pk %}">{{package.name}}</a></td> + <td><a href="{% url "package_built_detail" build.pk package.pk %}">{{package.version}}_{{package.revision}}</a></td> + <td class="sizecol"><a href="{% url "package_built_detail" build.pk package.pk %}">{{package.size|filtered_filesizeformat}}</a></td> + </tr> + + {% endfor %} + + {% endif %} + {% if objects %} + </tbody> + </table> + {% include "detail_pagination_bottom.html" %} + {% endif %} + </div> {# tab-pane #} + </div> {# tab-content #} +</div> {# span7 #} + +<div class="row span4 well"> + <h2>About {{recipe.name}}</h2> + <dl class="item-info"> + {% if recipe.summary %} + <dt>Summary</dt> + <dd>{{recipe.summary}}</dd> + {% endif %} + {% if recipe.description %} + <dt>Description</dt> + <dd>{{recipe.description}}</dd> + {% endif %} + {% if recipe.homepage %} + <dt>Homepage</dt> + <dd><a href="{{recipe.homepage}}">{{recipe.homepage}}</a></dd> + {% endif %} + {% if recipe.bugtracker %} + <dt>Bugtracker</dt> + <dd><a href="{{recipe.bugtracker}}">{{recipe.bugtracker}}</a></dd> + {% endif %} + {% if recipe.section %} + <dt> + Section + <i class="icon-question-sign get-help" title="The section in which recipes should be categorized"></i> + </dt> + <dd>{{recipe.section}}</dd> + {% endif %} + {% if recipe.license %} + <dt>License</dt> + <dd>{{recipe.license}}</dd> + {% endif %} + </dl> +</div> +{% endblock pagedetailinfomain %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipes.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipes.html new file mode 100644 index 000000000..5cdac437c --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipes.html @@ -0,0 +1,112 @@ +{% extends "basebuildpage.html" %} + +{% load projecttags %} + +{% block localbreadcrumb %} +<li>Recipes</li> +{% endblock %} + +{% block nav-recipes %} + <li class="active"><a href="{% url 'recipes' build.pk %}">Recipes</a></li> +{% endblock %} + +{% block buildinfomain %} +<div class="span10"> +<div class="page-header"> +<h1> + {% if request.GET.search and objects.paginator.count > 0 %} + {{objects.paginator.count}} recipe{{objects.paginator.count|pluralize}} found + {%elif request.GET.search and objects.paginator.count == 0%} + No recipes found + {%else%} + Recipes + {%endif%} + </h1> +</div> + +{% if objects.paginator.count == 0 %} + <div class="row-fluid"> + <div class="alert"> + <form class="no-results input-append" id="searchform"> + <input id="search" name="search" class="input-xxlarge" type="text" value="{%if request.GET.search%}{{request.GET.search}}{%endif%}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %} + <button class="btn" type="submit" value="Search">Search</button> + <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all recipes</button> + </form> + </div> + </div> + +{% else %} +{% include "basetable_top.html" %} + + {% for recipe in objects %} + + <tr class="data"> + <td class="recipe__name"> + <a href="{% url "recipe" build.pk recipe.pk %}">{{recipe.name}}</a> + </td> + <td class="recipe__version"> + <a href="{% url "recipe" build.pk recipe.pk %}">{{recipe.version}}</a> + </td> + <!-- Depends --> + <td class="depends_on"> + {% with deps=recipe_deps|get_dict_value:recipe.pk %} + {% with count=deps|length %} + {% if count %} + <a class="btn" + title="<a href='{% url "recipe" build.pk recipe.pk %}#dependencies'>{{recipe.name}}</a> dependencies" + data-content="<ul class='unstyled'> + {% for i in deps|dictsort:"depends_on.name"%} + <li><a href='{% url "recipe" build.pk i.depends_on.pk %}'>{{i.depends_on.name}}</a></li> + {% endfor %} + </ul>"> + {{count}} + </a> + {% endif %} + {% endwith %} + {% endwith %} + </td> + <!-- Brought in by --> + <td class="depends_by"> + {% with revs=recipe_revs|get_dict_value:recipe.pk %} + {% with count=revs|length %} + {% if count %} + <a class="btn" + title="<a href='{% url "recipe" build.pk recipe.pk %}#brought-in-by'>{{recipe.name}}</a> reverse dependencies" + data-content="<ul class='unstyled'> + {% for i in revs|dictsort:"recipe.name" %} + <li><a href='{% url "recipe" build.pk i.recipe.pk %}'>{{i.recipe.name}}</a></li> + {% endfor %} + </ul>"> + {{count}} + </a> + {% endif %} + {% endwith %} + {% endwith %} + </td> + <!-- Recipe file --> + <td class="recipe_file">{{recipe.file_path}} {% if recipe.pathflags %}<i>({{recipe.pathflags}})</i>{% endif %}</td> + <!-- Section --> + <td class="recipe_section">{{recipe.section}}</td> + <!-- License --> + <td class="recipe_license">{{recipe.license}}</td> + <!-- Layer --> + <td class="layer_version__layer__name">{{recipe.layer_version.layer.name}}</td> + <!-- Layer branch --> + <td class="layer_version__branch">{{recipe.layer_version.branch}}</td> + <!-- Layer commit --> + <td class="layer_version__layer__commit"> + <a class="btn" + data-content="<ul class='unstyled'> + <li>{{recipe.layer_version.commit}}</li> + </ul>"> + {{recipe.layer_version.commit|truncatechars:13}} + </a> + </td> + </tr> + + {% endfor %} + +{% include "basetable_bottom.html" %} +{% endif %} +</div> +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/tablesort.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/tablesort.html new file mode 100644 index 000000000..362474293 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/tablesort.html @@ -0,0 +1,38 @@ +{% load projecttags %} +<!-- component to display a generic table --> + {% if disable_sort %} + <table class="table table-bordered table-hover" id="detail_table"> + <thead> + <tr> + {% for tc in tablecols %} + <th class="{%if tc.dclass%}{{tc.dclass}}{%endif%} {%if tc.clclass%}{{tc.clclass}}{%endif%}"> + {%if tc.qhelp%}<i class="icon-question-sign get-help" title="{{tc.qhelp}}"></i>{%endif%} + {{tc.name}} + </th> + {% endfor %} + </tr> + </thead> + {% else %} + <table class="table table-bordered table-hover tablesorter" id="otable"> + <thead> + <!-- Table header row; generated from "tablecols" entry in the context dict --> + <tr> + {% for tc in tablecols %} + <th class="{%if tc.dclass%}{{tc.dclass}}{%endif%} {%if tc.clclass%}{{tc.clclass}}{%endif%}"> + {%if tc.qhelp%}<i class="icon-question-sign get-help" title="{{tc.qhelp}}"></i>{%endif%} + {%if tc.orderfield%} + <a {%if tc.ordericon%} class="sorted" {%endif%} + href="javascript:reload_params({'page': 1, 'orderby' : '{{tc.orderfield}}' })" > + {{tc.name}} + </a> + {%else%} + <span class="muted"> + {{tc.name}} + </span> + {%endif%} + {%if tc.ordericon%} <i class="icon-caret-{{tc.ordericon}}"></i>{%endif%} + </th> + {% endfor %} + </tr> + </thead> + {% endif %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/target.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/target.html new file mode 100644 index 000000000..65e6c4a07 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/target.html @@ -0,0 +1,162 @@ +{% extends "basebuildpage.html" %} +{% block localbreadcrumb %} +<li>{{target.target}}</li> +{% endblock localbreadcrumb%} + +{% load projecttags %} + +{% block nav-target %} + {% for t in build.get_sorted_target_list %} + {% ifequal target.pk t.pk %} + <li class="active"><a href="{% url 'target' build.pk t.pk %}">{{t.target}}</a><li> + {% else %} + <li><a href="{% url 'target' build.pk t.pk %}">{{t.target}}</a><li> + {% endifequal %} + {% endfor %} +{% endblock %} + +{% block buildinfomain %} + +<div class="row-fluid span10"> + <div class="page-header"> + <h1> + {% if request.GET.search and objects.paginator.count > 0 %} + {{objects.paginator.count}} package{{objects.paginator.count|pluralize}} found + {% elif request.GET.search and objects.paginator.count == 0 %} + No packages found + {% else %} + {{target.target}} + {% endif %} + </h1> + </div> +</div> + +<div class="row-fluid pull-right span10" id="navTab"> + <ul class="nav nav-pills"> + <li class="active"> + <a href="#target"> + <i class="icon-question-sign get-help" title="Of all the packages built, the subset installed in the root file system of this image"></i> + Packages included ({{target.package_count}} - {{packages_sum|filtered_filesizeformat}}) + </a> + </li> + <li> + <a href="{% url 'dirinfo' build.id target.id %}"> + <i class="icon-question-sign get-help" title="The directories and files in the root file system of this image"></i> + Directory structure + </a> + </li> + </ul> + + <div id="image-packages" class="tab-pane"> + + {% if objects.paginator.count == 0 %} + <div class="row-fluid"> + <div class="alert"> + <form class="no-results input-append" id="searchform"> + <input id="search" name="search" class="input-xxlarge" type="text" value="{% if request.GET.search %}{{request.GET.search}}{% endif %}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %} + <button class="btn" type="submit" value="Search">Search</button> + <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all packages</button> + </form> + </div> + </div> + + + {% else %} + {% include "basetable_top.html" %} + {% for package in objects %} + <tr> + {# order of the table data must match the columns defined in template's context tablecols #} + <td class="package_name"> + <a href="{% url 'package_included_detail' build.id target.id package.id %}"> + {{package.name}} + </a> + {% if package.installed_name and package.name != package.installed_name %} + <span class="muted"> as {{package.installed_name}}</span> + <i class="icon-question-sign get-help hover-help" title='{{package.name|add:" was renamed at packaging time and was installed in your image as "|add:package.installed_name}}'></i> + {% endif %} + </td> + <td class="package_version"> + <a href="{% url 'package_included_detail' build.id target.id package.id %}"> + {{package.version|filtered_packageversion:package.revision}} + </a> + </td> + <td class="license"> + {{package.license}} + </td> + <td class="size sizecol"> + {{package.size|filtered_installedsize:package.installed_size|filtered_filesizeformat}} + </td> + + <td class="size_over_total sizecol"> + {{package|filter_sizeovertotal:packages_sum}} + </td> + <td class="depends"> + {% with deps=package.runtime_dependencies %} + {% with deps_count=deps|length %} + {% if deps_count > 0 %} + <a class="btn" + title="<a href='{% url "package_included_dependencies" build.id target.id package.id %}'>{{package.name}}</a> dependencies" + data-content="<ul class='unstyled'> + {% for i in deps|dictsort:'depends_on.name' %} + <li><a href='{% url "package_included_detail" build.pk target.id i.depends_on.pk %}'>{{i.depends_on.name}}</a></li> + {% endfor %} + </ul>"> + {{deps_count}} + </a> + {% endif %} + {% endwith %} + {% endwith %} + </td> + <td class="brought_in_by"> + {% with rdeps=package.reverse_runtime_dependencies %} + {% with rdeps_count=rdeps|length %} + {% if rdeps_count > 0 %} + <a class="btn" + title="<a href='{% url "package_included_reverse_dependencies" build.id target.id package.id %}'>{{package.name}}</a> reverse dependencies" + data-content="<ul class='unstyled'> + {% for i in rdeps|dictsort:'package.name' %} + <li><a href='{% url "package_included_detail" build.id target.id i.package.id %}'>{{i.package.name}}</a></li> + {% endfor %} + </ul>"> + {{rdeps_count}} + </a> + {% endif %} + {% endwith %} + {% endwith %} + </td> + <td class="recipe_name"> + {% if package.recipe.version %} + <a href="{% url 'recipe' build.id package.recipe_id %}"> + {{ package.recipe.name }} + </a> + {% endif %} + </td> + <td class="recipe_version"> + {% if package.recipe.version %} + <a href="{% url 'recipe' build.id package.recipe_id %}"> + {{ package.recipe.version }} + </a> + {% endif %} + </td> + <td class="layer_name"> + {{ package.recipe.layer_version.layer.name }} + </td> + <td class="layer_branch"> + {{ package.recipe.layer_version.branch}} + </td> + <td class="layer_commit"> + <a class="btn" + data-content="<ul class='unstyled'> + <li>{{package.recipe.layer_version.commit}}</li> + </ul>"> + {{package.recipe.layer_version.commit|truncatechars:13}} + </a> + </td> + </tr> + {% endfor %} + + {% include "basetable_bottom.html" %} + {% endif %} + </div> <!-- tabpane --> +</div> <!--span 10--> +{% endblock buildinfomain %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/task.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/task.html new file mode 100644 index 000000000..635098a02 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/task.html @@ -0,0 +1,269 @@ +{% extends "basebuilddetailpage.html" %} + +{% load projecttags %} +{% load humanize %} + +{% block localbreadcrumb %} +<li><a href="{% url 'tasks' build.pk %}">Tasks</a></li> +<li>{{task.recipe.name}}_{{task.recipe.version}} {{task.task_name}}</li> +{% endblock %} + +{% block pagedetailinfomain %} + +<div class="row span11"> + <div class="page-header"> + <h1><a href="{%url 'recipe' build.pk task.recipe.pk %}">{{task.recipe.name}}_{{task.recipe.version}}</a> {{task.task_name}}</h1> + </div> + +{# Outcome section #} +<h2 {{ task|task_color:True }}> + {{task.get_outcome_display}} + <i class="icon-question-sign get-help heading-help" title="{{task.get_outcome_help}}"></i> +</h2> +{%if task.task_executed %} + {# executed tasks outcome #} + {% if task.logfile %} + <a class="btn btn-large" href="{% url 'build_artifact' build.id "tasklogfile" task.pk %}" style="margin:15px;">Download task log</a> + {% endif %} + {# show stack trace for failed task #} + {% if task.outcome == task.OUTCOME_FAILED and log_head %} + <h3>Python stack trace</h3> + <div> + <pre style="min-height:160px;"> + <code>{{log_head}}</code><a id="full-trace-show" data-target="#fulltrace" data-toggle="collapse" class="btn btn-mini">...</a> + <div id="fulltrace" class="collapse" style="margin-top: -20px; height: 0px;"> + <code>{{log_body}}</code><br><a id="full-trace-hide" class="btn btn-mini collapsed" style="font-family:Helvetica Neue" data-target="#fulltrace" data-toggle="collapse">Collapse stack trace<i class="icon-caret-up"></i></a></div></pre> + </div> + {% endif %} +{% else %} +{# not executed tasks outcome #} + {% if task.outcome == task.OUTCOME_PREBUILT %} + {% if not showing_matches %} + <a class="btn" href="javascript:reload_params({'show_matches' : 'true' })">Match to tasks in previous builds <i class="icon-question-sign get-help" style="margin-top:20px;" title="This shows you a list of tasks from previous builds with the same signature generated from the same inputs as used in the prebuilt task. Any of them could be the task that generated the output this prebuilt task is reusing"></i></a> + {% elif matching_tasks %} + <h3 class="details">Prebuilt task could be based on + <i class="icon-question-sign get-help heading-help" title="This table shows a list of tasks from previous builds with the same signature generated from the same inputs as used in the prebuilt task. Any of them could be the task that generated the output this prebuilt task is reusing"></i> + </h3> + <table class="table table-bordered table-hover"> + <thead> + <th> + <i class="icon-question-sign get-help" title="The name of the recipe to which each task applies"></i> + Recipe + </th> + <th> + <i class="icon-question-sign get-help" title="The name of the task"></i> + Task + </th> + <th> + <i class="icon-question-sign get-help" title="This value tells you if a task had to run (executed) in order to generate the task output, or if the output was provided by another task and therefore the task didn't need to run (not executed)"></i> + Executed + </th> + <th> + <i class="icon-question-sign get-help" title="This column tells you if 'executed' tasks succeeded or failed. The column also tells you why 'not executed' tasks did not need to run"></i> + Outcome + </th> + <th> + <i class="icon-question-sign get-help" title="The date and time the build finished"></i> + Build completed on + </th> + </thead> + <tbody> + {% for match in matching_tasks %} + <tr {{ match|task_color }}> + <td> + <a href="{%url "task" match.build.pk match.pk%}">{{match.recipe.name}}</a> + </td> + <td> + <a href="{%url "task" match.build.pk match.pk%}">{{match.task_name}}</a> + {% if task.get_description %} + <i class="icon-question-sign get-help hover-help" title="{{task.get_description}}"></i> + {% endif %} + </td> + <td> + <a href="{%url "task" match.build.pk match.pk%}">{{match.get_executed_display}}</a> + </td> + <td> + <a href="{%url "task" match.build.pk match.pk%}">{{match.get_outcome_display}} </a><i class="icon-question-sign get-help hover-help" title="{{match.get_outcome_help}}"></i> + </td> + <td> + <a href="{%url "task" match.build.pk match.pk%}">{{match.build.completed_on|date:"d/m/y H:i"}}</a> + </td> + </tr> + {% endfor %} + </tbody> + </table> + {% else %} + <p class="alert"> + <strong> We have found no tasks matching this prebuilt task</strong><br/> + The task you are looking for could belong to a build for which Toaster has no data. + </p> + {% endif %} + {% elif task.outcome == task.OUTCOME_COVERED %} + <dl class="dl-horizontal"> + <dt> + <i class="icon-question-sign get-help" title="The task(s) providing the outcome of this task"></i> Task covered by + </dt> + <dd> + <ul> + {% for t in covered_by %} + <li> + <a href="{%url 'task' t.build.pk t.pk%}" + class="task-info" + title="{{t.get_executed_display}} | {{t.get_outcome_display}}"> + {{t.recipe.name}}_{{t.recipe.version}} + {{t.task_name}} + </a> + </li> + {% endfor %} + </ul> + </dd> + </dl> + {%elif task.outcome == task.OUTCOME_CACHED%} + {% for t in task.get_related_setscene %} + {% if forloop.last %} + <a class="btn btn-large" href="{% url 'build_artifact' build.id "tasklogfile" t.pk %}" style="margin:15px;">Download task log</a> + {% endif %} + {% endfor %} + + {%elif task.outcome == task.OUTCOME_EMPTY%} + <div class="alert alert-info details"> + This task is empty because it has the <code>noexec</code> flag set to <code>1</code>, or the task function is empty + </div> + {% endif %} +{% endif %} + +{# Execution section #} + {% if task.task_executed %} + <h2> + Executed + <i class="icon-question-sign get-help heading-help" title="'Executed' tasks are those that need to run in order to generate the task output"></i> + {% else %} + <h2 class="muted"> + Not Executed + <i class="icon-question-sign get-help heading-help" title="'Not executed' tasks don't need to run because their outcome is provided by another task"></i> + {% endif %} + </h2> + +<dl class="dl-horizontal"> + <dt> + <i class="icon-question-sign get-help" title="To make builds more efficient, the build system detects changes in the 'inputs' to a given task by creating a 'task signature'. If the signature changes, the build system assumes the inputs have changed and the task needs to be rerun"></i> + Task inputs signature + </dt> + <dd> + {{task.sstate_checksum}} + </dd> +</dl> + {% if task.sstate_result != task.SSTATE_NA %} + <div class="alert alert-info">Attempting to restore output from sstate cache + <i class="icon-question-sign get-help get-help-blue" title="The build system is searching for the task output in your <code>sstate-cache</code> directory and mirrors. If the build system finds the task output, it will reuse it instead of building it from scratch by running the real task. Reusing the task output makes the build faster"></i> + </div> + <dl class="dl-horizontal"> + <dt> + <i class="icon-question-sign get-help" title="The name of the file searched for in your <code>sstate-cache</code> directory and mirrors"></i> + File searched for + </dt> + <dd><code>{{task.path_to_sstate_obj}}</code></dd> + <dt> + <i class="icon-question-sign get-help" title="The locations searched for the above file (i.e. your <code>sstate-cache</code> directory and any mirrors you have set up)"></i> + URI(s) searched + </dt> + <dd><ul>{% for uri in uri_list %}<li><code>{{uri}}</code></li>{% endfor %}</ul></dd> + </dl> + {% endif %} + {% if task.sstate_result == task.SSTATE_MISS %} + <div class="alert alert-info"> + <strong>File not in sstate cache.</strong> Running the real task instead. + </div> + {% elif task.sstate_result == task.SSTATE_FAILED%} + <div class="alert"> + <strong>Failed</strong> to restore output from sstate cache. The file was found but could not be unpacked. + </div> + <dl class="dl-horizontal"> + <a href="{% url 'build_artifact' build.id "tasklogfile" task.pk %}" style="margin:15px;">Download log</a> + </dl> + <div class="alert alert-info"> + Running the real task instead. + </div> + {% elif task.sstate_result == task.SSTATE_RESTORED %} + <div class="alert alert-info"> + Output <strong>successfully restored</strong> from sstate cache. + </div> + {% endif %} + <dl class="dl-horizontal"> + <dt> + <i class="icon-question-sign get-help" title="The running sequence of each task in the build"></i> + Task order + </dt> + <dd><a href="{%url "tasks_task" build.pk task.order %}#{{task.order}}">{{task.order}}</a></dd> + {% if task.task_executed %} + <dt> + <i class="icon-question-sign get-help" title="Indicates if this task executes a Python or Shell function(s)"></i> + Task script type + </dt> + <dd>{{task.get_script_type_display}}</dd> + {% endif %} +<!-- + <dt> + <i class="icon-question-sign get-help" title="The code executed by the task"></i> + Task executable output + </dt> + <dd><code>{{task.source_url}}</code></dd> +--> + <dt> + <i class="icon-question-sign get-help" title="Task dependency chain (i.e. other tasks)"></i> + Dependencies + </dt> + <dd> + <ul> + {% for dep in deps %} + <li><a href="{%url 'task' dep.build.pk dep.pk%}" class="task-info" title="{{dep.get_executed_display}} | {{dep.get_outcome_display}}">{{dep.recipe.name}}_{{dep.recipe.version}} <span class="task-name">{{dep.task_name}}</span></a></li> + {% empty %} + <li class="muted">This task has no dependencies</li> + {% endfor %} + </ul> + </dd> + <dt> + <i class="icon-question-sign get-help" title="Tasks that depend on this task"></i> + Reverse dependencies + </dt> + <dd> + <ul> + {% for dep in rdeps %} + <li><a href="{%url 'task' dep.build.pk dep.pk%}" class="task-info" title="{{dep.get_executed_display}} | {{dep.get_outcome_display}}">{{dep.recipe.name}}_{{dep.recipe.version}} <span class="task-name">{{dep.task_name}}</span></a></li> + {% empty %} + <li class="muted">This task has no reverse dependencies</li> + {% endfor %} + </ul> +</dl> + +{# Performance section - shown only for executed tasks #} +{%if task.elapsed_time or task.cpu_usage or task.disk_io %} + <h2 class="details">Performance</h2> +{% endif %} + <dl class="dl-horizontal"> + {% if task.elapsed_time %} + <dt> + <i class="icon-question-sign get-help" title="How long it took the task to finish in seconds"></i> + Time (secs) + </dt> + <dd>{{task.elapsed_time|format_none_and_zero|floatformat:2}}</dd> + {% endif %} + {% if task.cpu_usage > 0 %} + <dt> + <i class="icon-question-sign get-help" title="The percentage of task CPU utilization"></i> + CPU usage + </dt> + <dd>{{task.cpu_usage|format_none_and_zero|floatformat:2}}%</dd> + {% endif %} + {% if task.disk_io > 0 %} + <dt> + <i class="icon-question-sign get-help" title="Number of miliseconds the task spent doing disk input and output"></i> + Disk I/O (ms) + </dt> + <dd>{{task.disk_io|format_none_and_zero}}</dd> + {% endif %} + </dl> + +</div> +{% endblock %} + diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/tasks.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/tasks.html new file mode 100644 index 000000000..b18b5c7c4 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/tasks.html @@ -0,0 +1,136 @@ +{% extends "basebuildpage.html" %} +{% load projecttags %} + +{% block localbreadcrumb %} +<li>{{title}}</li> +{% endblock %} + +{% block nav-tasks %} + {% if 'Tasks' == title %} + <li class="active"><a href="{% url 'tasks' build.pk %}">Tasks</a></li> + {% else %} + <li><a href="{% url 'tasks' build.pk %}">Tasks</a></li> + {% endif %} +{% endblock %} +{% block nav-buildtime %} + {% if 'Time' == title %} + <li class="active"><a href="{% url 'buildtime' build.pk %}">Time</a></li> + {% else %} + <li><a href="{% url 'buildtime' build.pk %}">Time</a></li> + {% endif %} +{% endblock %} +{% block nav-cpuusage %} + {% if 'CPU usage' == title %} + <li class="active"><a href="{% url 'cpuusage' build.pk %}">CPU usage</a></li> + {% else %} + <li><a href="{% url 'cpuusage' build.pk %}">CPU usage</a></li> + {% endif %} +{% endblock %} +{% block nav-diskio %} + {% if 'Disk I/O' == title %} + <li class="active"><a href="{% url 'diskio' build.pk %}">Disk I/O</a></li> + {% else %} + <li><a href="{% url 'diskio' build.pk %}">Disk I/O</a></li> + {% endif %} +{% endblock %} + +{% block buildinfomain %} +<div class="span10"> +{% if not request.GET.filter and not request.GET.search and not objects.paginator.count %} + <!-- Empty - no data in database --> + <div class="page-header"> + <h1>{{title}}</h1> + </div> + <div class="alert alert-info lead"> + No data was recorded for this build. + </div> + +{% else %} + + <div class="page-header"> + <h1> + {% if request.GET.filter and objects.paginator.count > 0 or request.GET.search and objects.paginator.count > 0 %} + {{objects.paginator.count}} task{{objects.paginator.count|pluralize}} found + {%elif request.GET.filter and objects.paginator.count == 0 or request.GET.search and objects.paginator.count == 0 %} + No tasks found + {%else%} + {{title}} + {%endif%} + </h1> + </div> + + {% if objects.paginator.count == 0 %} + <div class="row-fluid"> + <div class="alert"> + <form class="no-results input-append" id="searchform"> + <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 %} + <button class="btn" type="submit" value="Search">Search</button> + <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all tasks</button> + </form> + </div> + </div> + + + {% else %} + {% include "basetable_top.html" %} + + {% for task in objects %} + <tr {{ task|task_color }} id="{{task.order}}"> + <td class="order"> + <a href="{%url "task" build.pk task.pk%}">{{task.order}}</a> + </td> + <td class="recipe_name" > + <a href="{% url "recipe" build.pk task.recipe.pk %}">{{task.recipe.name}}</a> + </td> + <td class="recipe_version"> + <a href="{% url "recipe" build.pk task.recipe.pk %}">{{task.recipe.version}}</a> + </td> + <td class="task_name"> + <a href="{%url "task" build.pk task.pk%}">{{task.task_name}}</a> {% if task.get_description %}<i class="icon-question-sign get-help hover-help" title="{{task.get_description}}"></i> {% endif %} + </td> + <td class="executed"> + <a href="{%url "task" build.pk task.pk%}">{{task.get_executed_display}}</a> + </td> + <td class="outcome"> + <a href="{%url "task" build.pk task.pk%}">{{task.get_outcome_display}} </a> + {% if task.outcome = task.OUTCOME_FAILED %} + <a href="{% url 'build_artifact' build.pk "tasklogfile" task.pk %}"> + <i class="icon-download-alt" title="Download task log file"></i> + </a> + {% endif %} + <i class="icon-question-sign get-help hover-help" title="{{task.get_outcome_help}}"></i> + </td> + <td class="cache_attempt"> + <a href="{%url "task" build.pk task.pk%}">{{task.get_sstate_result_display|format_none_and_zero}}</a> + </td> + <td class="time_taken"> + {{task.elapsed_time|format_none_and_zero|floatformat:2}} + </td> + <td class="cpu_used"> + {{task.cpu_usage|format_none_and_zero|floatformat:2}}{% if task.cpu_usage %}%{% endif %} + </td> + <td class="disk_io"> + {{task.disk_io|format_none_and_zero}} + </td> + + </tr> + {% endfor %} + + {% include "basetable_bottom.html" %} + {% endif %} {# objects.paginator.count #} +{% endif %} {# empty #} +</div> + +<script type="text/javascript"> + + $(document).ready(function() { + // enable blue hightlight animation for the order link + if (location.href.search('#') > -1) { + var task_order = location.href.split('#')[1]; + $("#" + task_order).addClass("highlight"); + } + }); + +</script> + +{% endblock %} diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable-filter.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable-filter.html new file mode 100644 index 000000000..7c8dc49b3 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable-filter.html @@ -0,0 +1,18 @@ +<!-- filter modal --> +<div id="filter-modal-{{table_name}}" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="false"> + <form id="filter-modal-form-{{table_name}}" style="margin-bottom: 0px"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button> + <h3 id="filter-modal-title-{{table_name}}"> </h3> + </div> + <div class="modal-body"> + <p>Show:</p> + <span id="filter-actions-{{table_name}}"></span> + </div> + <div class="modal-footer"> + <button class="btn btn-primary" type="submit">Apply</button> + </div> + </form> +</div> +<button id="clear-filter-btn-{{table_name}}" style="display:none"></button> +<!-- end filter modal --> diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable-simple.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable-simple.html new file mode 100644 index 000000000..212318bc5 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable-simple.html @@ -0,0 +1,94 @@ + +{% load static %} +{% load projecttags %} + +<script src="{% static 'js/table.js' %}"></script> +<script src="{% static 'js/layerBtn.js' %}"></script> +<script> + $(document).ready(function() { + (function(){ + + var ctx = { + tableName : "{{table_name}}", + url : "{{ xhr_table_url }}?format=json", + title : "{{title}}", + projectLayers : {{projectlayers|json}}, + }; + + try { + tableInit(ctx); + } catch (e) { + document.write("Problem loading table widget: " + e); + } + })(); + }); +</script> + +{% include 'toastertable-filter.html' %} + +<div class="row-fluid" id="no-results-{{table_name}}" style="display:none"> + <div class="alert"> + <form class="no-results input-append"> + <input class="input-xlarge" id="new-search-input-{{table_name}}" name="search" type="text" placeholder="Search {{title|lower}}" value="{% if request.GET.search %}{{request.GET.search}}{% endif %}"/> + <a href="#" class="add-on btn remove-search-btn-{{table_name}}" tabindex="-1"> + <i class="icon-remove"></i> + </a> + <button class="btn search-submit-{{table_name}}" >Search</button> + <button class="btn btn-link remove-search-btn-{{table_name}}">Show {{title|lower}} + </button> + </form> + </div> +</div> +<div id="table-container-{{table_name}}" style="visibility: hidden"> + <!-- control header --> + <div class="row-fluid" id="table-chrome-{{table_name}}"> + <div class="navbar-search input-append pull-left"> + + <input class="input-xlarge" id="search-input-{{table_name}}" name="search" type="text" placeholder="Search {{title|lower}}" value="{% if request.GET.search %}{{request.GET.search}}{% endif %}"/> + <a href="#" style="display:none" class="add-on btn remove-search-btn-{{table_name}}" tabindex="-1"> + <i class="icon-remove"></i> + </a> + <button class="btn" id="search-submit-{{table_name}}" >Search</button> + </div> + + <div class="pull-right"> + + <div style="display:inline"> + <span class="divider-vertical"></span> + <span class="help-inline" style="padding-top:5px;">Show rows:</span> + <select style="margin-top:5px;margin-bottom:0px;" class="pagesize-{{table_name}}"> + {% with "10 25 50 100 150" as list%} + {% for i in list.split %} + <option value="{{i}}">{{i}}</option> + {% endfor %} + {% endwith %} + </select> + </div> + </div> + </div> + + <!-- The actual table --> + <table class="table table-bordered table-hover tablesorter" id="{{table_name}}"> + <thead> + <tr><th></th></tr> + </thead> + <tbody></tbody> + </table> + + <!-- Pagination controls --> + <div class="pagination pagination-centered" id="pagination-{{table_name}}"> + <ul class="pagination" style="display: block-inline"> + </ul> + + <div class="pull-right"> + <span class="help-inline" style="padding-top:5px;">Show rows:</span> + <select style="margin-top:5px;margin-bottom:0px;" class="pagesize-{{table_name}}"> + {% with "10 25 50 100 150" as list%} + {% for i in list.split %} + <option value="{{i}}">{{i}}</option> + {% endfor %} + {% endwith %} + </select> + </div> + </div> +</div> diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable.html new file mode 100644 index 000000000..9ef4c6ffe --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable.html @@ -0,0 +1,103 @@ + +{% load static %} +{% load projecttags %} + +<script src="{% static 'js/table.js' %}"></script> +<script src="{% static 'js/layerBtn.js' %}"></script> +<script> + $(document).ready(function() { + (function(){ + + var ctx = { + tableName : "{{table_name}}", + url : "{{ xhr_table_url }}?format=json", + title : "{{title}}", + projectLayers : {{projectlayers|json}}, + }; + + try { + tableInit(ctx); + } catch (e) { + document.write("Problem loading table widget: " + e); + } + })(); + }); +</script> + +{% include 'toastertable-filter.html' %} + +<div class="row-fluid" id="no-results-{{table_name}}" style="display:none"> + <div class="alert"> + <form class="no-results input-append"> + <input class="input-xxlarge" id="new-search-input-{{table_name}}" name="search" type="text" placeholder="Search {{title|lower}}" value="{%if request.GET.search %}{{request.GET.search}}{%endif%}"/> + <a href="#" class="add-on btn remove-search-btn-{{table_name}}" tabindex="-1"> + <i class="icon-remove"></i> + </a> + <button class="btn search-submit-{{table_name}}" >Search</button> + <button class="btn btn-link remove-search-btn-{{table_name}}">Show {{title|lower}} + </button> + </form> + </div> +</div> + +<div id="table-container-{{table_name}}" style="visibility: hidden"> + <!-- control header --> + <div class="navbar" id="table-chrome-{{table_name}}"> + <div class="navbar-inner"> + <div class="navbar-search input-append pull-left"> + + <input class="input-xxlarge" id="search-input-{{table_name}}" name="search" type="text" placeholder="Search {{title|lower}}" value="{%if request.GET.search%}{{request.GET.search}}{%endif%}"/> + <a href="#" style="display:none" class="add-on btn remove-search-btn-{{table_name}}" tabindex="-1"> + <i class="icon-remove"></i> + </a> + <button class="btn" id="search-submit-{{table_name}}" >Search</button> + </div> + + <div class="pull-right"> + <div class="btn-group"> + <button class="btn dropdown-toggle" data-toggle="dropdown">Edit columns + <span class="caret"></span> + </button> + <ul class="dropdown-menu editcol"> + </ul> + </div> + <div style="display:inline"> + <span class="divider-vertical"></span> + <span class="help-inline" style="padding-top:5px;">Show rows:</span> + <select style="margin-top:5px;margin-bottom:0px;" class="pagesize-{{table_name}}"> + {% with "10 25 50 100 150" as list%} + {% for i in list.split %} + <option value="{{i}}">{{i}}</option> + {% endfor %} + {% endwith %} + </select> + </div> + </div> + </div> + </div> + + <!-- The actual table --> + <table class="table table-bordered table-hover tablesorter" id="{{table_name}}"> + <thead> + <tr><th></th></tr> + </thead> + <tbody></tbody> + </table> + + <!-- Pagination controls --> + <div class="pagination pagination-centered" id="pagination-{{table_name}}"> + <ul class="pagination" style="display: block-inline"> + </ul> + + <div class="pull-right"> + <span class="help-inline" style="padding-top:5px;">Show rows:</span> + <select style="margin-top:5px;margin-bottom:0px;" class="pagesize-{{table_name}}"> + {% with "10 25 50 100 150" as list%} + {% for i in list.split %} + <option value="{{i}}">{{i}}</option> + {% endfor %} + {% endwith %} + </select> + </div> + </div> +</div> diff --git a/yocto-poky/bitbake/lib/toaster/toastergui/templates/unavailable_artifact.html b/yocto-poky/bitbake/lib/toaster/toastergui/templates/unavailable_artifact.html new file mode 100644 index 000000000..b9f8fee03 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/toastergui/templates/unavailable_artifact.html @@ -0,0 +1,15 @@ +{% extends "base.html" %} +{% load projecttags %} +{% load humanize %} +{% load static %} + +{% block pagecontent %} + +<div class="row-fluid air"> + <div class="alert alert-info span8 lead"> + <p"> The build artifact you are trying to download no longer exists.</p> + <p><a href="javascript:window.history.back()">Back to previous page</a></p> + </div> +</div> +{% endblock %} + |