diff --git a/app/assets/javascripts/discourse/app/components/about-page.gjs b/app/assets/javascripts/discourse/app/components/about-page.gjs
index f95b35c5674..31a836a733c 100644
--- a/app/assets/javascripts/discourse/app/components/about-page.gjs
+++ b/app/assets/javascripts/discourse/app/components/about-page.gjs
@@ -120,7 +120,7 @@ export default class AboutPage extends Component {
},
];
- if (this.siteSettings.display_eu_visitor_stats) {
+ if (this.displayVisitorStats) {
list.splice(2, 0, {
icon: "user-secret",
class: "visitors",
@@ -137,6 +137,14 @@ export default class AboutPage extends Component {
return list.concat(this.siteActivitiesFromPlugins());
}
+ get displayVisitorStats() {
+ return (
+ this.siteSettings.display_eu_visitor_stats &&
+ typeof this.args.model.stats.eu_visitors_7_days === "number" &&
+ typeof this.args.model.stats.visitors_7_days === "number"
+ );
+ }
+
get contactInfo() {
const url = escape(this.args.model.contact_url || "");
const email = escape(this.args.model.contact_email || "");
@@ -292,7 +300,7 @@ export default class AboutPage extends Component {
{{/each}}
- {{#if this.siteSettings.display_eu_visitor_stats}}
+ {{#if this.displayVisitorStats}}
{{/if}}
diff --git a/app/assets/javascripts/discourse/app/controllers/about.js b/app/assets/javascripts/discourse/app/controllers/about.js
index 55206f821aa..7249274f878 100644
--- a/app/assets/javascripts/discourse/app/controllers/about.js
+++ b/app/assets/javascripts/discourse/app/controllers/about.js
@@ -54,4 +54,17 @@ export default class AboutController extends Controller {
}
return Array.from(set);
}
+
+ @discourseComputed(
+ "model.stats.visitors_7_days",
+ "model.stats.eu_visitors_7_days",
+ "siteSettings.display_eu_visitor_stats"
+ )
+ displayVisitorStats(visitors, euVisitors, displayEuVisitorStats) {
+ return (
+ displayEuVisitorStats &&
+ typeof euVisitors === "number" &&
+ typeof visitors === "number"
+ );
+ }
}
diff --git a/app/assets/javascripts/discourse/app/templates/about.hbs b/app/assets/javascripts/discourse/app/templates/about.hbs
index 5b6fd6dba64..ac7b68c4661 100644
--- a/app/assets/javascripts/discourse/app/templates/about.hbs
+++ b/app/assets/javascripts/discourse/app/templates/about.hbs
@@ -139,7 +139,7 @@
{{number this.model.stats.active_users_30_days}} |
— |
- {{#if this.siteSettings.display_eu_visitor_stats}}
+ {{#if this.displayVisitorStats}}
{{i18n "about.visitor_count"}} |
{{number this.model.stats.visitors_last_day}} |
@@ -183,7 +183,7 @@
{{/each}}
- {{#if this.siteSettings.display_eu_visitor_stats}}
+ {{#if this.displayVisitorStats}}
{{/if}}
diff --git a/app/assets/javascripts/discourse/tests/integration/components/about-page-test.gjs b/app/assets/javascripts/discourse/tests/integration/components/about-page-test.gjs
index df7854af670..3eee0b41a99 100644
--- a/app/assets/javascripts/discourse/tests/integration/components/about-page-test.gjs
+++ b/app/assets/javascripts/discourse/tests/integration/components/about-page-test.gjs
@@ -3,6 +3,7 @@ import { module, test } from "qunit";
import AboutPage from "discourse/components/about-page";
import { withPluginApi } from "discourse/lib/plugin-api";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
+import I18n from "discourse-i18n";
function createModelObject({
title = "My Forums",
@@ -61,4 +62,40 @@ module("Integration | Component | about-page", function (hooks) {
)
.hasText("in the last 3 weeks");
});
+
+ test("visitor stats are not rendered if they're not available in the model", async function (assert) {
+ this.siteSettings.display_eu_visitor_stats = true;
+ let model = createModelObject({
+ stats: {},
+ });
+
+ await render();
+ assert
+ .dom(".about__activities-item.visitors")
+ .doesNotExist("visitors stats item is not rendered");
+
+ model = createModelObject({
+ stats: {
+ eu_visitors_7_days: 13,
+ eu_visitors_30_days: 30,
+ visitors_7_days: 33,
+ visitors_30_days: 103,
+ },
+ });
+
+ await render();
+ assert
+ .dom(".about__activities-item.visitors")
+ .exists("visitors stats item is rendered");
+ assert
+ .dom(".about__activities-item.visitors .about__activities-item-count")
+ .hasText(
+ I18n.messageFormat("about.activities.visitors_MF", {
+ total_count: 33,
+ eu_count: 13,
+ total_formatted_number: "33",
+ eu_formatted_number: "13",
+ })
+ );
+ });
});
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 4d883b97abe..317fb70adf0 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -2263,7 +2263,7 @@ en:
tos_url: "If you have a Terms of Service document hosted elsewhere that you want to use, provide the full URL here."
privacy_policy_url: "If you have a Privacy Policy document hosted elsewhere that you want to use, provide the full URL here."
log_anonymizer_details: "Whether to keep a user's details in the log after being anonymized."
- display_eu_visitor_stats: "Show number of global and EU visitors on the /about page."
+ display_eu_visitor_stats: "Show number of global and EU visitors on the /about page. It may take a few minutes for the stats to appear after turning on this setting."
newuser_spam_host_threshold: "How many times a new user can post a link to the same host within their `newuser_spam_host_threshold` posts before being considered spam."