mirror of
git://git.yoctoproject.org/layerindex-web.git
synced 2026-01-27 09:01:24 +01:00
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>
442 lines
23 KiB
HTML
442 lines
23 KiB
HTML
{% extends "layerindex/classic_base.html" %}
|
|
{% load i18n %}
|
|
|
|
{% comment %}
|
|
|
|
layerindex-web - comparison recipe search page template
|
|
|
|
Copyright (C) 2013, 2018 Intel Corporation
|
|
Licensed under the MIT license, see COPYING.MIT for details
|
|
|
|
{% endcomment %}
|
|
|
|
|
|
<!--
|
|
{% block title_append %} - {% if branch.name == 'oe-classic' %}OE-Classic recipes{% else %}{{ branch.short_description }} packages{% endif %}{% endblock %}
|
|
-->
|
|
|
|
{% block navs %}
|
|
{% autoescape on %}
|
|
<li class="active"><a href="{% url 'comparison_recipe_search' branch.name %}">Recipes</a></li>
|
|
<li><a href="{% url 'comparison_recipe_stats' branch.name %}">Stats</a></li>
|
|
{% endautoescape %}
|
|
{% endblock %}
|
|
|
|
{% block navs_extra %}
|
|
{% autoescape on %}
|
|
{% if updateable %}
|
|
<div id="updateDialog" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="updateDialogLabel">
|
|
<div class="modal-dialog" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
|
<h3 id="updateDialogLabel">Update {{ branch.short_description }}</h3>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>Are you sure you want to update? This will likely take some time.</p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<a href="{% url 'comparison_update' branch.name %}" class="btn btn-primary">Update</a>
|
|
<button class="btn btn-default" id="id_layerdialog_cancel" data-dismiss="modal">Cancel</button>
|
|
</div>
|
|
</div><!-- /.modal-content -->
|
|
</div><!-- /.modal-dialog -->
|
|
</div>
|
|
<div class="pull-right"><a href="#updateDialog" id="id_update_btn" role="button" class="btn btn-default navbar-btn" data-toggle="modal">Update</a></div>
|
|
{% endif %}
|
|
{% endautoescape %}
|
|
{% endblock %}
|
|
|
|
|
|
{% block content_inner %}
|
|
{% autoescape on %}
|
|
|
|
<div class="row">
|
|
|
|
<div class="col-md-12">
|
|
|
|
{% block page_heading %}
|
|
{% if branch.name == 'oe-classic' %}
|
|
<h2>OE-Classic recipes</h2>
|
|
|
|
<div class="alert alert-warning">
|
|
<b>NOTE:</b> This is the recipe search for OE-Classic, the older monolithic version of OpenEmbedded which is no longer actively developed. <a href="{% url 'recipe_search' 'master' %}">Click here</a> to search current recipes.
|
|
</div>
|
|
{% else %}
|
|
<h2>{{ branch.short_description }} packages</h2>
|
|
{% endif %}
|
|
{% endblock %}
|
|
|
|
<div class="row bottom-margin">
|
|
<form id="search-form" class="form-inline" method="GET">
|
|
<table class="search-form-table">
|
|
<tbody>
|
|
{% for field in search_form.visible_fields %}
|
|
<tr>
|
|
{% if field.name == 'oe_layer' %}
|
|
<td>
|
|
{{ field.label }}
|
|
</td>
|
|
<td>
|
|
<div class="input-group">
|
|
<input type="text" class="form-control input-large" id="id_selectedlayers_display" value="{{ selectedlayers_display }}" />
|
|
<div class="input-group-btn">
|
|
<a href="#layerDialog" id="id_select_layers" role="button" class="btn btn-default" data-toggle="modal">...</a>
|
|
</div>
|
|
</div>
|
|
<input type="hidden" id="id_selectedlayers" name="selectedlayers" value="{{ selectedlayers|join:"," }}" />
|
|
|
|
<div id="layerDialog" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="layerDialogLabel">
|
|
<div class="modal-dialog" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
|
<h3 id="layerDialogLabel">Select layers to include</h3>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="scrolling" id="id_layerdialog_list">
|
|
</div>
|
|
<div class="buttonblock">
|
|
<button type="button" class="btn btn-default" id="id_layerdialog_select_all">Select all</button>
|
|
<button type="button" class="btn btn-default buttonblock-btn" id="id_layerdialog_select_none">Select none</button>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button class="btn btn-primary" id="id_layerdialog_ok" data-dismiss="modal">OK</button>
|
|
<button class="btn btn-default" id="id_layerdialog_cancel" data-dismiss="modal">Cancel</button>
|
|
</div>
|
|
</div><!-- /.modal-content -->
|
|
</div><!-- /.modal-dialog -->
|
|
</div>
|
|
|
|
</td>
|
|
{% else %}
|
|
<td>
|
|
{{ field.label }}
|
|
</td>
|
|
<td>
|
|
{{ field }}
|
|
</td>
|
|
{% endif %}
|
|
</tr>
|
|
{% endfor %}
|
|
|
|
{% if branch.comparison %}
|
|
<tr><td>
|
|
<div class="checkbox">
|
|
<label>
|
|
<input type="checkbox" name="compare" {% if compare %}checked{% endif %}></input> Show comparison
|
|
</label>
|
|
</div>
|
|
</td></tr>
|
|
<tr><td>
|
|
<div class="checkbox">
|
|
<label>
|
|
<input type="checkbox" name="reversed" id="id_reversed" {% if reversed %}checked{% endif %}></input> Reversed
|
|
</label>
|
|
</div>
|
|
</td></tr>
|
|
|
|
<tr id="id_reversed_fields">
|
|
<td>
|
|
Exclude classes
|
|
</td>
|
|
<td>
|
|
<div class="input-group">
|
|
<input class="form-control input-large" id="id_excludeclasses_display" type="text" value="{{ excludeclasses_display }}" />
|
|
<div class="input-group-btn">
|
|
<a href="#excludeclassDialog" id="id_select_excludeclasses" role="button" class="btn btn-default" data-toggle="modal">...</a>
|
|
</div>
|
|
</div>
|
|
<input type="hidden" id="id_excludeclasses" name="excludeclasses" value="{{ excludeclasses|join:"," }}" />
|
|
|
|
<div id="excludeclassDialog" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="excludeclassDialogLabel">
|
|
<div class="modal-dialog" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
|
<h3 id="excludeclassDialogLabel">Select classes to exclude</h3>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="scrolling" id="id_excludeclassdialog_list">
|
|
</div>
|
|
<div class="buttonblock">
|
|
<button type="button" class="btn btn-default buttonblock-btn" id="id_excludeclassdialog_select_none">Select none</button>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button class="btn btn-primary" id="id_excludeclassdialog_ok" data-dismiss="modal">OK</button>
|
|
<button class="btn btn-default" id="id_excludeclassdialog_cancel" data-dismiss="modal">Cancel</button>
|
|
</div>
|
|
</div><!-- /.modal-content -->
|
|
</div><!-- /.modal-dialog -->
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
|
|
</tbody>
|
|
</table>
|
|
<button class="btn btn-default" type="submit">Search</button>
|
|
{% block export_button %}
|
|
<button class="btn btn-default" type="submit" formaction="{% url 'comparison_recipe_search_csv' branch.name %}">Export CSV</button>
|
|
{% endblock %}
|
|
</form>
|
|
</div>
|
|
|
|
{% if recipe_list %}
|
|
<table class="table table-striped table-bordered recipestable">
|
|
<thead>
|
|
<tr>
|
|
{% if not branch.comparison %}
|
|
<th>Recipe name</th>
|
|
<th>Layer</th>
|
|
<th>Version</th>
|
|
<th class="col-md-7">Description</th>
|
|
<th>Section</th>
|
|
{% elif reversed %}
|
|
<th>Recipe name</th>
|
|
<th>OE Layer</th>
|
|
<th>Version</th>
|
|
<th class="col-md-7">Description</th>
|
|
<th>Section</th>
|
|
<th class="col-md-5">Status</th>
|
|
{% if branch.name == 'oe-classic' %}
|
|
<th>Covering recipe</th>
|
|
{% else %}
|
|
<th>Covering package</th>
|
|
{% endif %}
|
|
{% elif compare %}
|
|
{% if branch.name == 'oe-classic' %}
|
|
<th>Recipe name</th>
|
|
{% else %}
|
|
<th>Package name</th>
|
|
{% endif %}
|
|
<th>Version</th>
|
|
<th>Patches</th>
|
|
<th>Status</th>
|
|
<th>OE Layer</th>
|
|
<th>OE Recipe</th>
|
|
<th>OE Version</th>
|
|
<th>OE Patches</th>
|
|
{% else %}
|
|
{% if branch.name == 'oe-classic' %}
|
|
<th>Recipe name</th>
|
|
{% else %}
|
|
<th>Package name</th>
|
|
{% endif %}
|
|
<th>Version</th>
|
|
<th class="col-md-7">Description</th>
|
|
<th class="col-md-5">Status</th>
|
|
<th>Covering recipe</th>
|
|
<th>Categories</th>
|
|
{% endif %}
|
|
{% block table_head_extra %}{% endblock %}
|
|
</tr>
|
|
</thead>
|
|
|
|
<tbody>
|
|
{% for recipe in recipe_list %}
|
|
<tr {% if recipe.preferred_count > 0 %}class="text-muted"{% endif %}>
|
|
{% if not branch.comparison %}
|
|
<td><a href="{% block no_comparison_recipe_url %}{% url 'recipe' recipe.id %}{% endblock %}">{{ recipe.name }}</a></td>
|
|
<td>{{ recipe.layerbranch.layer.name }}</td>
|
|
<td>{{ recipe.pv }}</td>
|
|
<td>{{ recipe.short_desc }}</td>
|
|
<td>{{ recipe.section }}</td>
|
|
{% elif reversed %}
|
|
<td><a href="{% url 'recipe' recipe.id %}">{{ recipe.name }}{% if recipe.needs_attention %} <i class="glyphicon glyphicon-exclamation-sign" data-toggle="tooltip" title="Needs attention" aria-hidden="true"></i>{% endif %}</a></td>
|
|
<td><a href="{% url 'layer_item' 'master' recipe.layerbranch.layer.name %}">{{ recipe.layerbranch.layer.name }}</a></td>
|
|
<td>{{ recipe.pv }}</td>
|
|
<td>{{ recipe.short_desc }}</td>
|
|
<td>{{ recipe.section }}</td>
|
|
<td>{% if recipe.cover_recipe %}{{ recipe.cover_recipe.get_cover_status_display }}{% endif %}</td>
|
|
<td>{% if recipe.cover_recipe %}<a href="{% url 'comparison_recipe' recipe.cover_recipe.id %}">{% endif %}{{ recipe.cover_recipe.pn }}{% if recipe.cover_recipe %}</a>{% endif %}</td>
|
|
{% elif compare %}
|
|
<td><a href="{% url 'comparison_recipe' recipe.id %}">{{ recipe.name }}{% if recipe.needs_attention %} <i class="glyphicon glyphicon-exclamation-sign" data-toggle="tooltip" title="Needs attention" aria-hidden="true"></i>{% endif %}</a></td>
|
|
<td>{{ recipe.pv|truncatechars:10 }}</td>
|
|
<td>{% if recipe.patch_set.exists %}{{ recipe.patch_set.count }}{% endif %}</td>
|
|
<td>{{ recipe.get_cover_status_display }}{% if recipe.cover_comment %} <a href="{% url 'classic_recipe' recipe.id %}"><i class="glyphicon glyphicon-comment" data-toggle="tooltip" title="{{ recipe.cover_comment }}" aria-hidden="true"></i></a>{% endif %}</td>
|
|
<td>{% if recipe.cover_layerbranch %}<a href="{% url 'layer_item' 'master' recipe.cover_layerbranch.layer.name %}">{{ recipe.cover_layerbranch.layer.name }}</a>{% endif %}</td>
|
|
{% if recipe.cover_pn %}
|
|
<td>{% if recipe.cover_recipe %}<a href="{% url 'recipe' recipe.cover_recipe.id %}">{% endif %}{{ recipe.cover_pn }}{% if recipe.cover_recipe %}</a>{% endif %}</td>
|
|
<td {% if recipe.cover_vercmp < 0 %}class="error"{% endif %}>{% if recipe.cover_recipe %}{{ recipe.cover_recipe.pv|truncatechars:10 }}{% endif %}</td>
|
|
<td>{% if recipe.cover_recipe and recipe.cover_recipe.patch_set.exists %}{{ recipe.cover_recipe.patch_set.count }}{% endif %}</td>
|
|
{% else %}
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
{% endif %}
|
|
{% else %}
|
|
<td><a href="{% block comparison_recipe_url %}{% url 'comparison_recipe' recipe.id %}{% endblock %}">{{ recipe.name }}{% if recipe.needs_attention %} <i class="glyphicon glyphicon-exclamation-sign" data-toggle="tooltip" title="Needs attention" aria-hidden="true"></i>{% endif %}</a></td>
|
|
<td>{{ recipe.pv }}</td>
|
|
<td>{{ recipe.short_desc }}</td>
|
|
<td>{{ recipe.get_cover_desc }}</td>
|
|
<td>{% if recipe.cover_pn %}{% if recipe.cover_recipe %}<a href="{% url 'recipe' recipe.cover_recipe.id %}">{% endif %}{{ recipe.cover_pn }}{% if recipe.cover_recipe %}</a>{% endif %}{% endif %}</td>
|
|
<td>{{ recipe.classic_category }}</td>
|
|
{% endif %}
|
|
{% block table_row_extra %}{% endblock %}
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
|
|
{% if is_paginated %}
|
|
{% load pagination %}
|
|
{% pagination page_obj %}
|
|
{% endif %}
|
|
{% else %}
|
|
{% if searched %}
|
|
{% if branch.name == 'oe-classic' %}
|
|
<p>No matching OE-Classic recipes in database.</p>
|
|
{% elif not branch.comparison %}
|
|
<p>No matching recipes in {{ branch }} branch.</p>
|
|
{% else %}
|
|
<p>No matching {{ branch }} packages in database.</p>
|
|
{% endif %}
|
|
{% endif %}
|
|
{% endif %}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{% endautoescape %}
|
|
|
|
{% endblock %}
|
|
|
|
|
|
{% block scripts %}
|
|
<script>
|
|
update_selected_layer_display = function() {
|
|
layernames = [];
|
|
layerids = [];
|
|
$('.filterlayercheckbox:checked').each(function() {
|
|
layernames.push($("label[for="+$(this).attr('id')+"]").html());
|
|
layerids.push($(this).attr('value'))
|
|
});
|
|
$('#id_selectedlayers').val(layerids)
|
|
if(layernames.length)
|
|
$('#id_selectedlayers_display').val(layernames)
|
|
else
|
|
$('#id_selectedlayers_display').val(' (any)')
|
|
}
|
|
update_excludeclasses_display = function() {
|
|
classnames = [];
|
|
$('.filterclasscheckbox:checked').each(function() {
|
|
classnames.push($(this).attr('value'));
|
|
});
|
|
if(classnames.length)
|
|
$('#id_excludeclasses_display').val(classnames)
|
|
else
|
|
$('#id_excludeclasses_display').val(' (none)');
|
|
$('#id_excludeclasses').val(classnames)
|
|
}
|
|
update_filters_enabled = function() {
|
|
if( $('#id_reversed').is(":checked") ) {
|
|
$('#id_reversed_fields').show()
|
|
}
|
|
else {
|
|
$('#id_reversed_fields').hide()
|
|
}
|
|
}
|
|
select_layer_checkboxes = function() {
|
|
$('.filterlayercheckbox').attr('checked', false);
|
|
selectedlayers = $('#id_selectedlayers').val().split(',');
|
|
for(i in selectedlayers) {
|
|
$('#id_layercheckbox_' + selectedlayers[i]).attr('checked', true);
|
|
}
|
|
}
|
|
setup_layer_list = function() {
|
|
if( $.trim($('#id_layerdialog_list').html()) ) {
|
|
select_layer_checkboxes()
|
|
}
|
|
else {
|
|
$('#id_layerdialog_list').html('Loading...');
|
|
$('#id_layerdialog_ok').prop('disabled', true)
|
|
$('#id_layerdialog_ok').addClass('disabled')
|
|
$.ajax({
|
|
url: '{% url 'layer_checklist' 'master' %}',
|
|
dataType: 'html',
|
|
success: function( resp ) {
|
|
$('#id_layerdialog_list').html(resp);
|
|
select_layer_checkboxes()
|
|
$('#id_layerdialog_ok').prop('disabled', false)
|
|
$('#id_layerdialog_ok').removeClass('disabled')
|
|
},
|
|
error: function( req, status, err ) {
|
|
$('#id_layerdialog_list').html(err);
|
|
console.log( 'something went wrong', status, err );
|
|
}
|
|
});
|
|
}
|
|
}
|
|
select_excludeclass_checkboxes = function() {
|
|
$('.filterclasscheckbox').attr('checked', false);
|
|
excludeclasses = $('#id_excludeclasses').val().split(',');
|
|
for(i in excludeclasses) {
|
|
$('#id_classcheckbox_' + excludeclasses[i]).attr('checked', true);
|
|
}
|
|
}
|
|
setup_excludeclass_list = function() {
|
|
if( $.trim($('#id_excludeclassdialog_list').html()) ) {
|
|
select_excludeclass_checkboxes()
|
|
}
|
|
else {
|
|
$('#id_excludeclassdialog_list').html('Loading...');
|
|
$('#id_excludeclassdialog_ok').prop('disabled', true)
|
|
$('#id_excludeclassdialog_ok').addClass('disabled')
|
|
$.ajax({
|
|
url: '{% url 'class_checklist' 'master' %}',
|
|
dataType: 'html',
|
|
success: function( resp ) {
|
|
$('#id_excludeclassdialog_list').html(resp);
|
|
select_excludeclass_checkboxes()
|
|
$('#id_excludeclassdialog_ok').prop('disabled', false)
|
|
$('#id_excludeclassdialog_ok').removeClass('disabled')
|
|
},
|
|
error: function( req, status, err ) {
|
|
$('#id_excludeclassdialog_list').html(err);
|
|
console.log( 'something went wrong', status, err );
|
|
}
|
|
});
|
|
}
|
|
}
|
|
$(document).ready(function() {
|
|
$('#id_selectedlayers_display').prop('readonly', true)
|
|
$('#id_excludeclasses_display').prop('readonly', true)
|
|
update_filters_enabled()
|
|
$('[data-toggle="tooltip"]').tooltip();
|
|
firstfield = $("#search-form input:text").first()
|
|
if( ! firstfield.val() )
|
|
firstfield.focus()
|
|
});
|
|
$('#id_layerdialog_select_all').click(function (e) {
|
|
$('.filterlayercheckbox').attr('checked', true);
|
|
});
|
|
$('#id_layerdialog_select_none').click(function (e) {
|
|
$('.filterlayercheckbox').attr('checked', false);
|
|
});
|
|
$('#id_layerdialog_ok').click(function (e) {
|
|
update_selected_layer_display()
|
|
});
|
|
$('#id_select_layers').click(function (e) {
|
|
setup_layer_list()
|
|
});
|
|
$('#id_excludeclassdialog_select_none').click(function (e) {
|
|
$('.filterclasscheckbox').attr('checked', false);
|
|
});
|
|
$('#id_excludeclassdialog_ok').click(function (e) {
|
|
update_excludeclasses_display()
|
|
});
|
|
$('#id_select_excludeclasses').click(function (e) {
|
|
setup_excludeclass_list()
|
|
});
|
|
$('#id_reversed').click(function (e) {
|
|
update_filters_enabled()
|
|
});
|
|
{% block scripts_extra %}
|
|
{% endblock %}
|
|
</script>
|
|
{% endblock %}
|