diff --git a/app/assets/javascripts/discourse/app/components/user-flag-percentage.gjs b/app/assets/javascripts/discourse/app/components/user-flag-percentage.gjs
new file mode 100644
index 00000000000..f362ff925e8
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/components/user-flag-percentage.gjs
@@ -0,0 +1,64 @@
+import Component from "@glimmer/component";
+import { cached } from "@glimmer/tracking";
+import { gte } from "truth-helpers";
+import icon from "discourse-common/helpers/d-icon";
+import { i18n } from "discourse-i18n";
+
+export default class UserFlagPercentage extends Component {
+ // We do a little logic to choose which icon to display and which text
+ @cached
+ get percentage() {
+ const { agreed, disagreed, ignored } = this.args;
+ const total = agreed + disagreed + ignored;
+ const result = { total };
+
+ if (total <= 0) {
+ return result;
+ }
+
+ const roundedAgreed = Math.round((agreed / total) * 100);
+ const roundedDisagreed = Math.round((disagreed / total) * 100);
+ const roundedIgnored = Math.round((ignored / total) * 100);
+
+ const highest = Math.max(agreed, disagreed, ignored);
+ if (highest === agreed) {
+ result.icon = "thumbs-up";
+ result.className = "agreed";
+ result.label = `${roundedAgreed}%`;
+ } else if (highest === disagreed) {
+ result.icon = "thumbs-down";
+ result.className = "disagreed";
+ result.label = `${roundedDisagreed}%`;
+ } else {
+ result.icon = "up-right-from-square";
+ result.className = "ignored";
+ result.label = `${roundedIgnored}%`;
+ }
+
+ result.title = i18n("review.user_percentage.summary", {
+ agreed: i18n("review.user_percentage.agreed", {
+ count: roundedAgreed,
+ }),
+ disagreed: i18n("review.user_percentage.disagreed", {
+ count: roundedDisagreed,
+ }),
+ ignored: i18n("review.user_percentage.ignored", {
+ count: roundedIgnored,
+ }),
+ count: total,
+ });
+
+ return result;
+ }
+
+
+ {{#if (gte this.percentage.total 3)}}
+
+ {{this.percentage.label}}
+ {{icon this.percentage.icon}}
+
+ {{/if}}
+
+}
diff --git a/app/assets/javascripts/discourse/app/components/user-flag-percentage.hbs b/app/assets/javascripts/discourse/app/components/user-flag-percentage.hbs
deleted file mode 100644
index dfb33468822..00000000000
--- a/app/assets/javascripts/discourse/app/components/user-flag-percentage.hbs
+++ /dev/null
@@ -1,8 +0,0 @@
-{{#if this.showPercentage}}
-
- {{this.percentage.label}}
- {{d-icon this.percentage.icon}}
-
-{{/if}}
\ No newline at end of file
diff --git a/app/assets/javascripts/discourse/app/components/user-flag-percentage.js b/app/assets/javascripts/discourse/app/components/user-flag-percentage.js
deleted file mode 100644
index 93f8c2ec3a0..00000000000
--- a/app/assets/javascripts/discourse/app/components/user-flag-percentage.js
+++ /dev/null
@@ -1,55 +0,0 @@
-import Component from "@ember/component";
-import { tagName } from "@ember-decorators/component";
-import discourseComputed from "discourse-common/utils/decorators";
-import { i18n } from "discourse-i18n";
-
-@tagName("")
-export default class UserFlagPercentage extends Component {
- @discourseComputed("percentage")
- showPercentage(percentage) {
- return percentage.total >= 3;
- }
-
- // We do a little logic to choose which icon to display and which text
- @discourseComputed("agreed", "disagreed", "ignored")
- percentage(agreed, disagreed, ignored) {
- let total = agreed + disagreed + ignored;
- let result = { total };
-
- if (total > 0) {
- result.agreed = Math.round((agreed / total) * 100);
- result.disagreed = Math.round((disagreed / total) * 100);
- result.ignored = Math.round((ignored / total) * 100);
- }
-
- let highest = Math.max(agreed, disagreed, ignored);
- if (highest === agreed) {
- result.icon = "thumbs-up";
- result.className = "agreed";
- result.label = `${result.agreed}%`;
- } else if (highest === disagreed) {
- result.icon = "thumbs-down";
- result.className = "disagreed";
- result.label = `${result.disagreed}%`;
- } else {
- result.icon = "up-right-from-square";
- result.className = "ignored";
- result.label = `${result.ignored}%`;
- }
-
- result.title = i18n("review.user_percentage.summary", {
- agreed: i18n("review.user_percentage.agreed", {
- count: result.agreed,
- }),
- disagreed: i18n("review.user_percentage.disagreed", {
- count: result.disagreed,
- }),
- ignored: i18n("review.user_percentage.ignored", {
- count: result.ignored,
- }),
- count: total,
- });
-
- return result;
- }
-}