Skip to content

Commit 0b4e311

Browse files
JelteFclaude
andcommitted
Complete Bootstrap 5 upgrade with navigation and UX improvements
This commit completes the Bootstrap 5.3.7 upgrade with significant navigation and user experience improvements: **Bootstrap 5 Migration:** - Updated JavaScript APIs: modal() → new bootstrap.Modal() - Fixed modal header structure with proper title positioning - Updated button classes: btn-default → btn-outline-secondary - Fixed form submit buttons to use btn-primary styling **Navigation System:** - Replaced basic menu with full-width dark navbar - Added active state highlighting for current pages - Integrated search functionality in header - Added GitHub contribution button with proper icon styling - Created "More" dropdown for secondary navigation items - Added conditional "New Patch" link when CF is available **Homepage Redesign:** - Merged dashboard functionality into homepage for logged-in users - Added experience-based help text for new users (30+ days) - Removed separate /me/ route and template - Added login prompt for non-authenticated users - Integrated complete patch listing with filtering **Typography & Consistency:** - Updated all date ranges to use en dash (–) instead of hyphen (-) - Added CommitFest dates to breadcrumbs on new patch page - Fixed modal close button positioning and sizing **Context & Configuration:** - Added global context processor for navigation state - Added CommitFest.get_current() method for nav logic - Updated URL patterns and view logic Closes #74 - "New Patch" button now visible in navigation Improves overall UX with modern Bootstrap 5 components and better information architecture. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 4c465f6 commit 0b4e311

File tree

16 files changed

+408
-253
lines changed

16 files changed

+408
-253
lines changed

.claude/settings.local.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"Bash(make:*)",
5+
"Bash(git add:*)"
6+
],
7+
"deny": []
8+
}
9+
}

CLAUDE.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
This is a Django 4.2 application that manages commitfests for the PostgreSQL community. A commitfest is a collection of patches and reviews as part of the PostgreSQL development process. The application tracks patches, their status, reviews, and integrates with cfbot for automated testing.
8+
9+
## Development Setup
10+
11+
### Environment Setup
12+
```bash
13+
# Create virtual environment
14+
python3 -m venv env
15+
source env/bin/activate
16+
pip install -e '.[dev]'
17+
18+
# Database setup
19+
createdb pgcommitfest
20+
cp pgcommitfest/local_settings_example.py pgcommitfest/local_settings.py
21+
22+
# Run migrations
23+
./manage.py migrate
24+
25+
# Load test data (optional)
26+
./manage.py loaddata auth_data.json
27+
./manage.py loaddata commitfest_data.json
28+
```
29+
30+
### Development Commands
31+
32+
Start development server:
33+
```bash
34+
./run_dev.py
35+
```
36+
37+
Database management:
38+
```bash
39+
./manage.py migrate # Run migrations
40+
./manage.py createsuperuser # Create admin user
41+
./manage.py loaddata <file> # Load fixtures
42+
```
43+
44+
Code formatting and linting:
45+
```bash
46+
make format # Format code (ruff, biome, djhtml)
47+
make lint # Check code quality
48+
make lint-fix # Fix linting issues
49+
make lint-fix-unsafe # Fix linting issues (unsafe)
50+
make fix # Format + lint-fix-unsafe
51+
```
52+
53+
## Application Architecture
54+
55+
### Core Django Apps
56+
- **pgcommitfest.commitfest**: Main application handling patches, commitfests, reviews
57+
- **pgcommitfest.mailqueue**: Email notification system
58+
- **pgcommitfest.userprofile**: User profile management and preferences
59+
60+
### Key Models
61+
- **CommitFest**: Represents a commitfest period with status (Open/In Progress/Closed)
62+
- **Patch**: Individual patches with status tracking, reviews, and cfbot integration
63+
- **PatchOnCommitFest**: Links patches to specific commitfests
64+
- **MailThread**: Integration with PostgreSQL mailing list archives
65+
- **CfbotTask/CfbotBranch**: cfbot CI integration for automated testing
66+
67+
### Authentication
68+
Custom authentication backend (`pgcommitfest.auth.AuthBackend`) integrates with PostgreSQL community authentication system.
69+
70+
### Static Files and Media
71+
- Static files served from `/media/` (CSS, JS, images)
72+
- JavaScript: jQuery, Bootstrap, custom commitfest.js
73+
- CSS: Bootstrap with custom commitfest.css
74+
75+
### Key Features
76+
- Patch status tracking (Waiting for Author, Needs Review, Ready for Committer, etc.)
77+
- Email notifications for patch updates
78+
- Integration with PostgreSQL mailing list archives
79+
- cfbot CI integration for automated testing
80+
- User subscription system for patches
81+
- Bulk email functionality for commitfest managers
82+
83+
### Database
84+
PostgreSQL database with custom fields and constraints. Uses Django migrations for schema management.
85+
86+
## Testing
87+
88+
The application does not appear to have a formal test suite. Manual testing is done through:
89+
- Development server at http://localhost:8007
90+
- Admin interface at http://localhost:8007/admin
91+
- Test data loaded via fixtures
92+
93+
## Deployment
94+
95+
- Staging: https://commitfest-test.postgresql.org/ (auto-deploys from main branch)
96+
- Production: Auto-deploys from prod branch
97+
- Uses uWSGI for serving (configured in uwsgi_dev.ini)

benchmark.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
insert into commitfest_patch SELECT i as id, 'test' || i, '', '', now(), now(), now(), NULL, 1, NULL from generate_series(1010, 100000) i;
2+
insert into commitfest_patchoncommitfest SELECT i as id, now(), NULL, 1, 2, i from generate_series(1010, 100000) i;
3+
insert into commitfest_cfbotbranch SELECT i, i, 'cf/' || i, NULL, '', 'failed', now(), now() from generate_series(1010, 100000) i;
4+
insert into auth_user SELECT i, 'abc', NULL, FALSE, 'user' || i, 'first' || i, 'last' || i, 'user' || i || '@example.com', FALSE, TRUE, now() from generate_series(100, 1000) i;

media/commitfest/css/commitfest.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,8 @@ a .badge {
141141
a:hover .badge {
142142
text-decoration: none !important;
143143
}
144+
145+
/* Make GitHub icon white in dark navbar */
146+
.navbar-dark .github-logo {
147+
filter: brightness(0) invert(1);
148+
}

media/commitfest/js/commitfest.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@ function browseThreads(attachfunc, closefunc) {
5252
$("#attachModal").on("hidden.bs.modal", (e) => {
5353
if (closefunc) closefunc();
5454
});
55-
$("#attachModal").modal();
55+
const attachModal = new bootstrap.Modal(
56+
document.getElementById("attachModal"),
57+
);
58+
attachModal.show();
5659
findLatestThreads();
5760

5861
$("#doAttachThreadButton").unbind("click");
@@ -74,7 +77,10 @@ function browseThreads(attachfunc, closefunc) {
7477
$("#attachThreadSearchButton").addClass("disabled");
7578
$("#attachThreadButton").addClass("disabled");
7679
if (attachfunc(msgid, subject)) {
77-
$("#attachModal").modal("hide");
80+
const attachModal = bootstrap.Modal.getInstance(
81+
document.getElementById("attachModal"),
82+
);
83+
attachModal.hide();
7884
}
7985
$("#attachThreadListWrap").removeClass("loading");
8086
$("#attachThreadSearchButton").removeClass("disabled");
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from .models import CommitFest
2+
3+
4+
def global_context(request):
5+
"""Add global context variables available in all templates."""
6+
return {
7+
"current_cf": CommitFest.get_current(),
8+
"open_cf": CommitFest.get_open_regular(),
9+
}

pgcommitfest/commitfest/models.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def statusstring(self):
6363

6464
@property
6565
def periodstring(self):
66-
return "{0} - {1}".format(self.startdate, self.enddate)
66+
return "{0} {1}".format(self.startdate, self.enddate)
6767

6868
@property
6969
def last_open_date(self):
@@ -277,6 +277,15 @@ def get_in_progress(cls):
277277
def get_open_regular(cls):
278278
return cls.objects.filter(status=CommitFest.STATUS_OPEN, draft=False).first()
279279

280+
@classmethod
281+
def get_current(cls):
282+
# First try to get in-progress CommitFest
283+
current = cls.get_in_progress()
284+
if current:
285+
return current
286+
# If no in-progress, fall back to open regular CommitFest
287+
return cls.get_open_regular()
288+
280289
def __str__(self):
281290
return self.name
282291

pgcommitfest/commitfest/templates/base.html

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,52 @@
1414
</head>
1515
<body>
1616
<!-- Main Navigation -->
17-
<nav class="navbar navbar-expand-lg navbar-light bg-light mb-3">
17+
<nav class="navbar navbar-expand-lg navbar-dark bg-dark mb-3">
1818
<div class="container-fluid">
1919
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#mainNavbar" aria-controls="mainNavbar" aria-expanded="false" aria-label="Toggle navigation">
2020
<span class="navbar-toggler-icon"></span>
2121
</button>
2222
<div class="collapse navbar-collapse" id="mainNavbar">
2323
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
2424
<li class="nav-item">
25-
<a class="nav-link" href="/me/">Dashboard</a>
25+
<a class="nav-link{% if request.resolver_match.url_name == 'home' or request.path == '/' %} active{% endif %}" href="/">Home</a>
2626
</li>
27+
{% if current_cf %}
28+
<li class="nav-item">
29+
<a class="nav-link{% if '/new/' in request.path %} active{% endif %}" href="/{{current_cf.id}}/new/">New Patch</a>
30+
</li>
31+
{% endif %}
32+
{% if current_cf %}
33+
<li class="nav-item">
34+
<a class="nav-link{% if cf and cf.is_in_progress %} active{% endif %}" href="/current/">Current CF</a>
35+
</li>
36+
{% endif %}
2737
<li class="nav-item">
28-
<a class="nav-link" href="/current/">Current CF</a>
38+
<a class="nav-link{% if cf and cf.is_open_regular %} active{% endif %}" href="/open/">Open CF</a>
2939
</li>
3040
<li class="nav-item">
31-
<a class="nav-link" href="/open/">Open CF</a>
41+
<a class="nav-link{% if cf and cf.is_open_draft %} active{% endif %}" href="/draft/">Draft CF</a>
3242
</li>
33-
<li class="nav-item">
34-
<a class="nav-link" href="/activity/">Activity Log</a>
35-
</li>
36-
<li class="nav-item">
37-
<a class="nav-link" href="/commitfest_history/">All CommitFests</a>
43+
<li class="nav-item dropdown">
44+
<a class="nav-link dropdown-toggle{% if '/activity/' in request.path or '/commitfest_history/' in request.path %} active{% endif %}" href="#" id="moreDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
45+
More
46+
</a>
47+
<ul class="dropdown-menu" aria-labelledby="moreDropdown">
48+
<li><a class="dropdown-item" href="/activity/">Activity Log</a></li>
49+
<li><a class="dropdown-item" href="/commitfest_history/">All CommitFests</a></li>
50+
</ul>
3851
</li>
3952
<li class="nav-item">
40-
<a class="nav-link" href="/help/">Help</a>
53+
<a class="nav-link{% if '/help/' in request.path %} active{% endif %}" href="/help/">Help</a>
4154
</li>
4255
</ul>
56+
<div class="d-flex gap-2 align-items-center">
57+
<form method="GET" action="/search/" class="d-flex gap-1">
58+
<input type="text" class="form-control" name="searchterm" placeholder="Email Message-ID or keywords" style="width: 250px;">
59+
<button type="submit" class="btn btn-outline-light">Search</button>
60+
</form>
61+
<a class="btn btn-primary" href="https://github.com/postgres/pgcommitfest" target="_blank"><img class="github-logo" src="/media/commitfest/github-mark.svg"/> Contribute on GitHub</a>
62+
</div>
4363
</div>
4464
</div>
4565
</nav>

pgcommitfest/commitfest/templates/base_form.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
{%endfor%}
3232
<div class="form-group">
3333
<div class="col-lg-12">
34-
<div class="control"><input type="submit" class="btn btn-outline-secondary" value="{{savebutton|default:"Save"}}"></div>
34+
<div class="control"><input type="submit" class="btn btn-primary" value="{{savebutton|default:"Save"}}"></div>
3535
</div>
3636
</div>
3737
</form>
@@ -45,8 +45,8 @@
4545
<div class="modal-dialog modal-lg">
4646
<div class="modal-content">
4747
<div class="modal-header">
48+
<h3 class="modal-title">Search user</h3>
4849
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
49-
<h3>Search user</h3>
5050
</div>
5151
<div class="modal-body">
5252
<form class="d-flex gap-2" style="margin-bottom: 5px;">

0 commit comments

Comments
 (0)