Skip to content

Feature/direct user selection and refactor - #6

Open
antonio-rodriguez-tam wants to merge 5 commits into
mainfrom
feature/direct-user-selection-and-refactor
Open

Feature/direct user selection and refactor#6
antonio-rodriguez-tam wants to merge 5 commits into
mainfrom
feature/direct-user-selection-and-refactor

Conversation

@antonio-rodriguez-tam

@antonio-rodriguez-tam antonio-rodriguez-tam commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Add direct user selection with CSV bulk paste support

Description:
Summary

  • Add "Select Users" mode to compose: staff can hand-pick recipients via search autocomplete or bulk paste instead of using the filter cascade
  • Bulk paste accepts newlines, commas, semicolons, tabs, and spaces (CSV, spreadsheet, plain lists)
  • Batch DB queries for bulk resolve (2 queries instead of N)
  • Extract shared helpers (_parse_json, _normalize_filter_keys, _serialize_user) to eliminate cross-class static method calls and duplicate code
  • Fix undefined is_direct variable in ValidateView that caused a 500 error

Test plan

  • Switch to "Select Users" mode, search and add users via autocomplete
  • Bulk paste usernames/emails in various formats: one per line, comma-separated, semicolon-separated, space-separated, mixed
  • Verify found and not_found feedback is correct
  • Validate with selected users — confirm no 500 error
  • Preview recipients in direct mode
  • Send a notification in direct mode
  • Switch back to filter mode and verify it still works
  • Save and restore a draft in direct mode
  • Run unit tests: python -m unittest coldfront_notifications.tests.test_filters coldfront_notifications.tests.test_validators coldfront_notifications.tests.test_resolvers

Security Checklist

  • Input Validation: All user inputs are properly validated and sanitized to prevent injection attacks.
  • Authentication & Authorization: The PR does not introduce unauthorized access, public endpoints or privilege escalation risks.
  • Secrets Management: No hardcoded secrets, API keys, or sensitive data are present.
  • Data Protection: Sensitive data is encrypted both at rest and in transit where applicable.
  • Logging & Monitoring: New features include proper logging and monitoring where necessary, without logging sensitive information.
  • Security Headers: If applicable, relevant security headers (CSP, HSTS, X-Frame-Options) are correctly configured.
  • Error Handling: Errors do not expose sensitive system details.
  • Third-Party Services: Any new third-party integrations follow security best practices (e.g. authentication, encryption, logging).
  • Code Review: The PR has been reviewed for potential security flaws.

Additional Notes

Checklist

  • I have performed a self-review of my code
  • I have tested the changes locally
  • I have run security tests where applicable
  • This PR follows the coding and security guidelines of the project

…d of hardcoding "Storage Quota (TB)"

The attribute name can be "Storage Quota (TiB)" depending on the resource,
so we now dynamically build it from the resource's quantity_label property.
… undefined is_direct bug

Add "Select Users" mode to compose: staff can hand-pick recipients by
username/email search or bulk paste instead of using the filter cascade.
Includes RecipientResolver direct-mode support, UserSearchView,
UserBulkResolveView, compose_direct_select.js, and updated tests.

Refactor filters, models, views, and JS for improved readability and
reduced duplication. Fix undefined `is_direct` variable in ValidateView
that caused a 500 error in direct selection mode.
…iews

Bulk resolve now splits on commas, semicolons, tabs, and spaces in
addition to newlines, supporting CSV paste and spreadsheet copy. Batch
DB queries replace per-identifier lookups (N queries → 2).

Extract _parse_json, _normalize_filter_keys, and _serialize_user as
module-level helpers to eliminate cross-class static method calls and
duplicate code.
@antonio-rodriguez-tam
antonio-rodriguez-tam marked this pull request as ready for review July 21, 2026 18:18
…rch, and fix draft body race condition

- Sort PI-role rows first in recipient enumeration so deduped users
  receive their PI-context email by default
- Add per-row include/exclude checkboxes on all multi-email recipient
  rows with dedupe_selections dict for granular control
- Replace client-side recipient search with debounced server-side
  search across all pages
- Fix TinyMCE race condition where draft body appeared blank because
  setBodyContent was called before the editor finished initializing
…e-all at allocation scope

Recipients are now resolved through ProjectUser membership only — AllocationUser
is no longer used to determine who receives emails. Allocation filters identify
which projects have matching allocations, then all ProjectUsers on those projects
are included. This fixes both missing recipients (ProjectUsers who weren't
AllocationUsers) and wrong recipients (AllocationUsers who weren't ProjectUsers).

"Dedupe all" now keeps exactly one email per user regardless of scope by using
the legacy first-tuple-only path instead of per-project selections. Per-row
checkboxes still allow fine-grained control by transitioning individual users
to the selections path.

Also adds a loading spinner to the validation feedback bar while the request
is in flight.
@claire-peters claire-peters self-assigned this Aug 13, 2026
@claire-peters
claire-peters self-requested a review August 13, 2026 19:15
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.

2 participants