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 + + +
+ + + + + + + + + + + {{ render 'admin_report_total_users' total_users }} + {{ render 'admin_report_visits' visits }} +
 {{i18n admin.dashboard.reports.today}}{{i18n admin.dashboard.reports.yesterday}}{{i18n admin.dashboard.reports.7_days_ago}}{{i18n admin.dashboard.reports.30_days_ago}}
+
+ +
\ 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