Page MenuHomePhabricator

Load the voting Vue app on wishes and focus areas
Closed, ResolvedPublic5 Estimated Story Points

Description

The wish and focus area view pages will have the HTML generated by the server. This would also include the voting button.

User story

As a wishlist participant, I want to be able to show my support to a wish so that the WMF knows which wish is important to me.

Enable supporting individual wishes. User should be able to support a wish with or without adding a comment and remove a support.

Acceptance criteria

  • Add any necessary config settings, including one to control whether voting is enabled
  • If enabled, add the voting button to the renderWish output
  • In the BeforePageDisplay hook, load the voting module (if voting is enabled and we're on a wish or focus area page)

Designs:

https://www.figma.com/design/JcTMFwbEJPpCKBiZ16Jkel/Future-of-the-Wishlist?node-id=3797-150914&t=H8DqOupKYrNx1LOk-1

Derived Requirement

Ensure that the voting Vue app is conditionally loaded on wish and focus area view pages. When voting is enabled via configuration, the page should display a voting button rendered by the Vue app, allowing users to support or remove support for a wish—with or without a comment. The voting module must be dynamically loaded using the BeforePageDisplay hook.

Test Steps

Test Case 1: Verify voting module is loaded and voting button is visible on wish page when voting is enabled

*Precondition: Voting feature flag is enabled via config ($wgCommunityRequestsWishVotingEnabled = true)*

  1. Log in to the beta wiki with a user account that has voting permissions.
  2. Navigate to a wish view page (e.g., Special:WishlistIntake/Community_Wishlist/Wishes/W1).
  3. ✅❓❌⬜ AC1: Verify that a voting button is visible inside the rendered wish view (as per Figma design).
  4. ✅❓❌⬜ AC2: Click the voting button and confirm that support is registered.
  5. ✅❓❌⬜ AC3: Optionally enter a comment and confirm that the comment is saved.
  6. ✅❓❌⬜ AC4: Click again to remove support and verify that the vote is withdrawn.
  7. ✅❓❌⬜ AC5: Reload the page and confirm that voting state persists as expected.

Test Case 2: Verify voting module is loaded and voting button is visible on focus area page when voting is enabled

  1. Navigate to a focus area view page (e.g., Community_Wishlist/Focus_areas/FA3).
  2. ✅❓❌⬜ AC6: Confirm that the Vue-based voting app is loaded.
  3. ✅❓❌⬜ AC7: Verify that a voting button is present and interactive.
  4. ✅❓❌⬜ AC8: Test supporting and removing support for the focus area.
  5. ✅❓❌⬜ AC9: Confirm UI updates immediately and is styled per Figma specs.

Test Case 3: Verify voting module is not loaded when voting is disabled

*Precondition: Voting is disabled via config ($wgCommunityRequestsWishVotingEnabled = false;, $wgCommunityRequestsFocusAreaVotingEnabled = false;)*

  1. Log in as any user in Local.
  2. Visit a wish or focus area view page.
  3. ✅❓❌⬜ AC10: AC10: Confirm that Vue voting app JavaScript is not loaded on the page.

QA Results - Commtech.toolforge/Local

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

I think the idea with {{#focus-area-votes}} was that there's no need to actually store the votes themselves in the database, but just the total count of support votes (which can go in the focus_areas table). The votes would still be stored on a /Votes subpage using {{support}} etc. but the /Vote_count page wouldn't be needed any more. So the parser function would be (as you say) a Vue app that basically does what the current one does with a button and dialog and appending the vote to the subpage — the difference would be that it'd use an API call to store the vote count rather than a wiki page. The parser function would also perhaps count and store the votes (when the focus area page is rendered, so making it possible to handle manual votes). Having the count and store functionality server-side means it wouldn't need to be duplicated client-side (and we can't only have it client side because then manual votes wouldn't be counted until someone else votes).

Regarding parser function vs tag, I'm not sure it matters which here as it doesn't take any params and is outputting a bare div to hang the Vue app on. With the others, we've gone with a parser function where it's about storing data (because we need to wrap translate tags around param values, and that doesn't work for parser function attributes), and a tag when it's about displaying data (i.e. can output full HTML).

Do you think there's a need to store all the individual votes in the DB? Do they get queried other than to count them? I guess it'd be nice to show people a list of all of their own votes.

Ahh, I see. Sorry. I was going off of the schema we already have, which is meant to support voting on wishes too, and also different types of votes – necessitating its own table. I understand if we're now trying to trim the fat and just do a MVP.

Also, the storage happening in the Vote template could get tricky with bulk updates, and in particular deletions (say from vandalism). Perhaps solvable by putting the preexisting vote results in the process cache and comparing against it as each {{#community-requests-vote}} (or what have you) is processed. Nonetheless I can foresee that being tricky! So yeah, storing the total votes somewhere sounds pretty good.

Do you think there's a need to store all the individual votes in the DB? Do they get queried other than to count them? I guess it'd be nice to show people a list of all of their own votes.

We have repeatedly wanted to reach out to voters of a wish/focus area, but it's not that hard to run some regex on the /Votes subpage and accomplish the same.


Alright, so we want to store only the total vote count. What if we made that a parser function, i.e. {{#focus-area-vote-count|<focus-area>}}? Then it gets cached, and we don't need to build an API. We'd only need the Vue app to trigger a purge, which it needs to do anyway to ensure we get the updated /Votes page.

The part I don't like is:

… on page load, trigger an api call to update the number of votes (by counting the templates on the subpage)

Reads should be idempotent and not change any data. But also, there could be a network hiccup, runtime JS error, or some other reason that our vote count doesn't update. I'm thinking it should be more foolproof than that.

Another idea is to add a hook to listen to changes to pages starting with i.e. $wgCommunityRequestsFocusAreaPagePrefix, and do the vote counting and storage then. That seems pretty straightforward.

Hmm yeah that does sound more straightforward. Is this an existing pattern? Like are there other extensions that (for example) do a title check on onpagesavecomplete?

Updated T388220 to use the hook rather than an api call ... @Samwilson does this seem ok to you?

Very good points. I like the idea of triggering on changes to the /Votes page — could we avoid the config var because we already know if a page is a focus area (based on the presence of {{#focus-area}}) and I guess the subpage name will need to be set to something static anyway? One of the ideas I like with what we've got so far is that we're not enforcing any particular subpage structures for any of this, which I think keeps it simpler.

i.e. when a Foo/Bar/Votes subpage is edited, we count the votes and update any focus area row with a page title that matches the parent page's. Which I think could perhaps be done with something along the lines of update community_requests_focus_areas set crfa_vote_count = 3 where crfa_page = ( select page_id from page where page_title = 'Foo/Bar' LIMIT 1 ) — so if the parent isn't already a focus area, nothing happens.

We already have {{#focus-area}} (T388207) which will be used in Template:Community_Wishlist/Focus_area (or one of its sub-templates). Do we need an additional parser function just to indicate where the Vue app should add the support button, or could that container div just be part of the {{#focus-area}} output?

It could all be done in the one parser function, but I was thinking that they'd both be called in the Template:Community_Wishlist/Focus_area/Full template, and that template would then handle all the other bits like description (not short description), created and updated times, list of wishes (T387962), owners and volunteers, and transcluding the list of votes from /Votes.

{{#focus-area}} will just save the three fields that are needed to be displayed elsewhere (title, short description, and status), and not output anything. The /Full template will handle the actual display of everything (as it already does, so not much change will be needed).

Or does that sound like it splits things up too much between on-wiki and in the extension?

If they are meant to be in the same template, maybe we can just place {{#focus-area}} where we want the empty <div> to go? We'd want both wrapped in a <noinclude>, anyway, so it seems easier for both template editors and for us as engineers to have one fewer parser function.

Ok so after talking this through last night we think we're going to have 2 templates - {{focus-area-header}} and {{focus-area-footer}}, and this one will be used in the footer

This parser function doesn't have to do the wish table and transclusion, those are pretty much just <community-requests focus-area="Lorem ipsum" /> and {{:{{PAGENAME}}/Votes}} and can go in the {{focus-area-footer}}.

So perhaps this should be called {{#focus-area-vote-button}} or just {{#support-button}} or something?

Ok updated - it's kind of a tiny task now really

Cparle renamed this task from New {{#focus-area-votes}} parser function to New {{#focus-area-support}} parser function.Apr 9 2025, 9:54 AM
HMonroy renamed this task from New {{#focus-area-support}} parser function to New <voting-button> parser tag.May 29 2025, 1:00 AM
HMonroy updated the task description. (Show Details)

Change #1151820 had a related patch set uploaded (by HMonroy; author: HMonroy):

[mediawiki/extensions/CommunityRequests@master] WIP: new voting-button parser tag

https://gerrit.wikimedia.org/r/1151820

Change #1161615 had a related patch set uploaded (by MusikAnimal; author: MusikAnimal):

[mediawiki/extensions/CommunityRequests@master] WishHookHandler: add voting button and transclude /Votes

https://gerrit.wikimedia.org/r/1161615

MusikAnimal renamed this task from New <voting-button> parser tag to Load the voting Vue app on wishes and focus areas.Jun 19 2025, 8:18 PM
MusikAnimal updated the task description. (Show Details)

Change #1163497 had a related patch set uploaded (by HMonroy; author: HMonroy):

[mediawiki/extensions/CommunityRequests@master] Add frontend functionaly to voting button

https://gerrit.wikimedia.org/r/1163497

Change #1151820 abandoned by HMonroy:

[mediawiki/extensions/CommunityRequests@master] WIP: new voting-button parser tag

Reason:

replacing it with a cleaner patch https://gerrit.wikimedia.org/r/c/mediawiki/extensions/CommunityRequests/+/1163497

https://gerrit.wikimedia.org/r/1151820

Change #1163497 merged by jenkins-bot:

[mediawiki/extensions/CommunityRequests@master] Add frontend functionaly to voting button

https://gerrit.wikimedia.org/r/1163497

I don't think there's a way to QA this yet.

Change #1165637 had a related patch set uploaded (by MusikAnimal; author: MusikAnimal):

[mediawiki/extensions/CommunityRequests@master] Add SpecialEditFocusArea and focus area detail page; add voting sections

https://gerrit.wikimedia.org/r/1165637

Change #1161615 abandoned by MusikAnimal:

[mediawiki/extensions/CommunityRequests@master] WishHookHandler: add voting button and transclude /Votes

Reason:

superseded by I15ea8f39853a43af144b48605d69b0676922e386

https://gerrit.wikimedia.org/r/1161615

Change #1167294 had a related patch set uploaded (by MusikAnimal; author: MusikAnimal):

[mediawiki/extensions/CommunityRequests@master] CommunityRequestsHooks: load voting RL module when applicable

https://gerrit.wikimedia.org/r/1167294

Change #1165637 merged by jenkins-bot:

[mediawiki/extensions/CommunityRequests@master] Add SpecialEditFocusArea and focus area detail page; add voting sections

https://gerrit.wikimedia.org/r/1165637

Change #1167294 merged by jenkins-bot:

[mediawiki/extensions/CommunityRequests@master] CommunityRequestsHooks: load voting RL module when applicable

https://gerrit.wikimedia.org/r/1167294

Change #1167937 had a related patch set uploaded (by HMonroy; author: HMonroy):

[mediawiki/extensions/CommunityRequests@master] Set up `wish` or `focus-area` text according to page

https://gerrit.wikimedia.org/r/1167937

Change #1167937 merged by jenkins-bot:

[mediawiki/extensions/CommunityRequests@master] Set up `wish` or `focus-area` text according to page

https://gerrit.wikimedia.org/r/1167937

MusikAnimal changed the task status from Open to In Progress.Aug 4 2025, 7:10 PM

@HMonroy Please review results below, thanks!

Test Result - Local/Commtech.toolforge

Status: ✅ PASS / ❓Need More Info / ❌ FAIL
Environment: Local/Commtech.toolforge
OS: macOS Sequoia 15.5
Browser: Chrome 138
Device: MBA
Emulated Device: NA

Test Artifact(s):

Test Steps

Test Case 1: Verify voting module is loaded and voting button is visible on wish page when voting is enabled

*Precondition: Voting feature flag is enabled via config ($wgCommunityRequestsWishVotingEnabled = true)*

  1. Log in to the beta wiki with a user account that has voting permissions.
  2. Navigate to a wish view page (e.g., Special:WishlistIntake/Community_Wishlist/Wishes/W1).
  3. AC1: Verify that a voting button is visible inside the rendered wish view (as per Figma design).

  1. AC2: Click the voting button and confirm that support is registered.

See AC1

  1. AC3: Optionally enter a comment and confirm that the comment is saved.

Once supported, are those words the correct one since it's different then Figma?

See AC1

  1. AC4: Click again to remove support and verify that the vote is withdrawn.

Vote will be removed in T399496: Supporting wishes and focus areas

  1. AC5: Reload the page and confirm that voting state persists as expected.

Format is different compared to figma

FigmaCommtech.toolforge
2025-08-04_21-46-42.png (139×534 px, 22 KB)
2025-08-04_16-11-52.png (269×869 px, 33 KB)

Test Case 2: Verify voting module is loaded and voting button is visible on focus area page when voting is enabled

  1. Navigate to a focus area view page (e.g., Community_Wishlist/Focus_areas/FA1).
  2. AC6: Confirm that the Vue-based voting app is loaded.

  1. AC7: Verify that a voting button is present and interactive.

    See AC6
  1. AC8: Test supporting and removing support for the focus area.

Supporting for focus area goes through but no removing until T399496: Supporting wishes and focus areas is completed.
See AC6

  1. AC9: Confirm UI updates immediately and is styled per Figma specs.

Just like wish, wording does not match with Figma when wish is supported.

See AC7
Format is different compared to figma

FigmaCommtech.toolforge
2025-08-04_21-46-42.png (139×534 px, 22 KB)
2025-08-04_21-45-59.png (1×1 px, 242 KB)

Test Case 3: Verify voting module is not loaded when voting is disabled

*Precondition: Voting is disabled via config ($wgCommunityRequestsWishVotingEnabled = false;, $wgCommunityRequestsFocusAreaVotingEnabled = false;)*

  1. Log in as any user on Local.
  2. Visit a wish or focus area view page.
  3. AC10: Confirm that Vue voting app JavaScript is not loaded on the page.
WishFocusMobile- FocusMobile- WishRTL- FocusRTL- Wish
2025-08-04_12-43-23.png (1×1 px, 560 KB)
2025-08-04_12-50-37.png (1×1 px, 581 KB)
2025-08-04_13-18-49.png (1×1 px, 191 KB)
2025-08-04_13-29-34.png (1×1 px, 454 KB)
2025-08-04_13-22-34.png (1×1 px, 531 KB)
2025-08-04_13-27-07.png (1×1 px, 509 KB)
GMikesell-WMF updated the task description. (Show Details)
GMikesell-WMF updated the task description. (Show Details)
GMikesell-WMF moved this task from QA to In Development on the Community-Tech (Sea Lion Squad) board.
  1. AC3: Optionally enter a comment and confirm that the comment is saved.

Once supported, are those words the correct one since it's different then Figma?

See AC1

  1. AC4: Click again to remove support and verify that the vote is withdrawn.

Vote will be removed in T399496: Supporting wishes and focus areas

  1. AC5: Reload the page and confirm that voting state persists as expected.

The figma shows the "remove support" button. We just added a greyed out button that confirms that a support has been submitted since we are going to hold on that functionality for now.

  1. AC8: Test supporting and removing support for the focus area.

We are not implementing removing support for a focus area/wish for now.

Supporting for focus area goes through but no removing until T399496: Supporting wishes and focus areas is completed.
See AC6

  1. AC9: Confirm UI updates immediately and is styled per Figma specs.

Test Case 3: Verify voting module is not loaded when voting is disabled

*Precondition: Voting is disabled via config ($wgCommunityRequestsWishVotingEnabled = false;, $wgCommunityRequestsFocusAreaVotingEnabled = false;)*

  1. Log in as any user on Local.
  2. Visit a wish or focus area view page.
  3. AC10: Confirm that Vue voting app JavaScript is not loaded on the page.

I believe we still want to load the voting section, just not the ability to vote (voting button), which looks correct in the screenshots.

Please let me know if you have any questions :) Thanks!

Change #1175969 had a related patch set uploaded (by HMonroy; author: HMonroy):

[mediawiki/extensions/CommunityRequests@master] Allow voting with no comment submitted

https://gerrit.wikimedia.org/r/1175969

Change #1175969 merged by jenkins-bot:

[mediawiki/extensions/CommunityRequests@master] Allow voting with no comment submitted

https://gerrit.wikimedia.org/r/1175969

@HMonroy Please review below, thanks!

UPDATE: After Discussions, design-related issues will be ignored for now. Created bug T401726: Submit Wish (or Focus Area) appears briefly after Refresh when already voted . I will mark this as resolved now, thanks!

✅ AC3: Optionally enter a comment and confirm that the comment is saved.

Once the wish is submitted, the words do not match with Figma

FigmaCommtech.toolforge
2025-08-04_21-46-42.png (139×534 px, 22 KB)
2025-08-07_11-04-49.png (314×806 px, 40 KB)

⬜  AC5: Reload the page and confirm that voting state persists as expected.

When you refresh the page, "Support wish" button becomes available for a brief period, as seen in the gif

2025-08-07_11-05-34.mp4.gif (1×1 px, 615 KB)

UPDATE: Bug created T401726: Submit Wish (or Focus Area) appears briefly after Refresh when already voted

⬜  AC8: Test supporting and removing support for the focus area.

Ok to ignore per T388219#11063089

✅ AC9: Confirm UI updates immediately and is styled per Figma specs.

User support format does not match with Figma

FigmaCommtech.toolforge
2025-08-04_21-46-42.png (139×534 px, 22 KB)
2025-08-07_11-41-25.png (285×733 px, 33 KB)

4✅ AC10: Confirm that Vue voting app JavaScript is not loaded on the page.

For LTR, "Support Wish" is greyed out. For RTL, everything s removed. Also look at the "x" in the green message box on how it's in the middle

WishMobile- WishFocusMobile- FocusRTL- FocusRTL- Wish
2025-08-07_12-46-17.png (1×882 px, 209 KB)
2025-08-07_12-47-34.png (1×878 px, 211 KB)
2025-08-07_12-51-16.png (1×839 px, 224 KB)
2025-08-07_12-51-39.png (1×912 px, 220 KB)
2025-08-07_14-11-08.png (1×1 px, 295 KB)
2025-08-07_14-07-38.png (1×1 px, 276 KB)
GMikesell-WMF updated Other Assignee, removed: GMikesell-WMF.
GMikesell-WMF updated the task description. (Show Details)