From 6ad7d559b8ec15048a087620a81c29f69a07bc23 Mon Sep 17 00:00:00 2001 From: Jean Date: Wed, 19 Jul 2023 13:01:21 -0400 Subject: [PATCH] FEATURE: sort by likes given and add groups exclusion (#37) * FEATURE: sort by likes given and add groups exclusion --------- Co-authored-by: Penar Musaraj Co-authored-by: Jarek Radosz --- README.md | 29 ++++--- .../discourse/components/top-contributors.js | 20 +++-- .../templates/components/top-contributors.hbs | 13 ++- test/acceptance/top-contributors-test.js | 83 +++++++++++++++++++ 4 files changed, 122 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 91717ff..f407564 100644 --- a/README.md +++ b/README.md @@ -25,16 +25,19 @@ You can also use other Ember components as blocks, you just need to use the corr You can control some features for the provided blocks via parameters. -| name | description | default | value | available for | -| --------------------------- | ------------------------------------- | ------- | ------------------------------------------------ | -------------------------------- | -| count | limits number of results | varies | number | all except custom-html | -| excerptLimit | limits length of each reply excerpt | 150 | number | recent-replies | -| id | category id | | category id (category-list uses comma-separated) | category-topics, category-list | -| content | contents to display | | html | custom-html | -| scopeToCategory | only shows in category X | | category id | popular-tags | -| excludedTags | list of excluded tags | | tagnames | popular-tags | -| displayInSpecificCategories | list of categories to show the widget | all | comma-separated numbers | popular-tags | -| id | leaderboard id | | number | minimal-gamification-leaderboard | -| tag | which tag to display | | tag id | tag-topics | -| period | time period of top topics | weekly | all, yearly, quarterly, monthly, weekly, daily | top-topics | -| title | title of the block | varies | string | tag-topics, category-list | +| name | description | default | value | available for | +|-----------------------------|---------------------------------------|----------------| ------------------------------------------------ |----------------------------------| +| count | limits number of results | varies | number | all except custom-html | +| excerptLimit | limits length of each reply excerpt | 150 | number | recent-replies | +| id | category id | | category id (category-list uses comma-separated) | category-topics, category-list | +| content | contents to display | | html | custom-html | +| scopeToCategory | only shows in category X | | category id | popular-tags | +| excludedTags | list of excluded tags | | tagnames | popular-tags | +| displayInSpecificCategories | list of categories to show the widget | all | comma-separated numbers | popular-tags | +| id | leaderboard id | | number | minimal-gamification-leaderboard | +| tag | which tag to display | | tag id | tag-topics | +| period | time period of top topics | weekly | all, yearly, quarterly, monthly, weekly, daily | top-topics | +| title | title of the block | varies | string | tag-topics, category-list | +| excludedGroupNames | Excludes specified groups | | Group names | top-contributors | +| order | Orders the contributors | likes_received | String (likes_received or likes_given) | top-contributors | +| period | Time period for top contributors | yearly | all, yearly, quarterly, monthly, weekly, daily | top-contributors | \ No newline at end of file diff --git a/javascripts/discourse/components/top-contributors.js b/javascripts/discourse/components/top-contributors.js index 2dcd2f9..443927c 100644 --- a/javascripts/discourse/components/top-contributors.js +++ b/javascripts/discourse/components/top-contributors.js @@ -4,17 +4,25 @@ import { tracked } from "@glimmer/tracking"; export default class TopContributors extends Component { @tracked topContributors = null; + order = this.args.params?.order || "likes_received"; + period = this.args.params?.period || "yearly"; + count = this.args.params?.count || 5; constructor() { super(...arguments); - const count = this.args?.params?.count || 5; + ajax(this.requestURL).then((data) => { + this.topContributors = data.directory_items?.slice(0, this.count); + }); + } + + get requestURL() { + const excludedGroupNames = this.args.params?.excludedGroupNames || ""; + return `/directory_items.json?period=${this.period}&order=${this.order}&exclude_groups=${excludedGroupNames}&limit=${this.count}`; + } - ajax(`/directory_items.json?period=yearly&order=likes_received`).then( - (data) => { - this.topContributors = data.directory_items.slice(0, count); - } - ); + get viewAllUrl() { + return `/u?order=${this.order}&period=${this.period}`; } willDestroy() { diff --git a/javascripts/discourse/templates/components/top-contributors.hbs b/javascripts/discourse/templates/components/top-contributors.hbs index f7c6ebc..adc1058 100644 --- a/javascripts/discourse/templates/components/top-contributors.hbs +++ b/javascripts/discourse/templates/components/top-contributors.hbs @@ -12,9 +12,14 @@ {{avatar item.user imageSize="small"}} {{html-safe item.user.username}} - - {{d-icon "heart"}} - {{item.likes_received}} + + {{#if (eq this.order "likes_received")}} + {{d-icon "heart"}} + {{item.likes_received}} + {{else}} + {{d-icon "heart"}} + {{item.likes_given}} + {{/if}} {{/each}} @@ -22,7 +27,7 @@ {{theme-i18n "top_contributors.view_all"}} \ No newline at end of file diff --git a/test/acceptance/top-contributors-test.js b/test/acceptance/top-contributors-test.js index 72f6470..6333796 100644 --- a/test/acceptance/top-contributors-test.js +++ b/test/acceptance/top-contributors-test.js @@ -74,6 +74,13 @@ acceptance("Right Sidebar - Top Contributors - Custom count", function (needs) { test("Viewing latest", async function (assert) { await visit("/"); + assert + .dom(".top-contributors--user-likes") + .doesNotHaveClass("order--likes_given"); + assert + .dom(".top-contributors--user-likes") + .hasClass("order--likes_received"); + assert.ok(visible(".tc-right-sidebar"), "sidebar element is present"); assert.ok( visible(".top-contributors--container"), @@ -87,3 +94,79 @@ acceptance("Right Sidebar - Top Contributors - Custom count", function (needs) { ); }); }); + +acceptance( + "Right Sidebar - Top Contributors - Custom order, group exclusion and period", + function (needs) { + const blocksJSON = [ + { + name: "top-contributors", + params: [ + { + name: "count", + value: "3", + }, + { + name: "order", + value: "likes_given", + }, + { + name: "period", + value: "weekly", + }, + { + name: "excludedGroupNames", + value: "Team|contributors", + }, + ], + }, + ]; + + needs.hooks.beforeEach(() => { + settings.blocks = JSON.stringify(blocksJSON); + }); + + needs.hooks.afterEach(() => { + settings.blocks = "[]"; + }); + + needs.pretender((server, helper) => { + server.get("/directory_items.json", (request) => { + if ( + request.queryParams.period === "weekly" && + request.queryParams.order === "likes_given" && + request.queryParams.exclude_groups === "Team|contributors" && + request.queryParams.limit === "3" + ) { + return helper.response(DirectoryFixtures["directory_items"]); + } + + return helper.response(400, {}, { error: "Bad Request" }); + }); + }); + + test("Viewing latest", async function (assert) { + await visit("/"); + + assert + .dom(".top-contributors--user-likes") + .hasClass("order--likes_given"); + assert + .dom(".top-contributors--user-likes") + .doesNotHaveClass("order--likes_received"); + + assert.dom(".tc-right-sidebar").isVisible("sidebar element is present"); + assert + .dom(".top-contributors--container") + .isVisible("top contributors element is present"); + + assert + .dom(".top-contributors--user") + .exists({ count: 3 }, "custom limit is respected"); + + assert + .dom(".top-contributors--view-all") + .hasAttribute("href", "/u?order=likes_given&period=weekly"); + }); + } +);