Skip to content

Add pledge participants admin views#629

Open
Bhavatu wants to merge 3 commits into
feat/sign_in_sign_up_mutationsfrom
feature/pledge_participants_admin_ui
Open

Add pledge participants admin views#629
Bhavatu wants to merge 3 commits into
feat/sign_in_sign_up_mutationsfrom
feature/pledge_participants_admin_ui

Conversation

@Bhavatu

@Bhavatu Bhavatu commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Description

Two surfaces for plan admins on plans with community engagement enabled:

  • A global Participants list under Pledges -> Participants (the Pledges menu becomes a submenu with Pledges and Participants children). Columns: email, commitment count, marketing opt-in. All sortable. Header buttons: Copy opted-in emails (clipboard) and Export opted-in emails as CSV.
  • A Participants tab on the pledge edit view scoped to that pledge. Same email + opt-in tick columns; same Copy/Export buttons.

Both surfaces share _get_participants_queryset (plan-scoped, excludes anonymous PublicUsers via email IS NULL, annotates commitment_count) and _opted_in_emails (filters to marketing_consented_at IS NOT NULL, sorted). The CSV endpoints under /admin/pledge-participants/ are gated to the active plan and reject pledges outside it.

The ParticipantsViewSet subclasses SnippetViewSet but overrides get_urlpatterns to expose only list/list_results (add/edit/delete view classes can't simply be nulled because SnippetViewSet hard-codes those routes). Permission policy is dedicated, separate from PledgePermissionPolicy, because the participants UI is read-only.

The copy-to-clipboard JS is plain JS loaded via insert_global_admin_js; the button carries the opted-in email list in a data attribute so the copy is a one-click no-roundtrip operation.

Screenshots/Videos (if applicable)

Add screenshots or videos demonstrating the changes if applicable.

Related issue

https://app.asana.com/1/1201243246741462/project/1206017643443542/task/1215606704588443
https://app.asana.com/1/1201243246741462/project/1206017643443542/task/1215606704588431

Requirements, dependencies and related PRs

Base: #626

Additional Notes

Any additional information that reviewers should know about this PR.


✅ Pre-Merge Checklist

Type of Change

  • Set the PR's label to match the nature of this change

Testing

  • Built Unit tests (unit tests added/updated)
  • Built E2E tests (if applicable. E2E tests added/updated)
  • Authorization is tested (permissions and access controls verified)
  • Manually tested locally (functionality verified)
    Manual testing instructions
    If feature requires manual testing by reviewer, you can provide instructions here.

Internationalization & Accessibility

  • New strings are translatable (all user-facing text uses i18n)
  • Accessibility standards met (WCAG compliance, screen reader support)

Integrations (if applicable)

If there are model changes to models which use any of the features below, verify the new models work together with the features.
For example, when adding a new model, verify the new model instances are copied when copying a plan.

  • Moderation integration implemented
  • Reporting integration implemented
  • Copy plan feature integration implemented
  • Umbrella plan structure integration implemented

Dependencies

  • Dependencies are merged (if applicable. If the change depends on other PRs e.g. kausal_common)

@Bhavatu Bhavatu added the New feature New feature (non-breaking change which adds functionality) label Jun 26, 2026
@kausal-code-coverage

kausal-code-coverage Bot commented Jun 26, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.77249% with 25 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
actions/pledge_participants_admin.py 88.88% 10 Missing and 7 partials ⚠️
actions/wagtail_hooks.py 80.64% 3 Missing and 3 partials ⚠️
actions/pledge_admin.py 60.00% 2 Missing ⚠️

Impacted file tree graph

@@                        Coverage Diff                         @@
##           feat/sign_in_sign_up_mutations     #629      +/-   ##
==================================================================
+ Coverage                           63.45%   63.55%   +0.09%     
==================================================================
  Files                                 389      390       +1     
  Lines                               41972    42157     +185     
  Branches                             5413     5432      +19     
==================================================================
+ Hits                                26634    26791     +157     
- Misses                              13648    13669      +21     
- Partials                             1690     1697       +7     
Flag Coverage Δ
e2e-tests 8.46% <11.11%> (-0.01%) ⬇️
unittests 60.94% <86.77%> (+0.12%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
actions/pledge_admin.py 64.63% <60.00%> (-2.99%) ⬇️
actions/wagtail_hooks.py 85.55% <80.64%> (-2.78%) ⬇️
actions/pledge_participants_admin.py 88.88% <88.88%> (ø)

... and 1 file with indirect coverage changes

Impacted file tree graph

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 285d5f42c9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread actions/pledge_participants_admin.py Outdated
@Bhavatu
Bhavatu force-pushed the feature/pledge_participants_admin_ui branch from 285d5f4 to 809b0bd Compare June 26, 2026 11:42

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 809b0bdee0

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread actions/pledge_participants_admin.py
@Bhavatu
Bhavatu force-pushed the feature/pledge_participants_admin_ui branch from 809b0bd to 4bd7558 Compare June 26, 2026 11:59

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4bd7558983

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread actions/pledge_participants_admin.py
@Bhavatu
Bhavatu force-pushed the feature/pledge_participants_admin_ui branch from 4bd7558 to 7700365 Compare June 26, 2026 13:11

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7700365e37

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread actions/pledge_participants_admin.py Outdated
@Bhavatu
Bhavatu force-pushed the feature/pledge_participants_admin_ui branch from 7700365 to ad15192 Compare June 26, 2026 15:17
@Bhavatu
Bhavatu force-pushed the feat/sign_in_sign_up_mutations branch 10 times, most recently from 36e1496 to 3b98194 Compare July 1, 2026 13:26
@Bhavatu
Bhavatu force-pushed the feature/pledge_participants_admin_ui branch 3 times, most recently from b560534 to 7abae22 Compare July 2, 2026 09:59

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7abae2279d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread actions/pledge_participants_admin.py
Bhavatu added 2 commits July 2, 2026 16:24
Two surfaces for plan admins on plans with community engagement enabled:

- A global Participants list under Pledges -> Participants (the Pledges
  menu becomes a submenu with Pledges and Participants children).
  Columns: email, commitment count, marketing opt-in. All sortable.
  Header buttons: Copy opted-in emails (clipboard) and Export opted-in
  emails as CSV.
- A Participants tab on the pledge edit view scoped to that pledge.
  Same email + opt-in tick columns; same Copy/Export buttons.

Both surfaces share _get_participants_queryset (plan-scoped, excludes
anonymous PublicUsers via email IS NULL, annotates commitment_count) and
_opted_in_emails (filters to marketing_consented_at IS NOT NULL, sorted).
The CSV endpoints under /admin/pledge-participants/ are gated to the
active plan and reject pledges outside it.

The ParticipantsViewSet subclasses SnippetViewSet but overrides
get_urlpatterns to expose only list/list_results (add/edit/delete view
classes can't simply be nulled because SnippetViewSet hard-codes those
routes). Permission policy is dedicated, separate from PledgePermissionPolicy,
because the participants UI is read-only.

The copy-to-clipboard JS is plain JS loaded via insert_global_admin_js;
the button carries the opted-in email list in a data attribute so the
copy is a one-click no-roundtrip operation.
@Bhavatu
Bhavatu force-pushed the feature/pledge_participants_admin_ui branch from fc54195 to da060d2 Compare July 2, 2026 13:24

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: da060d2db9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread actions/pledge_admin.py
@Bhavatu
Bhavatu force-pushed the feature/pledge_participants_admin_ui branch from da060d2 to 57c6fb0 Compare July 2, 2026 14:08
@Bhavatu
Bhavatu force-pushed the feature/pledge_participants_admin_ui branch from 57c6fb0 to 06d0e77 Compare July 3, 2026 07:28
Comment on lines +204 to +211
# Wagtail's BooleanColumn reads bool() of the attribute. PublicUser.marketing_consented_at
# is a datetime-or-None; bool(datetime) is True, bool(None) is False, so the column
# already does the right thing as long as we expose `has_marketing_consent` as a property.
def _has_marketing_consent(self: PublicUser) -> bool:
return self.marketing_consented_at is not None


PublicUser.has_marketing_consent = property(_has_marketing_consent) # type: ignore[attr-defined]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may have been discussed before already, and I don't want to restart a discussion. But are there any benefits to using a datetime instead of a Boolean for the marketing consent? In general, one could always use a datetime instead of a Boolean. But it may be an unnecessary complication if there is no clear benefit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

New feature New feature (non-breaking change which adds functionality)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants