diff options
author | Elliot Smith <elliot.smith@intel.com> | 2016-01-15 13:00:44 +0200 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2016-01-15 16:29:59 +0000 |
commit | d29e4cd040f06cc62210231f6fae8532f2d56cb6 (patch) | |
tree | ef280d418083b5ec952d8fdc75ed6d9479288cdb /bitbake | |
parent | b1256dbc59d24bd1274f4191325ec1f5145e99b6 (diff) | |
download | poky-d29e4cd040f06cc62210231f6fae8532f2d56cb6.tar.gz |
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 <elliot.smith@intel.com>
Signed-off-by: Ed Bartosh <ed.bartosh@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r-- | bitbake/lib/toaster/toastergui/tables.py | 226 | ||||
-rw-r--r-- | bitbake/lib/toaster/toastergui/templates/projects-toastertable.html | 36 | ||||
-rw-r--r-- | bitbake/lib/toaster/toastergui/urls.py | 6 |
3 files changed, 265 insertions, 3 deletions
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 @@ | |||
21 | 21 | ||
22 | from toastergui.widgets import ToasterTable | 22 | from toastergui.widgets import ToasterTable |
23 | from orm.models import Recipe, ProjectLayer, Layer_Version, Machine, Project | 23 | from orm.models import Recipe, ProjectLayer, Layer_Version, Machine, Project |
24 | from orm.models import CustomImageRecipe, Package | 24 | from orm.models import CustomImageRecipe, Package, Build |
25 | from django.db.models import Q, Max | 25 | from django.db.models import Q, Max, Count |
26 | from django.conf.urls import url | 26 | from django.conf.urls import url |
27 | from django.core.urlresolvers import reverse | 27 | from django.core.urlresolvers import reverse |
28 | from django.views.generic import TemplateView | 28 | from django.views.generic import TemplateView |
29 | 29 | ||
30 | |||
31 | class ProjectFiltersMixin(object): | 30 | class ProjectFiltersMixin(object): |
32 | """Common mixin for recipe, machine in project filters""" | 31 | """Common mixin for recipe, machine in project filters""" |
33 | 32 | ||
@@ -633,3 +632,224 @@ class SelectPackagesTable(ToasterTable): | |||
633 | "the package content of you custom image", | 632 | "the package content of you custom image", |
634 | static_data_name="add_rm_pkg_btn", | 633 | static_data_name="add_rm_pkg_btn", |
635 | static_data_template='{% include "pkg_add_rm_btn.html" %}') | 634 | static_data_template='{% include "pkg_add_rm_btn.html" %}') |
635 | |||
636 | class ProjectsTable(ToasterTable): | ||
637 | """Table of projects in Toaster""" | ||
638 | |||
639 | def __init__(self, *args, **kwargs): | ||
640 | super(ProjectsTable, self).__init__(*args, **kwargs) | ||
641 | self.default_orderby = 'updated' | ||
642 | self.title = 'All projects' | ||
643 | self.static_context_extra['Build'] = Build | ||
644 | |||
645 | def get_context_data(self, **kwargs): | ||
646 | return super(ProjectsTable, self).get_context_data(**kwargs) | ||
647 | |||
648 | def setup_queryset(self, *args, **kwargs): | ||
649 | queryset = Project.objects.all() | ||
650 | |||
651 | # annotate each project with its number of builds | ||
652 | queryset = queryset.annotate(num_builds=Count('build')) | ||
653 | |||
654 | # exclude the command line builds project if it has no builds | ||
655 | q_default_with_builds = Q(is_default=True) & Q(num_builds__gt=0) | ||
656 | queryset = queryset.filter(Q(is_default=False) | | ||
657 | q_default_with_builds) | ||
658 | |||
659 | # order rows | ||
660 | queryset = queryset.order_by(self.default_orderby) | ||
661 | |||
662 | self.queryset = queryset | ||
663 | |||
664 | # columns: last activity on (updated) - DEFAULT, project (name), release, machine, number of builds, last build outcome, recipe (name), errors, warnings, image files | ||
665 | def setup_columns(self, *args, **kwargs): | ||
666 | name_template = ''' | ||
667 | {% load project_url_tag %} | ||
668 | <span data-project-field="name"> | ||
669 | <a href="{% project_url data %}"> | ||
670 | {{data.name}} | ||
671 | </a> | ||
672 | </span> | ||
673 | ''' | ||
674 | |||
675 | last_activity_on_template = ''' | ||
676 | {% load project_url_tag %} | ||
677 | <span data-project-field="updated"> | ||
678 | <a href="{% project_url data %}"> | ||
679 | {{data.updated | date:"d/m/y H:i"}} | ||
680 | </a> | ||
681 | </span> | ||
682 | ''' | ||
683 | |||
684 | release_template = ''' | ||
685 | <span data-project-field="release"> | ||
686 | {% if data.release %} | ||
687 | <a href="{% url 'project' data.id %}#project-details"> | ||
688 | {{data.release.name}} | ||
689 | </a> | ||
690 | {% elif data.is_default %} | ||
691 | <span class="muted">Not applicable</span> | ||
692 | <i class="icon-question-sign get-help hover-help" | ||
693 | data-original-title="This project does not have a release set. | ||
694 | It simply collects information about the builds you start from | ||
695 | the command line while Toaster is running" | ||
696 | style="visibility: hidden;"> | ||
697 | </i> | ||
698 | {% else %} | ||
699 | No release available | ||
700 | {% endif %} | ||
701 | </span> | ||
702 | ''' | ||
703 | |||
704 | machine_template = ''' | ||
705 | <span data-project-field="machine"> | ||
706 | {% if data.is_default %} | ||
707 | <span class="muted">Not applicable</span> | ||
708 | <i class="icon-question-sign get-help hover-help" | ||
709 | data-original-title="This project does not have a machine | ||
710 | set. It simply collects information about the builds you | ||
711 | start from the command line while Toaster is running" | ||
712 | style="visibility: hidden;"></i> | ||
713 | {% else %} | ||
714 | <a href="{% url 'project' data.id %}#machine-distro"> | ||
715 | {{data.get_current_machine_name}} | ||
716 | </a> | ||
717 | {% endif %} | ||
718 | </span> | ||
719 | ''' | ||
720 | |||
721 | number_of_builds_template = ''' | ||
722 | {% if data.get_number_of_builds > 0 %} | ||
723 | <a href="{% url 'projectbuilds' data.id %}"> | ||
724 | {{data.get_number_of_builds}} | ||
725 | </a> | ||
726 | {% else %} | ||
727 | <span class="muted">0</span> | ||
728 | {% endif %} | ||
729 | ''' | ||
730 | |||
731 | last_build_outcome_template = ''' | ||
732 | {% if data.get_number_of_builds > 0 %} | ||
733 | <a href="{% url 'builddashboard' data.get_last_build_id %}"> | ||
734 | {% if data.get_last_outcome == extra.Build.SUCCEEDED %} | ||
735 | <i class="icon-ok-sign success"></i> | ||
736 | {% elif data.get_last_outcome == extra.Build.FAILED %} | ||
737 | <i class="icon-minus-sign error"></i> | ||
738 | {% endif %} | ||
739 | </a> | ||
740 | {% endif %} | ||
741 | ''' | ||
742 | |||
743 | recipe_template = ''' | ||
744 | {% if data.get_number_of_builds > 0 %} | ||
745 | <a href="{% url "builddashboard" data.get_last_build_id %}"> | ||
746 | {{data.get_last_target}} | ||
747 | </a> | ||
748 | {% endif %} | ||
749 | ''' | ||
750 | |||
751 | errors_template = ''' | ||
752 | {% if data.get_number_of_builds > 0 %} | ||
753 | <a class="errors.count error" | ||
754 | href="{% url "builddashboard" data.get_last_build_id %}#errors"> | ||
755 | {{data.get_last_errors}} error{{data.get_last_errors | pluralize}} | ||
756 | </a> | ||
757 | {% endif %} | ||
758 | ''' | ||
759 | |||
760 | warnings_template = ''' | ||
761 | {% if data.get_number_of_builds > 0 %} | ||
762 | <a class="warnings.count warning" | ||
763 | href="{% url "builddashboard" data.get_last_build_id %}#warnings"> | ||
764 | {{data.get_last_warnings}} warning{{data.get_last_warnings | pluralize}} | ||
765 | </a> | ||
766 | {% endif %} | ||
767 | ''' | ||
768 | |||
769 | image_files_template = ''' | ||
770 | {% load projecttags %} | ||
771 | {% if data.get_number_of_builds > 0 and data.get_last_outcome == extra.Build.SUCCEEDED %} | ||
772 | <a href="{% url "builddashboard" data.get_last_build_id %}#images"> | ||
773 | {{fstypes | get_dict_value:data.id}} | ||
774 | </a> | ||
775 | {% endif %} | ||
776 | ''' | ||
777 | |||
778 | self.add_column(title='Project', | ||
779 | hideable=False, | ||
780 | orderable=True, | ||
781 | static_data_name='name', | ||
782 | static_data_template=name_template) | ||
783 | |||
784 | self.add_column(title='Last activity on', | ||
785 | help_text='Starting date and time of the \ | ||
786 | last project build. If the project has no \ | ||
787 | builds, this shows the date the project was \ | ||
788 | created.', | ||
789 | hideable=True, | ||
790 | orderable=True, | ||
791 | static_data_name='updated', | ||
792 | static_data_template=last_activity_on_template) | ||
793 | |||
794 | self.add_column(title='Release', | ||
795 | help_text='The version of the build system used by \ | ||
796 | the project', | ||
797 | hideable=False, | ||
798 | orderable=True, | ||
799 | static_data_name='release', | ||
800 | static_data_template=release_template) | ||
801 | |||
802 | self.add_column(title='Machine', | ||
803 | help_text='The hardware currently selected for the \ | ||
804 | project', | ||
805 | hideable=False, | ||
806 | orderable=False, | ||
807 | static_data_name='machine', | ||
808 | static_data_template=machine_template) | ||
809 | |||
810 | self.add_column(title='Number of builds', | ||
811 | help_text='The number of builds which have been run \ | ||
812 | for the project', | ||
813 | hideable=True, | ||
814 | orderable=False, | ||
815 | static_data_name='number_of_builds', | ||
816 | static_data_template=number_of_builds_template) | ||
817 | |||
818 | self.add_column(title='Last build outcome', | ||
819 | help_text='Indicates whether the last project build \ | ||
820 | completed successfully or failed', | ||
821 | hideable=True, | ||
822 | orderable=False, | ||
823 | static_data_name='last_build_outcome', | ||
824 | static_data_template=last_build_outcome_template) | ||
825 | |||
826 | self.add_column(title='Recipe', | ||
827 | help_text='The last recipe which was built in this \ | ||
828 | project', | ||
829 | hideable=True, | ||
830 | orderable=False, | ||
831 | static_data_name='recipe_name', | ||
832 | static_data_template=recipe_template) | ||
833 | |||
834 | self.add_column(title='Errors', | ||
835 | help_text='The number of errors encountered during \ | ||
836 | the last project build (if any)', | ||
837 | hideable=True, | ||
838 | orderable=False, | ||
839 | static_data_name='errors', | ||
840 | static_data_template=errors_template) | ||
841 | |||
842 | self.add_column(title='Warnings', | ||
843 | help_text='The number of warnings encountered during \ | ||
844 | the last project build (if any)', | ||
845 | hideable=True, | ||
846 | orderable=False, | ||
847 | static_data_name='warnings', | ||
848 | static_data_template=warnings_template) | ||
849 | |||
850 | self.add_column(title='Image files', | ||
851 | help_text='', | ||
852 | hideable=True, | ||
853 | orderable=False, | ||
854 | static_data_name='image_files', | ||
855 | 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 @@ | |||
1 | {% extends 'base.html' %} | ||
2 | |||
3 | {% block title %} All projects - Toaster {% endblock %} | ||
4 | |||
5 | {% block pagecontent %} | ||
6 | |||
7 | <div class="page-header top-air"> | ||
8 | <h1 data-role="page-title"></h1> | ||
9 | </div> | ||
10 | |||
11 | {% url 'projects' as xhr_table_url %} | ||
12 | {% include 'toastertable.html' %} | ||
13 | |||
14 | <script> | ||
15 | $(document).ready(function () { | ||
16 | var tableElt = $("#{{table_name}}"); | ||
17 | var titleElt = $("[data-role='page-title']"); | ||
18 | |||
19 | tableElt.on("table-done", function (e, total, tableParams) { | ||
20 | var title = "All projects"; | ||
21 | |||
22 | if (tableParams.search || tableParams.filter) { | ||
23 | if (total === 0) { | ||
24 | title = "No projects found"; | ||
25 | } | ||
26 | else if (total > 0) { | ||
27 | title = total + " project" + (total > 1 ? 's' : '') + " found"; | ||
28 | } | ||
29 | } | ||
30 | |||
31 | titleElt.text(title); | ||
32 | }); | ||
33 | }); | ||
34 | </script> | ||
35 | |||
36 | {% 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', | |||
75 | url(r'^newproject/$', 'newproject', name='newproject'), | 75 | url(r'^newproject/$', 'newproject', name='newproject'), |
76 | 76 | ||
77 | 77 | ||
78 | # TODO remove when new toaster table is ready | ||
78 | url(r'^projects/$', 'projects', name='all-projects'), | 79 | url(r'^projects/$', 'projects', name='all-projects'), |
79 | 80 | ||
81 | # TODO move to /projects/ when new toaster table is ready | ||
82 | url(r'^projects-new/$', | ||
83 | tables.ProjectsTable.as_view(template_name="projects-toastertable.html"), | ||
84 | name='all-projects-new'), | ||
85 | |||
80 | url(r'^project/(?P<pid>\d+)/$', 'project', name='project'), | 86 | url(r'^project/(?P<pid>\d+)/$', 'project', name='project'), |
81 | url(r'^project/(?P<pid>\d+)/configuration$', 'projectconf', name='projectconf'), | 87 | url(r'^project/(?P<pid>\d+)/configuration$', 'projectconf', name='projectconf'), |
82 | url(r'^project/(?P<pid>\d+)/builds/$', 'projectbuilds', name='projectbuilds'), | 88 | url(r'^project/(?P<pid>\d+)/builds/$', 'projectbuilds', name='projectbuilds'), |