From d29e4cd040f06cc62210231f6fae8532f2d56cb6 Mon Sep 17 00:00:00 2001 From: Elliot Smith Date: Fri, 15 Jan 2016 13:00:44 +0200 Subject: bitbake: toastergui: use ToasterTable for projects page The projects page uses the old approach for showing tables, which means a template for each table. This means that applying changes to ToasterTable (which is used for most tables) has no effect on the layout, styling and behaviour for these older tables, and requires additional duplicated effort. Move the projects page to use ToasterTable instead, to remove the duplication of effort. [YOCTO #8738] (Bitbake rev: df56a35bc71639457329c4b58839976c5ee40106) Signed-off-by: Elliot Smith Signed-off-by: Ed Bartosh Signed-off-by: Richard Purdie --- bitbake/lib/toaster/toastergui/tables.py | 226 ++++++++++++++++++++- .../templates/projects-toastertable.html | 36 ++++ bitbake/lib/toaster/toastergui/urls.py | 6 + 3 files changed, 265 insertions(+), 3 deletions(-) create mode 100644 bitbake/lib/toaster/toastergui/templates/projects-toastertable.html (limited to 'bitbake') diff --git a/bitbake/lib/toaster/toastergui/tables.py b/bitbake/lib/toaster/toastergui/tables.py index 38088201d8..e5cab48c48 100644 --- a/bitbake/lib/toaster/toastergui/tables.py +++ b/bitbake/lib/toaster/toastergui/tables.py @@ -21,13 +21,12 @@ from toastergui.widgets import ToasterTable from orm.models import Recipe, ProjectLayer, Layer_Version, Machine, Project -from orm.models import CustomImageRecipe, Package -from django.db.models import Q, Max +from orm.models import CustomImageRecipe, Package, Build +from django.db.models import Q, Max, Count from django.conf.urls import url from django.core.urlresolvers import reverse from django.views.generic import TemplateView - class ProjectFiltersMixin(object): """Common mixin for recipe, machine in project filters""" @@ -633,3 +632,224 @@ class SelectPackagesTable(ToasterTable): "the package content of you custom image", static_data_name="add_rm_pkg_btn", static_data_template='{% include "pkg_add_rm_btn.html" %}') + +class ProjectsTable(ToasterTable): + """Table of projects in Toaster""" + + def __init__(self, *args, **kwargs): + super(ProjectsTable, self).__init__(*args, **kwargs) + self.default_orderby = 'updated' + self.title = 'All projects' + self.static_context_extra['Build'] = Build + + def get_context_data(self, **kwargs): + return super(ProjectsTable, self).get_context_data(**kwargs) + + def setup_queryset(self, *args, **kwargs): + queryset = Project.objects.all() + + # annotate each project with its number of builds + queryset = queryset.annotate(num_builds=Count('build')) + + # exclude the command line builds project if it has no builds + q_default_with_builds = Q(is_default=True) & Q(num_builds__gt=0) + queryset = queryset.filter(Q(is_default=False) | + q_default_with_builds) + + # order rows + queryset = queryset.order_by(self.default_orderby) + + self.queryset = queryset + + # columns: last activity on (updated) - DEFAULT, project (name), release, machine, number of builds, last build outcome, recipe (name), errors, warnings, image files + def setup_columns(self, *args, **kwargs): + name_template = ''' + {% load project_url_tag %} + + + {{data.name}} + + + ''' + + last_activity_on_template = ''' + {% load project_url_tag %} + + + {{data.updated | date:"d/m/y H:i"}} + + + ''' + + release_template = ''' + + {% if data.release %} + + {{data.release.name}} + + {% elif data.is_default %} + Not applicable + + {% else %} + No release available + {% endif %} + + ''' + + machine_template = ''' + + {% if data.is_default %} + Not applicable + + {% else %} + + {{data.get_current_machine_name}} + + {% endif %} + + ''' + + number_of_builds_template = ''' + {% if data.get_number_of_builds > 0 %} + + {{data.get_number_of_builds}} + + {% else %} + 0 + {% endif %} + ''' + + last_build_outcome_template = ''' + {% if data.get_number_of_builds > 0 %} + + {% if data.get_last_outcome == extra.Build.SUCCEEDED %} + + {% elif data.get_last_outcome == extra.Build.FAILED %} + + {% endif %} + + {% endif %} + ''' + + recipe_template = ''' + {% if data.get_number_of_builds > 0 %} + + {{data.get_last_target}} + + {% endif %} + ''' + + errors_template = ''' + {% if data.get_number_of_builds > 0 %} + + {{data.get_last_errors}} error{{data.get_last_errors | pluralize}} + + {% endif %} + ''' + + warnings_template = ''' + {% if data.get_number_of_builds > 0 %} + + {{data.get_last_warnings}} warning{{data.get_last_warnings | pluralize}} + + {% endif %} + ''' + + image_files_template = ''' + {% load projecttags %} + {% if data.get_number_of_builds > 0 and data.get_last_outcome == extra.Build.SUCCEEDED %} + + {{fstypes | get_dict_value:data.id}} + + {% endif %} + ''' + + self.add_column(title='Project', + hideable=False, + orderable=True, + static_data_name='name', + static_data_template=name_template) + + self.add_column(title='Last activity on', + help_text='Starting date and time of the \ + last project build. If the project has no \ + builds, this shows the date the project was \ + created.', + hideable=True, + orderable=True, + static_data_name='updated', + static_data_template=last_activity_on_template) + + self.add_column(title='Release', + help_text='The version of the build system used by \ + the project', + hideable=False, + orderable=True, + static_data_name='release', + static_data_template=release_template) + + self.add_column(title='Machine', + help_text='The hardware currently selected for the \ + project', + hideable=False, + orderable=False, + static_data_name='machine', + static_data_template=machine_template) + + self.add_column(title='Number of builds', + help_text='The number of builds which have been run \ + for the project', + hideable=True, + orderable=False, + static_data_name='number_of_builds', + static_data_template=number_of_builds_template) + + self.add_column(title='Last build outcome', + help_text='Indicates whether the last project build \ + completed successfully or failed', + hideable=True, + orderable=False, + static_data_name='last_build_outcome', + static_data_template=last_build_outcome_template) + + self.add_column(title='Recipe', + help_text='The last recipe which was built in this \ + project', + hideable=True, + orderable=False, + static_data_name='recipe_name', + static_data_template=recipe_template) + + self.add_column(title='Errors', + help_text='The number of errors encountered during \ + the last project build (if any)', + hideable=True, + orderable=False, + static_data_name='errors', + static_data_template=errors_template) + + self.add_column(title='Warnings', + help_text='The number of warnings encountered during \ + the last project build (if any)', + hideable=True, + orderable=False, + static_data_name='warnings', + static_data_template=warnings_template) + + self.add_column(title='Image files', + help_text='', + hideable=True, + orderable=False, + static_data_name='image_files', + static_data_template=image_files_template) diff --git a/bitbake/lib/toaster/toastergui/templates/projects-toastertable.html b/bitbake/lib/toaster/toastergui/templates/projects-toastertable.html new file mode 100644 index 0000000000..5814f32d06 --- /dev/null +++ b/bitbake/lib/toaster/toastergui/templates/projects-toastertable.html @@ -0,0 +1,36 @@ +{% extends 'base.html' %} + +{% block title %} All projects - Toaster {% endblock %} + +{% block pagecontent %} + + + + {% url 'projects' as xhr_table_url %} + {% include 'toastertable.html' %} + + + +{% endblock %} diff --git a/bitbake/lib/toaster/toastergui/urls.py b/bitbake/lib/toaster/toastergui/urls.py index 2bf2d99ae7..da97a31133 100644 --- a/bitbake/lib/toaster/toastergui/urls.py +++ b/bitbake/lib/toaster/toastergui/urls.py @@ -75,8 +75,14 @@ urlpatterns = patterns('toastergui.views', url(r'^newproject/$', 'newproject', name='newproject'), + # TODO remove when new toaster table is ready url(r'^projects/$', 'projects', name='all-projects'), + # TODO move to /projects/ when new toaster table is ready + url(r'^projects-new/$', + tables.ProjectsTable.as_view(template_name="projects-toastertable.html"), + name='all-projects-new'), + url(r'^project/(?P\d+)/$', 'project', name='project'), url(r'^project/(?P\d+)/configuration$', 'projectconf', name='projectconf'), url(r'^project/(?P\d+)/builds/$', 'projectbuilds', name='projectbuilds'), -- cgit v1.2.3-54-g00ecf