Skip to content

feat: add dashboard pagination, bulk update, and quick assign - #6

Open
itheCreator1 wants to merge 2 commits into
mainfrom
feature/dashboard-pagination-bulk-actions
Open

feat: add dashboard pagination, bulk update, and quick assign#6
itheCreator1 wants to merge 2 commits into
mainfrom
feature/dashboard-pagination-bulk-actions

Conversation

@itheCreator1

Copy link
Copy Markdown
Owner

Summary

  • Salvages feature/dashboard-enhancements (stale since Jan 2026): admin dashboard gains pagination, ticket-age badges, a bulk status/priority/assignment update form, and per-row quick-assign
  • Rebased onto current main, resolving conflicts in app.js, routes/admin.js, validators/ticketValidators.js, and a full rewrite of views/admin/dashboard.ejs (the branch's markup was Bootstrap 5 + hardcoded English + inline <script>; rebuilt against main's current Tailwind design system, i18n (t() keys added to both locales/en/tickets.json and locales/el/tickets.json), existing badge partials, and an external CSP-safe JS file rather than inline handlers — main's Helmet CSP has no 'unsafe-inline' for scripts)
  • Renumbered a colliding migration (the branch's own 010_add_dashboard_indexes.sql collided with an unrelated migration already at that number on main) to 029_add_dashboard_indexes.sql

Bugs found and fixed while rebasing

  • Bulk-update silently unassigned every selected ticket on any update. Both the "no change" and "-- Unassign --" assignment options used value=""; the route treated any non-undefined assigned_to as an explicit unassign. Introduced a distinct __unassign__ sentinel so "no change" ("") and "unassign" are no longer the same value.
  • Bulk-update and quick-assign validators rejected their own forms' default statevalidateBulkUpdate/validateQuickAssign used bare .optional(), which only skips undefined, not the empty string every unchanged <select> sends. Switched to .optional({ checkFalsy: true }).
  • Bulk-update and quick-assign routes were missing adminMutationLimiter and audit-context threading (actorUsername/actorRole/sessionHash), unlike every other admin mutation route — added both.
  • Reworked dateHelpers.calculateTicketAge to return { unit, count, color } (a translation key + semantic badge color) instead of hardcoded English text and Bootstrap classes, since main uses Tailwind + i18n. Added unit tests since the contract changed.

Test plan

  • docker-compose exec web npm test — 1009/1009 passing (was 1004; +5 new dateHelpers tests)
  • docker-compose exec web npm run lint / npx prettier --check — clean on all touched files
  • Manually smoke-tested against a live container with seeded data: logged in, loaded /admin/dashboard (renders correctly, all badges/i18n/forms present), and exercised quick-assign and bulk-update end-to-end via curl — confirmed assignment sentinel fix (priority-only bulk update no longer wipes assignment), unassign works both ways, and audit log rows are created correctly for both endpoints
  • CI green

🤖 Generated with Claude Code

https://claude.ai/code/session_011tWtJbqWmefyKJUjXcEmfo

itheCreator1 and others added 2 commits September 3, 2026 16:26
…uick assign

Added comprehensive dashboard improvements for better ticket management:

Features:
- Pagination (50 tickets per page) for better performance
- Status and priority counts in filter dropdowns
- Last comment preview on each ticket row
- Ticket age calculation and display
- Bulk update functionality (status, priority, assignment)
- Quick assign dropdown for individual tickets
- Database indexes for dashboard query optimization

Technical Changes:
- New Ticket model methods: findAllPaginated(), getCountsByStatus(), getCountsByPriority(), bulkUpdate()
- New Comment model method: getLastCommentsByTicketIds()
- New utility: dateHelpers.js for ticket age calculation
- Enhanced ticketService with getDashboardData() and bulkUpdateTickets()
- New validators: validateBulkUpdate, validateQuickAssign
- Migration 010: Added indexes on tickets (status, priority, created_at)
- Comprehensive audit logging for bulk operations

Performance:
- Parallel queries for dashboard data
- Optimized comment fetching with single query
- Database indexes for faster filtering and sorting
- Pagination reduces initial load time

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…ure with current conventions

Fixes bugs found while rebasing feature/dashboard-enhancements onto main:
- Bulk-update's "no change" and "unassign" assignment options both used
  value="" - any bulk update (even one only touching status/priority)
  silently unassigned every selected ticket. Unassign now uses a distinct
  __unassign__ sentinel.
- validateBulkUpdate/validateQuickAssign rejected the empty-string default
  form values for status/priority/assigned_to, so submitting the form
  without touching every field failed validation entirely.
- bulk-update and quick-assign routes were missing adminMutationLimiter and
  audit-context threading (actorUsername/actorRole/sessionHash), unlike
  every other admin mutation route.

Also reworked dateHelpers.calculateTicketAge to return a translation
unit + count + semantic color token instead of hardcoded English text and
Bootstrap classes, since main uses Tailwind + i18n, not Bootstrap. Added
unit tests for it (5 tests, 1004 -> 1009 passing) since its return contract
changed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011tWtJbqWmefyKJUjXcEmfo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant