Release v0.3.1 #25

Merged
Mike Bros merged 49 commits from release/v0.3.1 into main 2026-02-17 22:35:32 +00:00
Contributor

Release v0.3.1 — Phase 3.1: UI Overhaul

Changes

Menu & Navigation Refactor (OP#801)

  • OP#806: Forgejo-style user dropdown menu
  • OP#807: Restructured user settings to /user/settings
  • OP#808: Forgejo-style grouped admin sidebar navigation
  • OP#809: Visual alignment pass for menus
  • OP#810: Unit tests

Live Dashboard Editor (OP#802)

  • OP#811: User-facing CRUD routes for pages, sections, items
  • OP#814: Pencil toggle edit mode
  • OP#812: Section create/edit modal overlay
  • OP#813: Item create/edit modal overlay
  • OP#815: Removed content editing from admin panel
  • OP#816: Unit tests

Public User Profiles (OP#803)

  • OP#818: Profile visibility toggle (public/private)
  • OP#817: Public profile page at /user/{username}
  • OP#819: Unit tests

Gravatar Support (OP#804)

  • OP#820: Gravatar URL generation from email hash
  • OP#821: Admin toggle for gravatar
  • OP#822: Avatars in dropdown, profiles, user lists
  • OP#823: Unit tests

Toast System & Custom Confirm Modals (OP#948)

  • OP#949: Custom confirm modal + global htmx error handler
  • OP#950: Flash cookie persistence + CRUD success toasts
  • OP#951: User toast preferences (duration, position)
  • OP#952: Unit tests

Notifications Refactor (OP#805)

  • OP#211: Renamed invites to notifications
  • OP#824: Multiple notification types
  • OP#825: Bell icon with unread badge
  • OP#166: Subscription preferences per type
  • OP#165: Email notification for invitations
  • OP#826: Unit tests

SMTP / Email

  • OP#164: SMTP configuration and sending service
  • OP#239: Unit tests

Release Refinements

  • OP#964: Fix errcheck lint failure in SMTP test
  • OP#965: Fix confirm modal popup on every htmx request
  • OP#966: Fix duplicate goose migration version numbers
  • OP#967: Fix Alpine.js FOUC on dropdowns and edit-mode elements
  • OP#968: Move edit toggle to sticky dashboard toolbar

Checklist

  • All 41 version tasks closed in OpenProject
  • go vet ./... passing
  • go test ./... passing
  • No version file (Go — tag only)

References

Version: v0.3.1 (OpenProject v74)

## Release v0.3.1 — Phase 3.1: UI Overhaul ### Changes **Menu & Navigation Refactor (OP#801)** - OP#806: Forgejo-style user dropdown menu - OP#807: Restructured user settings to `/user/settings` - OP#808: Forgejo-style grouped admin sidebar navigation - OP#809: Visual alignment pass for menus - OP#810: Unit tests **Live Dashboard Editor (OP#802)** - OP#811: User-facing CRUD routes for pages, sections, items - OP#814: Pencil toggle edit mode - OP#812: Section create/edit modal overlay - OP#813: Item create/edit modal overlay - OP#815: Removed content editing from admin panel - OP#816: Unit tests **Public User Profiles (OP#803)** - OP#818: Profile visibility toggle (public/private) - OP#817: Public profile page at `/user/{username}` - OP#819: Unit tests **Gravatar Support (OP#804)** - OP#820: Gravatar URL generation from email hash - OP#821: Admin toggle for gravatar - OP#822: Avatars in dropdown, profiles, user lists - OP#823: Unit tests **Toast System & Custom Confirm Modals (OP#948)** - OP#949: Custom confirm modal + global htmx error handler - OP#950: Flash cookie persistence + CRUD success toasts - OP#951: User toast preferences (duration, position) - OP#952: Unit tests **Notifications Refactor (OP#805)** - OP#211: Renamed invites to notifications - OP#824: Multiple notification types - OP#825: Bell icon with unread badge - OP#166: Subscription preferences per type - OP#165: Email notification for invitations - OP#826: Unit tests **SMTP / Email** - OP#164: SMTP configuration and sending service - OP#239: Unit tests **Release Refinements** - OP#964: Fix errcheck lint failure in SMTP test - OP#965: Fix confirm modal popup on every htmx request - OP#966: Fix duplicate goose migration version numbers - OP#967: Fix Alpine.js FOUC on dropdowns and edit-mode elements - OP#968: Move edit toggle to sticky dashboard toolbar ### Checklist - [x] All 41 version tasks closed in OpenProject - [x] `go vet ./...` passing - [x] `go test ./...` passing - [x] No version file (Go — tag only) ### References Version: v0.3.1 (OpenProject v74)
Replaces the flat text-based user dropdown with a Forgejo-inspired
design featuring:
- Initials avatar circle as the dropdown trigger (replaces icon + name)
- "Signed in as" header with username
- Wrench icon for Settings (was cog)
- Server icon for Admin Panel (was cog, matching Forgejo)
- Grouped sections with dividers (user links, admin links, sign out)
- Smooth scale/opacity transitions on open/close
- ARIA attributes (aria-expanded, aria-haspopup) for accessibility
- Escape key closes the dropdown
- Tighter spacing (py-1.5 menu items, rounded-lg instead of rounded-xl)

Also normalizes dashboard switcher dropdown to use rounded-lg and py-1
for visual consistency.

Closes OP#806

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Moves all user settings routes from /settings/* to /user/settings/*
to align with Forgejo's URL conventions. Adds legacy redirect handlers
for /settings and /settings/* to preserve backwards compatibility.

Updates all internal references across routes, handlers, templates,
and sidebar navigation to use the new /user/settings paths.

Closes OP#807

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Restructures the admin sidebar into grouped sections with headings:
- Dashboard (overview), Appearance (themes), Configuration (settings,
  authentication), and Tools (impersonate, import).

Renames heading to "Site Administration", updates Dashboard icon to
tachometer-alt, renames "Auth" label to "Authentication", and removes
unused NavItem struct.

Closes OP#808

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dashboard switcher: adds escape key handler, ARIA attributes, smooth
enter/leave transitions, consistent py-1.5 padding, fixed-width icons
with gap-3 layout matching the user dropdown pattern.

Search popover: adds matching smooth enter/leave transitions.

Sidebar navLinks (admin + settings): adds left accent border on active
state and transparent border on inactive for Forgejo-style active page
indicator. Icons now use fixed w-4 text-center for column alignment.

Closes OP#809

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
test(nav): add unit tests for menu and navigation refactor
All checks were successful
CI / test (pull_request) Successful in 1m16s
CI / security (pull_request) Successful in 1m45s
CI / build (pull_request) Successful in 1m50s
CI / lint (pull_request) Successful in 2m30s
fd0be159d4
Tests user dropdown visibility: regular user sees Settings + Sign Out
but not Admin; admin sees Settings + Admin + Impersonate + Sign Out;
guest sees login link instead of dropdown.

Tests legacy /settings redirect returns 301 to /user/settings, and
subpath redirects (/settings/appearance → /user/settings/appearance).

Tests userInitial helper for avatar fallback.

Closes OP#810

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reviewed-on: #12
Reviewed-by: Mike Bros <dev@bros.ninja>
Adds profile_public column to users table with migration, updates all
user query locations (8 total) to include the new field, adds a toggle
to the profile settings page, and registers a POST handler for saving.

Closes OP#818

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds created_at column to users table, ListOwnedDashboards service method,
profile template with avatar, join date, and dashboard list. Profile is
404 for non-existent or private users unless the viewer is the owner.

Closes OP#817

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
test(profile): add unit tests for public user profiles
All checks were successful
CI / lint (pull_request) Successful in 1m14s
CI / security (pull_request) Successful in 1m52s
CI / build (pull_request) Successful in 1m54s
CI / test (pull_request) Successful in 2m7s
6f4d9d10a9
Tests profile template rendering (dashboards, empty state, owner edit link,
avatar initial, username fallback), helper functions (userInitial, itemCountLabel,
joinDate), and profile settings toggle (visibility checkbox, profile URL).

Closes OP#819

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reviewed-on: #14
Reviewed-by: Mike Bros <dev@bros.ninja>
Dashboard edit mode previously linked to /admin/* routes that require
admin privileges. Non-admin dashboard owners got 403 when clicking
edit/create links. This adds user-facing CRUD routes (/pages/*, /sections/*,
/items/*) accessible to any authenticated user, with standalone form
pages and redirect-to-dashboard after submit.

Closes OP#811

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move edit mode toggle from inline dashboard button to a persistent
pencil icon in the header navbar. Uses Alpine.store('editMode') as
global state shared between the header button and the dashboard
editMode() component which manages SortableJS drag-and-drop.

- Add CanEdit field to HeaderData, pass from render.go
- Rewrite edit-mode.js to use Alpine.store instead of local state
- Replace all x-show="editing" with x-show="$store.editMode.active"
- Remove old inline Edit/Done button from dashboard_page.templ
- Non-editable pages use empty x-data="{}" (store defaults to false)

Closes OP#814

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace full-page navigation with htmx-loaded modal overlays for
section CRUD operations in edit mode. The modal renders in-place
over the dashboard, providing context while editing.

- Add reusable Modal templ component with backdrop, escape/click-away
- Add SectionFormModal variant with shared form fields
- Add modal endpoints: /sections/new/modal, /sections/{id}/edit/modal
- Wire "Add Section" and section cog to load modals via htmx
- Add #modal-container div to dashboard page

Closes OP#812

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extend the modal system to support item CRUD operations. Item edit
pencil and "Add Item" buttons now open htmx-loaded modals instead
of navigating to separate pages.

- Add ItemFormModal with shared itemFormFields templ component
- Add modal endpoints: /items/new/modal, /items/{id}/edit/modal
- Wire item edit pencil and "Add Item" links to load modals via htmx
- Widen modal to max-w-2xl with scroll for large item forms
- Refactor ItemFormStandalone to reuse shared fields

Closes OP#813

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dashboard content (pages, sections, items) is now managed via the
live editor pencil toggle in the header. Removes admin CRUD routes,
handlers, and template files. Admin dashboard page shows a pointer
to the edit mode instead.

Closes OP#815

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests cover pencil toggle visibility (CanEdit/guest), modal
rendering (new/edit section and item forms, escape close, cancel
button), modal handler auth/validation (401/404), and admin panel
CRUD removal verification.

Closes OP#816

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fix(lint): remove unused renderFragment method
All checks were successful
CI / security (pull_request) Successful in 53s
CI / build (pull_request) Successful in 1m52s
CI / test (pull_request) Successful in 2m4s
CI / lint (pull_request) Successful in 2m33s
9623365f75
Refs OP#802

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements GravatarURL helper that generates gravatar.com URLs from
user email addresses using MD5 hashing with identicon fallback.

Closes OP#820

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds gravatar_enabled boolean to app_settings (migration 00010),
wires it through LoadSettings/UpdateSettings, and adds a checkbox
in the admin General settings panel.

Closes OP#821

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Integrates gravatar rendering across all user-facing UI surfaces:
- Header user dropdown (28px)
- Public user profile page (128px)
- Admin impersonate user list (32px)

Each location falls back to initials/icons when gravatar is disabled
or user has no email.

Closes OP#822

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
test(gravatar): add unit tests for gravatar support
All checks were successful
CI / security (pull_request) Successful in 1m5s
CI / build (pull_request) Successful in 2m2s
CI / test (pull_request) Successful in 2m17s
CI / lint (pull_request) Successful in 2m47s
bb883bec9d
Tests cover:
- URL generation with correct MD5 hash
- Email normalization (case, whitespace)
- Empty/whitespace email returns empty string
- Size parameter variations
- Header template renders gravatar img vs initial fallback
- Profile template renders gravatar img vs initial fallback

Closes OP#823

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat(header): persist navigation header across all pages
All checks were successful
CI / test (pull_request) Successful in 1m20s
CI / security (pull_request) Successful in 1m44s
CI / build (pull_request) Successful in 1m47s
CI / lint (pull_request) Successful in 2m33s
7efe4715c7
Extract buildHeaderData helper and render the shared Header component
on admin, settings, and profile pages. Dashboard-specific elements
(search, dashboard switcher, edit toggle) are conditionally hidden on
non-dashboard pages via the IsDashboardPage flag.

Refs OP#804

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace all 8 browser confirm() dialogs with a themed Alpine.js modal.
Add htmx:beforeSwap to block HTML error swaps for 4xx/5xx, htmx:sendError
for network errors, and htmx:confirm interception for custom modal.

Closes OP#949
Refs OP#948

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add FlashToast() using URL-encoded cookies for toast persistence across
redirects. Add success toasts to ~25 handlers. Replace console.error in
edit-mode.js with toast dispatches. Change StatusNoContent to StatusOK
for HX-Redirect paths.

Closes OP#950
Refs OP#948

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add toast_duration and toast_position columns to users table. Update
User model and all 6 SQL scan sites. Add Notifications section to
settings page with duration dropdown and position radio buttons.
Populate BaseData with user toast prefs in all baseData() methods.

Closes OP#951
Refs OP#948

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
test(toast): add unit tests for toast system
All checks were successful
CI / lint (pull_request) Successful in 1m27s
CI / security (pull_request) Successful in 1m47s
CI / build (pull_request) Successful in 1m51s
CI / test (pull_request) Successful in 2m5s
254d363db0
Tests for TriggerToast header format, FlashToast cookie properties
(name, format, MaxAge, HttpOnly=false), and special character
round-tripping through URL encoding.

Closes OP#952
Refs OP#948

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
refactor: rename invites to notifications
All checks were successful
CI / lint (pull_request) Successful in 1m37s
CI / security (pull_request) Successful in 1m53s
CI / build (pull_request) Successful in 1m57s
CI / test (pull_request) Successful in 2m10s
0162b51642
Rename all "invites" references to "notifications" throughout:
- DB migration: dashboard_invites table → notifications
- Models: DashboardInvite → Notification, InviteView → NotificationView
- Services: SendInvite → SendNotification, etc.
- Handlers: Invites → Notifications, RespondInvite → RespondNotification
- Routes: /invites → /notifications (with legacy redirects)
- Templates: updated sidebar label, icons, and component names
- Tests: updated route assertions

Closes OP#211

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reviewed-on: #15
Reviewed-by: Mike Bros <dev@bros.ninja>
feat(smtp): add email/SMTP configuration and sending
All checks were successful
CI / test (pull_request) Successful in 1m42s
CI / security (pull_request) Successful in 1m47s
CI / build (pull_request) Successful in 1m50s
CI / lint (pull_request) Successful in 2m33s
c53233f35d
Add admin SMTP settings page with server config (host, port, security,
auth), credentials, sender info, enable toggle, and test email feature.
Supports env var override (GASHY_SMTP_*) with read-only UI when
env-configured. Implements EmailService with TLS/STARTTLS/plain modes.

Refs OP#164

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
test(smtp): add unit tests for SMTP config, env override, and send
Some checks failed
CI / security (pull_request) Successful in 1m44s
CI / test (pull_request) Successful in 1m45s
CI / build (pull_request) Successful in 1m50s
CI / lint (pull_request) Failing after 2m2s
59b211ab25
Tests cover: env var override logic with table-driven cases, DB fallback
path verification, message building, auth selection, mock SMTP server
send, unreachable host graceful failure, handler env-block (403), and
empty email validation.

Closes OP#239

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat(notifications): extend notification system with multiple types
All checks were successful
CI / security (pull_request) Successful in 1m7s
CI / build (pull_request) Successful in 2m1s
CI / test (pull_request) Successful in 2m13s
CI / lint (pull_request) Successful in 2m47s
58e2249469
Add notification types (invite, dashboard_shared, dashboard_updated,
system) with type-specific icons/colors, read/unread tracking, and
generic notification creation. Update notifications page with
type-aware rendering, unread indicators, and status badges.

New service methods: CreateNotification, ListNotifications,
UnreadNotificationCount, MarkNotificationRead, MarkAllNotificationsRead.

Closes OP#824

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat(notifications): add bell icon with unread badge in navbar
All checks were successful
CI / security (pull_request) Successful in 2m3s
CI / build (pull_request) Successful in 2m11s
CI / test (pull_request) Successful in 2m24s
CI / lint (pull_request) Successful in 2m54s
74ae2940b5
Show notification bell between edit toggle and user dropdown. Red badge
displays unread count, hidden when 0. Links to notifications settings
page. Count queried via UnreadNotificationCount service method.

Closes OP#825

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat(notifications): add subscription preferences per notification type
All checks were successful
CI / lint (pull_request) Successful in 1m30s
CI / security (pull_request) Successful in 1m50s
CI / build (pull_request) Successful in 1m53s
CI / test (pull_request) Successful in 2m7s
993a267222
Add notification_preferences table and UI for users to control email
notifications per type (invite, shared, updated, system). Email toggles
are only shown when SMTP is configured by the admin.

Closes OP#166

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat(notifications): add email notification for dashboard invites
All checks were successful
CI / security (pull_request) Successful in 1m15s
CI / build (pull_request) Successful in 2m3s
CI / test (pull_request) Successful in 2m20s
CI / lint (pull_request) Successful in 2m54s
5e2fd11c0a
Wire up optional email sending when a dashboard is shared. Checks SMTP
availability and user notification preferences before sending. Email
includes accept link and unsubscribe footer.

The NotificationEmailSender interface is nil-safe — email is inactive
until the SMTP service is wired in after branch merge.

Closes OP#165

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
test(notifications): add unit tests for notification refactor
All checks were successful
CI / test (pull_request) Successful in 1m34s
CI / security (pull_request) Successful in 1m50s
CI / build (pull_request) Successful in 1m55s
CI / lint (pull_request) Successful in 2m45s
2fc142b516
Test notification type constants, icon/color methods, handler auth
guards, legacy route redirects, invite email sending (nil-safe, not
configured, no email), email HTML content, and preference model.

Closes OP#826

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
# Conflicts:
#	internal/handlers/admin.go
#	internal/handlers/settings.go
# Conflicts:
#	internal/handlers/settings.go
#	internal/handlers/user_dashboards.go
# Conflicts:
#	internal/handlers/admin.go
#	internal/handlers/impersonate.go
#	internal/models/models.go
#	internal/services/dashboard.go
# Conflicts:
#	components/partials/header.templ
#	internal/handlers/render.go
# Conflicts:
#	internal/handlers/settings.go
# Conflicts:
#	cmd/gashy/main.go
#	internal/handlers/user_dashboards.go
Merge remote-tracking branch 'origin/feature/826-notification-tests' into release/v0.3.1
Some checks failed
CI / security (pull_request) Successful in 1m46s
CI / build (pull_request) Successful in 1m54s
CI / lint (pull_request) Failing after 2m8s
CI / test (pull_request) Successful in 2m32s
f2f0ee75a6
fix(release): resolve lint error and confirm modal popup bug
All checks were successful
CI / lint (pull_request) Successful in 1m20s
CI / security (pull_request) Successful in 2m4s
CI / build (pull_request) Successful in 2m8s
CI / test (pull_request) Successful in 2m27s
05f1668a45
- Replace fmt.Sscanf with strconv.Atoi to satisfy errcheck linter
- Only intercept htmx:confirm when hx-confirm attribute is set
  (prevents empty modal popup on every htmx request)

Refs OP#827

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fix(migrations): renumber duplicate migration versions
All checks were successful
CI / security (pull_request) Successful in 47s
CI / build (pull_request) Successful in 2m11s
CI / test (pull_request) Successful in 2m37s
CI / lint (pull_request) Successful in 3m7s
6b66ae3618
Goose panicked on duplicate version 10 and 11 files from parallel
feature branches. Renumber to sequential 00010-00015:
  10: gravatar_enabled (already applied)
  11: toast_preferences (already applied)
  12: rename_invites_to_notifications
  13: smtp_settings
  14: notification_types
  15: notification_preferences

Refs OP#827

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fix(ui): eliminate Alpine.js FOUC and move editor to sticky toolbar
Some checks failed
CI / test (pull_request) Failing after 1m22s
CI / security (pull_request) Successful in 1m52s
CI / build (pull_request) Successful in 1m55s
CI / lint (pull_request) Has been cancelled
f6f9f074d6
- Add [x-cloak] { display: none !important } CSS rule to base.templ
- Add x-cloak to all dropdowns, context menu, and edit-mode elements
- Move pencil edit toggle from header to dashboard action bar
- Toolbar becomes sticky with frosted glass effect when edit mode active
- Edit button now shows label ("Edit" / "Done") alongside icon

Closes OP#967 Closes OP#968

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
test(header): update pencil toggle test for toolbar move
All checks were successful
CI / lint (pull_request) Successful in 1m37s
CI / security (pull_request) Successful in 1m43s
CI / build (pull_request) Successful in 1m48s
CI / test (pull_request) Successful in 2m0s
02462ee4b0
The pencil edit toggle was moved from the header to the dashboard
toolbar (OP#968). Update test to verify the header no longer renders
the pencil button.

Refs OP#827

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Mike Bros deleted branch release/v0.3.1 2026-02-17 22:35:33 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
mike/gashy!25
No description provided.