Date: Sun, 15 Jun 2025 22:55:09 -0700
Subject: [PATCH 2/9] Added sub navigation bar items for queues.
---
DjangoPlugin/tracdjangoplugin/plugins.py | 51 ++++++++++++++++++++++++
scss/trachacks.scss | 18 +++++++++
trac-env/conf/trac.ini | 7 ++++
trac-env/templates/django_theme.html | 29 ++------------
4 files changed, 79 insertions(+), 26 deletions(-)
diff --git a/DjangoPlugin/tracdjangoplugin/plugins.py b/DjangoPlugin/tracdjangoplugin/plugins.py
index 8438dd4..5bc3664 100644
--- a/DjangoPlugin/tracdjangoplugin/plugins.py
+++ b/DjangoPlugin/tracdjangoplugin/plugins.py
@@ -88,6 +88,57 @@ def get_navigation_items(self, req):
]
+class CustomSubNavigationBar(Component):
+ """Add queue items for the sub navigation bar."""
+
+ implements(INavigationContributor)
+
+ def get_active_navigation_item(self, req):
+ stage = req.args.get("stage")
+ has_patch = req.args.get("has_patch")
+ needs_better_patch = req.args.get("needs_better_patch")
+
+ if stage == "Ready+for+checkin":
+ return "ready_for_checkin"
+ if stage == "Accepted" and has_patch == "0":
+ return "needs_patch"
+ if stage == "Accepted" and has_patch == "1" and needs_better_patch == "0":
+ return "needs_review"
+ if stage == "Accepted" and has_patch == "1" and needs_better_patch == "1":
+ return "waiting_on_author"
+
+ return "unreviewed"
+
+ def get_navigation_items(self, req):
+ return [
+ (
+ "subnav",
+ "unreviewed",
+ tag.a("Unreviewed", href="/query?stage=Unreviewed&status=!closed&order=changetime&desc=1"),
+ ),
+ (
+ "subnav",
+ "needs_patch",
+ tag.a("Needs Patch", href="/query?has_patch=0&stage=Accepted&status=!closed&order=changetime&desc=1"),
+ ),
+ (
+ "subnav",
+ "needs_review",
+ tag.a("Needs Review", href="/query?has_patch=1&needs_better_patch=0&needs_docs=0&needs_tests=0&stage=Accepted&status=!closed&order=changetime&desc=1"),
+ ),
+ (
+ "subnav",
+ "waiting_on_author",
+ tag.a("Waiting On Author", href="/query?has_patch=1&needs_better_patch=1&stage=Accepted&status=!closed&order=changetime&desc=1"),
+ ),
+ (
+ "subnav",
+ "ready_for_checkin",
+ tag.a("Ready For Checkin", href="/query?stage=Ready+for+checkin&status=!closed&order=changetime&desc=1"),
+ ),
+ ]
+
+
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..1d6160e 100644
--- a/scss/trachacks.scss
+++ b/scss/trachacks.scss
@@ -330,6 +330,24 @@ div[role="main"]{
}
}
+ #subnav {
+ @include sans-serif;
+
+ ul {
+ text-align: left;
+
+ li {
+ &.active {
+ background: $green-medium;
+ a {
+ background: none;
+ color: $white;
+ }
+ }
+ }
+ }
+ }
+
#main {
@include sans-serif;
diff --git a/trac-env/conf/trac.ini b/trac-env/conf/trac.ini
index d8bb307..c74ef95 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_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 e5d0f89..f42f27b 100644
--- a/trac-env/templates/django_theme.html
+++ b/trac-env/templates/django_theme.html
@@ -15,31 +15,6 @@
@@ -59,7 +34,9 @@
${navigation('mainnav')}
- ${navigation_queues()}
+ # if req.path_info == '/query':
+ ${navigation('subnav')}
+ # endif
Date: Fri, 19 Sep 2025 14:00:18 -0700
Subject: [PATCH 3/9] Updated link for "waiting on author" to include "needs
docs" and "needs tests".
---
DjangoPlugin/tracdjangoplugin/plugins.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/DjangoPlugin/tracdjangoplugin/plugins.py b/DjangoPlugin/tracdjangoplugin/plugins.py
index 5bc3664..5a61487 100644
--- a/DjangoPlugin/tracdjangoplugin/plugins.py
+++ b/DjangoPlugin/tracdjangoplugin/plugins.py
@@ -129,7 +129,7 @@ def get_navigation_items(self, req):
(
"subnav",
"waiting_on_author",
- tag.a("Waiting On Author", href="/query?has_patch=1&needs_better_patch=1&stage=Accepted&status=!closed&order=changetime&desc=1"),
+ tag.a("Waiting On Author", href="/query?has_patch=0&stage=Accepted&status=!closed&or&needs_better_patch=1&stage=Accepted&status=!closed&or&needs_docs=1&stage=Accepted&status=!closed&or&needs_tests=1&stage=Accepted&status=!closed&order=priority"),
),
(
"subnav",
From 98bdb04a1456ceedfa01411301ff48a630f301a7 Mon Sep 17 00:00:00 2001
From: ontowhee <82607723+ontowhee@users.noreply.github.com>
Date: Fri, 19 Sep 2025 14:01:06 -0700
Subject: [PATCH 4/9] Updated "Needs Review" to "Needs PR Review".
---
DjangoPlugin/tracdjangoplugin/plugins.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/DjangoPlugin/tracdjangoplugin/plugins.py b/DjangoPlugin/tracdjangoplugin/plugins.py
index 5a61487..d60b5eb 100644
--- a/DjangoPlugin/tracdjangoplugin/plugins.py
+++ b/DjangoPlugin/tracdjangoplugin/plugins.py
@@ -124,7 +124,7 @@ def get_navigation_items(self, req):
(
"subnav",
"needs_review",
- tag.a("Needs Review", href="/query?has_patch=1&needs_better_patch=0&needs_docs=0&needs_tests=0&stage=Accepted&status=!closed&order=changetime&desc=1"),
+ tag.a("Needs PR Review", href="/query?has_patch=1&needs_better_patch=0&needs_docs=0&needs_tests=0&stage=Accepted&status=!closed&order=changetime&desc=1"),
),
(
"subnav",
From 97897cd5ef774e1c062de34bee8d012988e41b79 Mon Sep 17 00:00:00 2001
From: ontowhee <82607723+ontowhee@users.noreply.github.com>
Date: Fri, 19 Sep 2025 14:05:34 -0700
Subject: [PATCH 5/9] Updated "Unreviewed" to be "Needs Triage".
---
DjangoPlugin/tracdjangoplugin/plugins.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/DjangoPlugin/tracdjangoplugin/plugins.py b/DjangoPlugin/tracdjangoplugin/plugins.py
index d60b5eb..6f9705e 100644
--- a/DjangoPlugin/tracdjangoplugin/plugins.py
+++ b/DjangoPlugin/tracdjangoplugin/plugins.py
@@ -114,7 +114,7 @@ def get_navigation_items(self, req):
(
"subnav",
"unreviewed",
- tag.a("Unreviewed", href="/query?stage=Unreviewed&status=!closed&order=changetime&desc=1"),
+ tag.a("Needs Triage", href="/query?stage=Unreviewed&status=!closed&order=changetime&desc=1"),
),
(
"subnav",
From aaea9a0e19a88b7652c4161733457845f9f711d8 Mon Sep 17 00:00:00 2001
From: ontowhee <82607723+ontowhee@users.noreply.github.com>
Date: Fri, 19 Sep 2025 17:38:30 -0700
Subject: [PATCH 6/9] Refactored and mark active item.
---
DjangoPlugin/tracdjangoplugin/plugins.py | 96 ++++++++++++++++--------
scss/trachacks.scss | 8 +-
trac-env/conf/trac.ini | 2 +-
trac-env/templates/django_theme.html | 2 -
4 files changed, 68 insertions(+), 40 deletions(-)
diff --git a/DjangoPlugin/tracdjangoplugin/plugins.py b/DjangoPlugin/tracdjangoplugin/plugins.py
index 6f9705e..c3c8830 100644
--- a/DjangoPlugin/tracdjangoplugin/plugins.py
+++ b/DjangoPlugin/tracdjangoplugin/plugins.py
@@ -93,50 +93,82 @@ class CustomSubNavigationBar(Component):
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_better_patch=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")
has_patch = req.args.get("has_patch")
needs_better_patch = req.args.get("needs_better_patch")
+ needs_docs = req.args.get("needs_docs")
+ needs_tests = req.args.get("needs_tests")
- if stage == "Ready+for+checkin":
+ if stage == "Unreviewed":
+ return "unreviewed"
+ if stage == "Ready for checkin":
return "ready_for_checkin"
if stage == "Accepted" and has_patch == "0":
return "needs_patch"
- if stage == "Accepted" and has_patch == "1" and needs_better_patch == "0":
- return "needs_review"
- if stage == "Accepted" and has_patch == "1" and needs_better_patch == "1":
+ if (stage == "Accepted" and has_patch == "1" and needs_better_patch == "0"
+ and needs_docs == "0" and needs_tests == "0"
+ ):
+ return "needs_pr_review"
+ if stage == "Accepted" and has_patch == "1":
return "waiting_on_author"
- return "unreviewed"
+ 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):
- return [
- (
- "subnav",
- "unreviewed",
- tag.a("Needs Triage", href="/query?stage=Unreviewed&status=!closed&order=changetime&desc=1"),
- ),
- (
- "subnav",
- "needs_patch",
- tag.a("Needs Patch", href="/query?has_patch=0&stage=Accepted&status=!closed&order=changetime&desc=1"),
- ),
- (
- "subnav",
- "needs_review",
- tag.a("Needs PR Review", href="/query?has_patch=1&needs_better_patch=0&needs_docs=0&needs_tests=0&stage=Accepted&status=!closed&order=changetime&desc=1"),
- ),
- (
- "subnav",
- "waiting_on_author",
- tag.a("Waiting On Author", href="/query?has_patch=0&stage=Accepted&status=!closed&or&needs_better_patch=1&stage=Accepted&status=!closed&or&needs_docs=1&stage=Accepted&status=!closed&or&needs_tests=1&stage=Accepted&status=!closed&order=priority"),
- ),
- (
- "subnav",
- "ready_for_checkin",
- tag.a("Ready For Checkin", href="/query?stage=Ready+for+checkin&status=!closed&order=changetime&desc=1"),
- ),
- ]
+ 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):
diff --git a/scss/trachacks.scss b/scss/trachacks.scss
index 1d6160e..0d07386 100644
--- a/scss/trachacks.scss
+++ b/scss/trachacks.scss
@@ -337,11 +337,9 @@ div[role="main"]{
text-align: left;
li {
- &.active {
- background: $green-medium;
- a {
- background: none;
- color: $white;
+ a {
+ &.active {
+ font-weight: bold;
}
}
}
diff --git a/trac-env/conf/trac.ini b/trac-env/conf/trac.ini
index c74ef95..7e406fe 100644
--- a/trac-env/conf/trac.ini
+++ b/trac-env/conf/trac.ini
@@ -87,7 +87,7 @@ wiki.order = 5.0
[subnav]
unreviewed.order = 1.0
needs_patch.order = 2.0
-needs_review.order = 3.0
+needs_pr_review.order = 3.0
waiting_on_author.order = 4.0
ready_for_checkin.order = 5.0
diff --git a/trac-env/templates/django_theme.html b/trac-env/templates/django_theme.html
index f42f27b..d817212 100644
--- a/trac-env/templates/django_theme.html
+++ b/trac-env/templates/django_theme.html
@@ -34,9 +34,7 @@
${navigation('mainnav')}
- # if req.path_info == '/query':
${navigation('subnav')}
- # endif
Date: Fri, 19 Sep 2025 20:51:20 -0700
Subject: [PATCH 7/9] Fixed params for "waiting on author".
---
DjangoPlugin/tracdjangoplugin/plugins.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/DjangoPlugin/tracdjangoplugin/plugins.py b/DjangoPlugin/tracdjangoplugin/plugins.py
index c3c8830..9bda49a 100644
--- a/DjangoPlugin/tracdjangoplugin/plugins.py
+++ b/DjangoPlugin/tracdjangoplugin/plugins.py
@@ -116,10 +116,10 @@ class CustomSubNavigationBar(Component):
"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_better_patch=1&stage=Accepted"
- "&status=assigned&status=new&order=changetime&desc=1"
+ "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"
),
},
{
From 46d66f00419b22562c6f7a5da2f37ccc44e8c637 Mon Sep 17 00:00:00 2001
From: ontowhee <82607723+ontowhee@users.noreply.github.com>
Date: Fri, 19 Sep 2025 20:56:22 -0700
Subject: [PATCH 8/9] Check the exact query_string for queues in the accepted
stage.
---
DjangoPlugin/tracdjangoplugin/plugins.py | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/DjangoPlugin/tracdjangoplugin/plugins.py b/DjangoPlugin/tracdjangoplugin/plugins.py
index 9bda49a..ee5ffb0 100644
--- a/DjangoPlugin/tracdjangoplugin/plugins.py
+++ b/DjangoPlugin/tracdjangoplugin/plugins.py
@@ -131,23 +131,18 @@ class CustomSubNavigationBar(Component):
def get_active_navigation_item(self, req):
stage = req.args.get("stage")
- has_patch = req.args.get("has_patch")
- needs_better_patch = req.args.get("needs_better_patch")
- needs_docs = req.args.get("needs_docs")
- needs_tests = req.args.get("needs_tests")
if stage == "Unreviewed":
return "unreviewed"
if stage == "Ready for checkin":
return "ready_for_checkin"
- if stage == "Accepted" and has_patch == "0":
- return "needs_patch"
- if (stage == "Accepted" and has_patch == "1" and needs_better_patch == "0"
- and needs_docs == "0" and needs_tests == "0"
- ):
- return "needs_pr_review"
- if stage == "Accepted" and has_patch == "1":
- return "waiting_on_author"
+ 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 ""
From bb935ca82449a349d3d414e992bfda35561ea4cb Mon Sep 17 00:00:00 2001
From: ontowhee <82607723+ontowhee@users.noreply.github.com>
Date: Mon, 22 Sep 2025 07:21:45 -0700
Subject: [PATCH 9/9] Fixed linting problems.
---
.TRACFREEZE.txt | 1 +
DjangoPlugin/tracdjangoplugin/plugins.py | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
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 ee5ffb0..cb00f3d 100644
--- a/DjangoPlugin/tracdjangoplugin/plugins.py
+++ b/DjangoPlugin/tracdjangoplugin/plugins.py
@@ -147,10 +147,10 @@ def get_active_navigation_item(self, req):
return ""
def _get_active_class(self, active_item, subnav_name):
- return 'active' if active_item == subnav_name else None
+ return "active" if active_item == subnav_name else None
def get_navigation_items(self, req):
- if req.path_info.startswith('/query'):
+ if req.path_info.startswith("/query"):
active_item = self.get_active_navigation_item(req)
return [
(