diff --git a/app/assets/javascripts/admin/routes/admin_dashboard_route.js b/app/assets/javascripts/admin/routes/admin_dashboard_route.js
index bf7571a4b..99bce2159 100644
--- a/app/assets/javascripts/admin/routes/admin_dashboard_route.js
+++ b/app/assets/javascripts/admin/routes/admin_dashboard_route.js
@@ -31,7 +31,7 @@ Discourse.AdminDashboardRoute = Discourse.Route.extend({
if( !c.get('reportsCheckedAt') || Date.create('1 hour ago') > c.get('reportsCheckedAt') ) {
// TODO: use one request to get all reports, or maybe one request for all dashboard data including version check.
c.set('reportsCheckedAt', new Date());
- ['visits', 'signups', 'topics', 'posts'].each(function(reportType){
+ ['visits', 'signups', 'topics', 'posts', 'total_users'].each(function(reportType){
c.set(reportType, Discourse.Report.find(reportType));
});
}
diff --git a/app/assets/javascripts/admin/templates/dashboard.js.handlebars b/app/assets/javascripts/admin/templates/dashboard.js.handlebars
index e97df94c2..6e97f3b23 100644
--- a/app/assets/javascripts/admin/templates/dashboard.js.handlebars
+++ b/app/assets/javascripts/admin/templates/dashboard.js.handlebars
@@ -54,9 +54,26 @@
{{i18n admin.dashboard.reports.last_30_days}} |
- {{ render 'admin_signups' signups }}
- {{ render 'admin_visits' visits }}
- {{ render 'admin_topics' topics }}
- {{ render 'admin_posts' posts }}
+ {{ render 'admin_report_signups' signups }}
+ {{ render 'admin_report_topics' topics }}
+ {{ render 'admin_report_posts' posts }}
-
\ No newline at end of file
+
+
+
+
+
+
+ |
+ {{i18n admin.dashboard.reports.today}} |
+ {{i18n admin.dashboard.reports.yesterday}} |
+ {{i18n admin.dashboard.reports.7_days_ago}} |
+ {{i18n admin.dashboard.reports.30_days_ago}} |
+
+
+ {{ render 'admin_report_total_users' total_users }}
+ {{ render 'admin_report_visits' visits }}
+
+
+
+
\ No newline at end of file
diff --git a/app/assets/javascripts/admin/templates/reports/per_day_counts_report.js.handlebars b/app/assets/javascripts/admin/templates/reports/per_day_counts_report.js.handlebars
new file mode 100644
index 000000000..8c33b4dc2
--- /dev/null
+++ b/app/assets/javascripts/admin/templates/reports/per_day_counts_report.js.handlebars
@@ -0,0 +1,9 @@
+{{#if loaded}}
+
+ {{title}} |
+ {{valueAtDaysAgo data 0}} |
+ {{valueAtDaysAgo data 1}} |
+ {{valueAtDaysAgo data 7}} |
+ {{valueAtDaysAgo data 30}} |
+
+{{/if}}
\ No newline at end of file
diff --git a/app/assets/javascripts/admin/templates/reports/summed_counts_report.js.handlebars b/app/assets/javascripts/admin/templates/reports/summed_counts_report.js.handlebars
new file mode 100644
index 000000000..8ac6c4077
--- /dev/null
+++ b/app/assets/javascripts/admin/templates/reports/summed_counts_report.js.handlebars
@@ -0,0 +1,9 @@
+{{#if loaded}}
+
+ {{title}} |
+ {{valueAtDaysAgo data 0}} |
+ {{valueAtDaysAgo data 1}} |
+ {{sumLast data 7}} |
+ {{sumLast data 30}} |
+
+{{/if}}
\ No newline at end of file
diff --git a/app/assets/javascripts/admin/views/report/admin_report_posts_view.js b/app/assets/javascripts/admin/views/report/admin_report_posts_view.js
new file mode 100644
index 000000000..bdabb547c
--- /dev/null
+++ b/app/assets/javascripts/admin/views/report/admin_report_posts_view.js
@@ -0,0 +1,4 @@
+Discourse.AdminReportPostsView = Discourse.View.extend({
+ templateName: 'admin/templates/reports/summed_counts_report',
+ tagName: 'tbody'
+});
\ No newline at end of file
diff --git a/app/assets/javascripts/admin/views/report/admin_report_signups_view.js b/app/assets/javascripts/admin/views/report/admin_report_signups_view.js
new file mode 100644
index 000000000..c2f6f4013
--- /dev/null
+++ b/app/assets/javascripts/admin/views/report/admin_report_signups_view.js
@@ -0,0 +1,4 @@
+Discourse.AdminReportSignupsView = Discourse.View.extend({
+ templateName: 'admin/templates/reports/summed_counts_report',
+ tagName: 'tbody'
+});
\ No newline at end of file
diff --git a/app/assets/javascripts/admin/views/report/admin_report_topics_view.js b/app/assets/javascripts/admin/views/report/admin_report_topics_view.js
new file mode 100644
index 000000000..9ef10d65f
--- /dev/null
+++ b/app/assets/javascripts/admin/views/report/admin_report_topics_view.js
@@ -0,0 +1,4 @@
+Discourse.AdminReportTopicsView = Discourse.View.extend({
+ templateName: 'admin/templates/reports/summed_counts_report',
+ tagName: 'tbody'
+});
\ No newline at end of file
diff --git a/app/assets/javascripts/admin/views/report/admin_report_total_users_view.js b/app/assets/javascripts/admin/views/report/admin_report_total_users_view.js
new file mode 100644
index 000000000..0edca3690
--- /dev/null
+++ b/app/assets/javascripts/admin/views/report/admin_report_total_users_view.js
@@ -0,0 +1,4 @@
+Discourse.AdminReportTotalUsersView = Discourse.View.extend({
+ templateName: 'admin/templates/reports/per_day_counts_report',
+ tagName: 'tbody'
+});
\ No newline at end of file
diff --git a/app/assets/javascripts/admin/views/report/admin_report_visits_view.js b/app/assets/javascripts/admin/views/report/admin_report_visits_view.js
new file mode 100644
index 000000000..31ab82c05
--- /dev/null
+++ b/app/assets/javascripts/admin/views/report/admin_report_visits_view.js
@@ -0,0 +1,4 @@
+Discourse.AdminReportVisitsView = Discourse.View.extend({
+ templateName: 'admin/templates/reports/per_day_counts_report',
+ tagName: 'tbody'
+});
\ No newline at end of file
diff --git a/app/assets/javascripts/admin/views/reports_views.js b/app/assets/javascripts/admin/views/reports_views.js
deleted file mode 100644
index c3bea1904..000000000
--- a/app/assets/javascripts/admin/views/reports_views.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- These views are needed so we can render the same template multiple times on
- the admin dashboard.
-**/
-var opts = { templateName: 'admin/templates/report', tagName: 'tbody' };
-Discourse.AdminSignupsView = Discourse.View.extend(opts);
-Discourse.AdminVisitsView = Discourse.View.extend(opts);
-Discourse.AdminTopicsView = Discourse.View.extend(opts);
-Discourse.AdminPostsView = Discourse.View.extend(opts);
\ No newline at end of file
diff --git a/app/assets/stylesheets/admin/admin_base.scss b/app/assets/stylesheets/admin/admin_base.scss
index 3e47626f3..99f7f9828 100644
--- a/app/assets/stylesheets/admin/admin_base.scss
+++ b/app/assets/stylesheets/admin/admin_base.scss
@@ -304,10 +304,13 @@ table {
}
.dashboard-stats {
- margin-top: 10px;
+ margin-top: 30px;
+ width: 450px;
+ float: left;
+ margin-left: 40px;
table {
- width: 450px;
+ width: 100%;
th {
font-weight: normal;
diff --git a/app/models/report.rb b/app/models/report.rb
index 719643865..d3b7e0bdc 100644
--- a/app/models/report.rb
+++ b/app/models/report.rb
@@ -69,6 +69,17 @@ class Report
end
end
+ def self.report_total_users(report)
+ report.data = []
+ fetch report do
+ (0..30).each do |i|
+ if (count = User.where('created_at < ?', i.days.ago).count) > 0
+ report.data << {x: i.days.ago.to_date.to_s, y: count}
+ end
+ end
+ end
+ end
+
private
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 70241de42..4a6e9e162 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -689,6 +689,8 @@ en:
last_7_days: "Last 7 Days"
last_30_days: "Last 30 Days"
all_time: "All Time"
+ 7_days_ago: "7 Days Ago"
+ 30_days_ago: "30 Days Ago"
flags:
title: "Flags"
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 1b3fd7d4d..4c2ecc845 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -244,7 +244,7 @@ en:
reports:
visits:
- title: "Users Visits"
+ title: "User Visits"
xaxis: "Day"
yaxis: "Number of visits"
signups:
@@ -259,6 +259,8 @@ en:
title: "New Posts"
xaxis: "Day"
yaxis: "Number of new posts"
+ total_users:
+ title: "Total Users"
site_settings:
default_locale: "The default language of this Discourse instance (ISO 639-1 Code)"
diff --git a/spec/models/report_spec.rb b/spec/models/report_spec.rb
index 012a1cade..3963e3fe5 100644
--- a/spec/models/report_spec.rb
+++ b/spec/models/report_spec.rb
@@ -45,9 +45,9 @@ describe Report do
context "with #{pluralized}" do
before do
fabricator = (arg == :signup ? :user : arg)
- Fabricate(fabricator, created_at: 2.days.ago)
- Fabricate(fabricator, created_at: 1.day.ago)
- Fabricate(fabricator, created_at: 1.day.ago)
+ Fabricate(fabricator, created_at: 25.hours.ago)
+ Fabricate(fabricator, created_at: 1.hours.ago)
+ Fabricate(fabricator, created_at: 1.hours.ago)
end
it 'returns correct data' do
@@ -58,6 +58,29 @@ describe Report do
end
end
+ describe "total_users report" do
+ let(:report) { Report.find("total_users", cache: false) }
+
+ context "no total_users" do
+ it 'returns an empty report' do
+ report.data.should be_blank
+ end
+ end
+
+ context "with users" do
+ before do
+ Fabricate(:user, created_at: 25.hours.ago)
+ Fabricate(:user, created_at: 1.hours.ago)
+ Fabricate(:user, created_at: 1.hours.ago)
+ end
+
+ it 'returns correct data' do
+ report.data[0][:y].should == 3
+ report.data[1][:y].should == 1
+ end
+ end
+ end
+
describe '#fetch' do
context 'signups' do
let(:report) { Report.find('signups', cache: true) }
@@ -90,9 +113,9 @@ describe Report do
context 'with data' do
before do
- Fabricate(:user, created_at: 2.days.ago)
- Fabricate(:user, created_at: 1.day.ago)
- Fabricate(:user, created_at: 1.day.ago)
+ Fabricate(:user, created_at: 25.hours.ago)
+ Fabricate(:user, created_at: 1.hour.ago)
+ Fabricate(:user, created_at: 1.hour.ago)
end
context 'cache miss' do