diff --git a/.TRACFREEZE.txt b/.TRACFREEZE.txt index 157c63d..ba2d703 100644 --- a/.TRACFREEZE.txt +++ b/.TRACFREEZE.txt @@ -102,6 +102,7 @@ trac.wiki.web_api.wikirenderer trac.wiki.web_ui.defaultwikipolicy tracdjangoplugin.plugins.customnavigationbar tracdjangoplugin.plugins.customnewticket +tracdjangoplugin.plugins.customsubnavigationbar tracdjangoplugin.plugins.customtheme tracdjangoplugin.plugins.customwikimodule tracdjangoplugin.plugins.githubbrowserwithsvnchangesets diff --git a/DjangoPlugin/tracdjangoplugin/plugins.py b/DjangoPlugin/tracdjangoplugin/plugins.py index 8438dd4..cb00f3d 100644 --- a/DjangoPlugin/tracdjangoplugin/plugins.py +++ b/DjangoPlugin/tracdjangoplugin/plugins.py @@ -88,6 +88,84 @@ def get_navigation_items(self, req): ] +class CustomSubNavigationBar(Component): + """Add queue items for the sub navigation bar.""" + + implements(INavigationContributor) + + queues = [ + { + "name": "unreviewed", + "label": "Needs Triage", + "params": "stage=Unreviewed&status=!closed&order=changetime&desc=1", + }, + { + "name": "needs_patch", + "label": "Needs Patch", + "params": "has_patch=0&stage=Accepted&status=!closed&order=changetime&desc=1", + }, + { + "name": "needs_pr_review", + "label": "Needs PR Review", + "params": ( + "has_patch=1&needs_better_patch=0&needs_docs=0&needs_tests=0&stage=Accepted" + "&status=!closed&order=changetime&desc=1" + ), + }, + { + "name": "waiting_on_author", + "label": "Waiting On Author", + "params": ( + "has_patch=1&needs_better_patch=1&stage=Accepted&status=assigned&status=new" + "&or&has_patch=1&needs_docs=1&stage=Accepted&status=assigned&status=new" + "&or&has_patch=1&needs_tests=1&stage=Accepted&status=assigned&status=new" + "&order=changetime&desc=1" + ), + }, + { + "name": "ready_for_checkin", + "label": "Ready For Checkin", + "params": "stage=Ready+for+checkin&status=!closed&order=changetime&desc=1", + }, + ] + + def get_active_navigation_item(self, req): + stage = req.args.get("stage") + + if stage == "Unreviewed": + return "unreviewed" + if stage == "Ready for checkin": + return "ready_for_checkin" + if stage == "Accepted": + if req.query_string == self.queues[1]["params"]: + return "needs_patch" + elif req.query_string == self.queues[2]["params"]: + return "needs_pr_review" + elif req.query_string == self.queues[3]["params"]: + return "waiting_on_author" + + return "" + + def _get_active_class(self, active_item, subnav_name): + return "active" if active_item == subnav_name else None + + def get_navigation_items(self, req): + if req.path_info.startswith("/query"): + active_item = self.get_active_navigation_item(req) + return [ + ( + "subnav", + queue["name"], + tag.a( + queue["label"], + href="/query?" + queue["params"], + class_=self._get_active_class(active_item, queue["name"]), + ), + ) + for queue in self.queues + ] + + class GitHubBrowserWithSVNChangesets(GitHubBrowser): def _format_changeset_link(self, formatter, ns, chgset, label, fullmatch=None): # Dead-simple version for SVN changesets. diff --git a/scss/trachacks.scss b/scss/trachacks.scss index 2ec86b2..0d07386 100644 --- a/scss/trachacks.scss +++ b/scss/trachacks.scss @@ -330,6 +330,22 @@ div[role="main"]{ } } + #subnav { + @include sans-serif; + + ul { + text-align: left; + + li { + a { + &.active { + font-weight: bold; + } + } + } + } + } + #main { @include sans-serif; diff --git a/trac-env/conf/trac.ini b/trac-env/conf/trac.ini index d8bb307..7e406fe 100644 --- a/trac-env/conf/trac.ini +++ b/trac-env/conf/trac.ini @@ -84,6 +84,13 @@ tickets.order = 2.0 timeline.order = 4.0 wiki.order = 5.0 +[subnav] +unreviewed.order = 1.0 +needs_patch.order = 2.0 +needs_pr_review.order = 3.0 +waiting_on_author.order = 4.0 +ready_for_checkin.order = 5.0 + [metanav] ; The metanav is hardcoded in templates/django_theme.html ; because it was too hard to make the login plugins play nice with each other diff --git a/trac-env/templates/django_theme.html b/trac-env/templates/django_theme.html index d912622..d817212 100644 --- a/trac-env/templates/django_theme.html +++ b/trac-env/templates/django_theme.html @@ -34,6 +34,7 @@ ${navigation('mainnav')} + ${navigation('subnav')}