layerindex-web/templates/rrs/recipes.html
Paul Eggleton 517424dc81 Upgrade to Bootstrap 3
Use a more modern version of Bootstrap and take the opportunity to
upgrade jQuery to the latest version at the same time. This provides
better browser compatibility, moves to MIT license, allows us to make
the site more responsive for different devices in future, and provides
theming capabilities for custom installs among other improvements.

(I chose to upgrade to v3 for now rather than straight to v4 as it was
easier to do this gradually.)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
2018-09-20 15:57:59 +12:00

362 lines
12 KiB
HTML

{% extends "rrs/base_toplevel.html" %}
{% load i18n %}
{% load staticfiles %}
{% comment %}
rrs-web - top level page template
Copyright (C) 2015 Intel Corporation
Licensed under the MIT license, see COPYING.MIT for details
{% endcomment %}
{% block navs %}
{% endblock %}
<!--
{% block title_append %} - recipe maintenance - {{ maintplan_name }}{% endblock %}
-->
{% block content_inner %}
<nav class="navbar navbar-default navbar-table-controls">
<div class="container-fluid table-controls">
<ul class="nav navbar-nav">
<li>
<span class="badge navbar-badge" id="recipe-count"></span>
</li>
<li class="dropdown">
<a data-toggle="dropdown" href="#" class="dropdown-toggle" id="selected-status">
Upstream status: <strong></strong>
<b class="caret"></b>
</a>
<ul class="dropdown-menu" id="select-status">
{% for us in upstream_status_set_choices %}
<li><a href="#">{{ us }}</a></li>
{% endfor %}
<li class="divider"/>
{% for us in upstream_status_choices %}
<li><a href="#">{{ us }}</a></li>
{% endfor %}
</ul>
</li>
{% if maintplan.per_recipe_maintainers %}
<li class="navbar-text">and</li>
<li class="dropdown">
<a data-toggle="dropdown" href="#" class="dropdown-toggle" id="selected-maintainer">
Maintainer: <strong></strong>
<b class="caret"></b>
</a>
<ul class="dropdown-menu" id="select-maintainer" style="overflow:scroll;max-height:40em;">
{% for m in set_maintainers %}
<li><a href="#">{{ m }}</a></li>
{% endfor %}
<li class="divider"/>
{% for m in all_maintainers %}
<li class="active"><a href="#">{{ m }}</a></li>
{% endfor %}
</ul>
</li>
{% endif %}
</ul>
<form id="form-search" class="pull-right navbar-form">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search all recipes" id="filter"/>
<div class="input-group-btn">
<a class="input-group-addon btn btn-default" style="display:none" id="clear-search-btn">
<i class="glyphicon glyphicon-remove" aria-hidden="true"></i>
</a>
<button type="submit" value="Search" class="btn btn-default" id="btn-search">Search</button>
</div>
</div>
</form>
</div>
</nav>
<div id="no_recipes_alert" class="alert alert-warning" style="display:none">
No recipes found <a href="#" id="view-all-recipes" style="margin-left:10px;">View all recipes</a>
</div>
<table class="table tablesorter table-bordered table-hover" id="recipestable">
<thead>
<tr>
<th class="recipe_column">Recipe</th>
<th class="version_column text-muted">Version</th>
<th class="upstream_version_column text-muted">Upstream version</th>
<th class="upstream_status_column span2">Upstream status</th>
<th class="last_updated_column">Last Updated</th>
<th class="patches_column">Patches</th>
{% if maintplan.per_recipe_maintainers %}
<th class="maintainer_column">Maintainer</th>
{% endif %}
<th class="summary_column text-muted span5">Summary</th>
<th class="no_update_reason_column text-muted span5" style="display:none">No update reason</th>
</tr>
</thead>
<tbody>
{% for r in recipe_list %}
<tr>
<td class="recipe_column"><a href="{% url "rrs_recipedetail" maintplan_name r.pk %}">{{ r.name }}</a></td>
<td class="version_column">{{ r.version }}</td>
<td class="upstream_version_column">{{ r.upstream_version }}</td>
{% if r.upstream_status == "Up-to-date" %}
<td class="text-success">
{% elif r.upstream_status == "Not updated" %}
<td class="text-danger">
{% elif r.upstream_status == "Can't be updated" %}
<td class="text-muted">
{% else %}
<td class="text-warning">
{% endif %}
{{ r.upstream_status }}
</td>
<td class="last_updated_column">{{r.outdated}}</td>
<td class="patches_column">{% if r.patches_total %}<span {% if not r.patches_pending %}class="text-muted"{% endif %}>{{ r.patches_pending }}<span class="text-muted"> / {{ r.patches_total }}</span>{% endif %}</td>
{% if maintplan.per_recipe_maintainers %}
<td class="maintainer_column">{{ r.maintainer_name }}</td>
{% endif %}
<td class="summary_column">{{ r.summary }}</td>
<td class="no_update_reason_column" style="display:none">{{ r.no_update_reason }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<style>
th.header {
background-image: url({{ STATIC_URL }}/img/small.gif);
cursor: pointer;
font-weight: bold;
background-repeat: no-repeat;
background-position: center left;
padding-left: 20px;
border-right: 1px solid #dad9c7;
margin-left: -1px;
}
th.headerSortUp {
background-image: url({{ STATIC_URL }}/img/small_asc.gif);
}
th.headerSortDown {
background-image: url({{ STATIC_URL }}/img/small_desc.gif);
}
</style>
{% endblock %}
{% block scripts %}
<script src="{% static "js/uitablefilter.js" %}"></script>
<script src="{% static "js/jquery.tablesorter.js" %}"></script>
<script>
(function($) {
$.fn.multiFilter = function(filters) {
var $table = $(this);
return $table.find('tbody > tr').each(function() {
var tr = $(this);
// Make it an array to avoid special cases later.
if(!$.isArray(filters))
filters = [ filters ];
howMany = 0;
for(i = 0, f = filters[0]; i < filters.length; f = filters[++i]) {
var index = 0;
$table.find('thead > tr > th').each(function(i) {
if($(this).text() == f.column) {
index = i;
return false;
}
});
var text = tr.find('td:eq(' + index + ')').text();
if(text.toLowerCase().indexOf(f.word.toLowerCase()) != -1)
++howMany;
}
if(howMany == filters.length)
tr.show();
else
tr.hide();
});
};
})(jQuery);
</script>
<script>
$(document).ready(function() {
recipesTable = $('#recipestable')
upstreamStatus = $("<div/>").html('{{ upstream_status }}').text()
maintainer = $("<div/>").html('{{ maintainer_name }}').text()
search = '{{ search }}'
function updateQueryString(queryString) {
if (window.history.pushState) {
var newurl = window.location.protocol + "//" +
window.location.host + window.location.pathname +
queryString
window.history.pushState({path:newurl}, '', newurl);
}
}
function updateRecipeCount() {
$('#recipestable').show()
$('#no_recipes_alert').hide()
var count = 0;
$('tr:visible').each(function() {
count++
});
if (count == 1) {
$('#recipestable').hide()
$('#no_recipes_alert').show()
}
if (count == 2) {
$('#recipe-count').html("1 recipe");
} else {
$('#recipe-count').html((count - 1) + " recipes");
}
}
function updateStatusSelected() {
$("#selected-status strong").html(upstreamStatus)
statusList = document.getElementById("select-status").getElementsByTagName("li")
for (var i = 0; i < statusList.length; i++) {
if (statusList[i].textContent == upstreamStatus) {
$(statusList[i]).addClass("active")
} else {
$(statusList[i]).removeClass("active")
}
}
}
function updateMaintainerSelected() {
{% if maintplan.per_recipe_maintainers %}
$("#selected-maintainer strong").html(maintainer)
maintainerList = document.getElementById("select-maintainer").getElementsByTagName("li")
for (var i = 0; i < maintainerList.length; i++) {
if (maintainerList[i].textContent == maintainer) {
$(maintainerList[i]).addClass("active")
} else {
$(maintainerList[i]).removeClass("active")
}
}
{% endif %}
}
function applyFilters() {
if (upstreamStatus == 'Can\'t be updated') {
$('.no_update_reason_column').show()
$('.summary_column').hide()
} else {
$('.no_update_reason_column').hide()
$('.summary_column').show()
}
if (upstreamStatus == 'Up-to-date' || upstreamStatus == 'All') {
$('.upstream_version_column').hide();
} else {
$('.upstream_version_column').show();
}
if (upstreamStatus == 'All') {
upstreamStatusFilter = ''
} else {
upstreamStatusFilter = upstreamStatus
}
if (maintainer == 'All') {
maintainerFilter = ''
} else {
maintainerFilter = maintainer
}
$(recipesTable).multiFilter([
{ column: 'Upstream status', word: upstreamStatusFilter },
{ column: 'Maintainer', word: maintainerFilter },
]);
updateStatusSelected()
updateMaintainerSelected()
queryString = ''
if (search != '') {
$.uiTableFilter(recipesTable, search);
queryString = '?search=' + search
} else {
if (upstreamStatus != 'All' && maintainer != 'All') {
queryString = '?upstream_status=' + upstreamStatus +
'&maintainer_name=' + maintainer
} else if (upstreamStatus != 'All') {
queryString = '?upstream_status=' + upstreamStatus
} else if (maintainer != 'All') {
queryString = '?maintainer_name=' + maintainer
}
}
updateQueryString(queryString)
}
$("#form-search").submit(function( event ) {
upstreamStatus = 'All'
maintainer = 'All'
search = $("#filter").val()
$("#clear-search-btn").show()
applyFilters()
updateRecipeCount()
event.preventDefault();
});
function clearSearch() {
$("#filter").val('')
search = $("#filter").val()
$("#clear-search-btn").hide()
applyFilters()
updateRecipeCount()
}
$("#select-status a").click(function() {
upstreamStatus = this.text
clearSearch()
});
{% if maintplan.per_recipe_maintainers %}
$("#select-maintainer a").click(function() {
maintainer = this.text
clearSearch()
});
{% endif %}
$("#view-all-recipes").click(function() {
upstreamStatus = 'All'
maintainer = 'All'
clearSearch()
});
$("#clear-search-btn").click(function() {
upstreamStatus = 'All'
maintainer = 'All'
clearSearch()
});
$(".glyphicon-remove").tooltip( {container: 'body', html: true, title: "Clear search" });
{% if recipe_list_count > 0 %}
$(recipesTable).tablesorter({
sortList: [[0,0]],
headers: {
1: { sorter: false },
2: { sorter: false },
6: { sorter: false },
7: { sorter: false },
}
});
{% endif %}
if (search != '') {
$("#filter").val(search)
$("#clear-search-btn").show()
}
applyFilters()
updateRecipeCount()
});
</script>
{% endblock %}