From 6332d5040d18ee682c7e417f8131df77b51861e3 Mon Sep 17 00:00:00 2001
From: Sam <sam.saffron@gmail.com>
Date: Mon, 14 May 2018 13:07:59 +1000
Subject: [PATCH] UX: switch dashboard to be the new dashboard

Also:
- add pageviews
- add problems and version sections
---
 .../controllers/admin-dashboard-next.js.es6   | 53 ++++++++++++++++++-
 .../admin/controllers/admin-dashboard.js.es6  | 46 ----------------
 .../admin/models/admin-dashboard-next.js.es6  | 22 ++++++++
 .../admin/models/admin-dashboard.js.es6       | 17 ------
 .../admin/routes/admin-route-map.js.es6       |  4 +-
 .../javascripts/admin/templates/admin.hbs     |  2 +-
 .../admin/templates/dashboard-problems.hbs    | 35 ++++++++++++
 .../javascripts/admin/templates/dashboard.hbs | 42 ---------------
 .../admin/templates/dashboard_next.hbs        | 20 ++++++-
 app/controllers/admin/dashboard_controller.rb |  1 -
 .../admin/dashboard_next_controller.rb        |  1 +
 app/jobs/scheduled/dashboard_stats.rb         |  2 +-
 app/models/admin_dashboard_next_data.rb       |  2 +-
 config/locales/client.en.yml                  |  2 +
 config/locales/server.en.yml                  |  2 +-
 15 files changed, 137 insertions(+), 114 deletions(-)
 create mode 100644 app/assets/javascripts/admin/templates/dashboard-problems.hbs

diff --git a/app/assets/javascripts/admin/controllers/admin-dashboard-next.js.es6 b/app/assets/javascripts/admin/controllers/admin-dashboard-next.js.es6
index af8a0d26dc8..95d248a4af7 100644
--- a/app/assets/javascripts/admin/controllers/admin-dashboard-next.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-dashboard-next.js.es6
@@ -1,7 +1,11 @@
+import { setting } from 'discourse/lib/computed';
 import DiscourseURL from "discourse/lib/url";
 import computed from "ember-addons/ember-computed-decorators";
 import AdminDashboardNext from "admin/models/admin-dashboard-next";
 import Report from "admin/models/report";
+import VersionCheck from 'admin/models/version-check';
+
+const PROBLEMS_CHECK_MINUTES = 1;
 
 export default Ember.Controller.extend({
   queryParams: ["period"],
@@ -9,10 +13,28 @@ export default Ember.Controller.extend({
   isLoading: false,
   dashboardFetchedAt: null,
   exceptionController: Ember.inject.controller("exception"),
+  showVersionChecks: setting('version_checks'),
   diskSpace: Ember.computed.alias("model.attributes.disk_space"),
 
   availablePeriods: ["yearly", "quarterly", "monthly", "weekly"],
 
+  @computed('problems.length')
+  foundProblems(problemsLength) {
+    return this.currentUser.get('admin') && (problemsLength || 0) > 0;
+  },
+
+
+  @computed('foundProblems')
+  thereWereProblems(foundProblems) {
+    if (!this.currentUser.get('admin')) { return false; }
+
+    if (foundProblems) {
+      this.set('hadProblems', true);
+      return true;
+    } else {
+      return this.get('hadProblems') || false;
+    }
+  },
 
   fetchDashboard() {
     if (this.get("isLoading")) return;
@@ -20,7 +42,14 @@ export default Ember.Controller.extend({
     if (!this.get("dashboardFetchedAt") || moment().subtract(30, "minutes").toDate() > this.get("dashboardFetchedAt")) {
       this.set("isLoading", true);
 
+      const versionChecks = this.siteSettings.version_checks;
+
       AdminDashboardNext.find().then(adminDashboardNextModel => {
+
+        if (versionChecks) {
+          this.set('versionCheck', VersionCheck.create(adminDashboardNextModel.version_check));
+        }
+
         this.setProperties({
           dashboardFetchedAt: new Date(),
           model: adminDashboardNextModel,
@@ -33,6 +62,25 @@ export default Ember.Controller.extend({
         this.set("isLoading", false);
       });
     }
+
+    if (!this.get('problemsFetchedAt') || moment().subtract(PROBLEMS_CHECK_MINUTES, 'minutes').toDate() > this.get('problemsFetchedAt')) {
+      this.loadProblems();
+    }
+  },
+
+  loadProblems() {
+    this.set('loadingProblems', true);
+    this.set('problemsFetchedAt', new Date());
+    AdminDashboardNext.fetchProblems().then(d => {
+      this.set('problems', d.problems);
+    }).finally(() => {
+      this.set('loadingProblems', false);
+    });
+  },
+
+  @computed('problemsFetchedAt')
+  problemsTimestamp(problemsFetchedAt) {
+    return moment(problemsFetchedAt).format('LLL');
   },
 
   @computed("period")
@@ -80,7 +128,10 @@ export default Ember.Controller.extend({
   actions: {
     changePeriod(period) {
       DiscourseURL.routeTo(this._reportsForPeriodURL(period));
-    }
+    },
+    refreshProblems() {
+      this.loadProblems();
+    },
   },
 
   _reportsForPeriodURL(period) {
diff --git a/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6 b/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6
index 6652002fb46..973cd3d57c9 100644
--- a/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6
@@ -1,11 +1,8 @@
-import { setting } from 'discourse/lib/computed';
 import AdminDashboard from 'admin/models/admin-dashboard';
-import VersionCheck from 'admin/models/version-check';
 import Report from 'admin/models/report';
 import AdminUser from 'admin/models/admin-user';
 import computed from 'ember-addons/ember-computed-decorators';
 
-const PROBLEMS_CHECK_MINUTES = 1;
 
 const ATTRIBUTES = [ 'disk_space','admins', 'moderators', 'silenced', 'suspended', 'top_traffic_sources',
                      'top_referred_topics', 'updated_at'];
@@ -18,35 +15,13 @@ export default Ember.Controller.extend({
   loading: null,
   versionCheck: null,
   dashboardFetchedAt: null,
-  showVersionChecks: setting('version_checks'),
   exceptionController: Ember.inject.controller('exception'),
 
-  @computed('problems.length')
-  foundProblems(problemsLength) {
-    return this.currentUser.get('admin') && (problemsLength || 0) > 0;
-  },
-
-  @computed('foundProblems')
-  thereWereProblems(foundProblems) {
-    if (!this.currentUser.get('admin')) { return false; }
-
-    if (foundProblems) {
-      this.set('hadProblems', true);
-      return true;
-    } else {
-      return this.get('hadProblems') || false;
-    }
-  },
-
   fetchDashboard() {
     if (!this.get('dashboardFetchedAt') || moment().subtract(30, 'minutes').toDate() > this.get('dashboardFetchedAt')) {
       this.set('loading', true);
-      const versionChecks = this.siteSettings.version_checks;
       AdminDashboard.find().then(d => {
         this.set('dashboardFetchedAt', new Date());
-        if (versionChecks) {
-          this.set('versionCheck', VersionCheck.create(d.version_check));
-        }
 
         REPORTS.forEach(name => this.set(name, d[name].map(r => Report.create(r))));
 
@@ -64,26 +39,8 @@ export default Ember.Controller.extend({
         this.set('loading', false);
       });
     }
-
-    if (!this.get('problemsFetchedAt') || moment().subtract(PROBLEMS_CHECK_MINUTES, 'minutes').toDate() > this.get('problemsFetchedAt')) {
-      this.loadProblems();
-    }
   },
 
-  loadProblems() {
-    this.set('loadingProblems', true);
-    this.set('problemsFetchedAt', new Date());
-    AdminDashboard.fetchProblems().then(d => {
-      this.set('problems', d.problems);
-    }).finally(() => {
-      this.set('loadingProblems', false);
-    });
-  },
-
-  @computed('problemsFetchedAt')
-  problemsTimestamp(problemsFetchedAt) {
-    return moment(problemsFetchedAt).format('LLL');
-  },
 
   @computed('updated_at')
   updatedTimestamp(updatedAt) {
@@ -91,9 +48,6 @@ export default Ember.Controller.extend({
   },
 
   actions: {
-    refreshProblems() {
-      this.loadProblems();
-    },
     showTrafficReport() {
       this.set("showTrafficReport", true);
     }
diff --git a/app/assets/javascripts/admin/models/admin-dashboard-next.js.es6 b/app/assets/javascripts/admin/models/admin-dashboard-next.js.es6
index 4747529fe7e..db3adf22481 100644
--- a/app/assets/javascripts/admin/models/admin-dashboard-next.js.es6
+++ b/app/assets/javascripts/admin/models/admin-dashboard-next.js.es6
@@ -13,10 +13,13 @@ AdminDashboardNext.reopenClass({
     @return {jqXHR} a jQuery Promise object
   **/
   find() {
+
     return ajax("/admin/dashboard-next.json").then(function(json) {
+
       var model = AdminDashboardNext.create();
 
       model.set("reports", json.reports);
+      model.set("version_check", json.version_check);
 
       const attributes = {};
       ATTRIBUTES.forEach(a => attributes[a] = json[a]);
@@ -24,6 +27,25 @@ AdminDashboardNext.reopenClass({
 
       model.set("loaded", true);
 
+      return model;
+    });
+  },
+
+
+  /**
+    Only fetch the list of problems that should be rendered on the dashboard.
+    The model will only have its "problems" attribute set.
+
+    @method fetchProblems
+    @return {jqXHR} a jQuery Promise object
+  **/
+  fetchProblems: function() {
+    return ajax("/admin/dashboard/problems.json", {
+      type: 'GET',
+      dataType: 'json'
+    }).then(function(json) {
+      var model = AdminDashboardNext.create(json);
+      model.set('loaded', true);
       return model;
     });
   }
diff --git a/app/assets/javascripts/admin/models/admin-dashboard.js.es6 b/app/assets/javascripts/admin/models/admin-dashboard.js.es6
index ac44a7677f1..49ed8e1a078 100644
--- a/app/assets/javascripts/admin/models/admin-dashboard.js.es6
+++ b/app/assets/javascripts/admin/models/admin-dashboard.js.es6
@@ -19,23 +19,6 @@ AdminDashboard.reopenClass({
     });
   },
 
-  /**
-    Only fetch the list of problems that should be rendered on the dashboard.
-    The model will only have its "problems" attribute set.
-
-    @method fetchProblems
-    @return {jqXHR} a jQuery Promise object
-  **/
-  fetchProblems: function() {
-    return ajax("/admin/dashboard/problems.json", {
-      type: 'GET',
-      dataType: 'json'
-    }).then(function(json) {
-      var model = AdminDashboard.create(json);
-      model.set('loaded', true);
-      return model;
-    });
-  }
 });
 
 export default AdminDashboard;
diff --git a/app/assets/javascripts/admin/routes/admin-route-map.js.es6 b/app/assets/javascripts/admin/routes/admin-route-map.js.es6
index 5b42f045e1d..5a033e1efa5 100644
--- a/app/assets/javascripts/admin/routes/admin-route-map.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-route-map.js.es6
@@ -1,7 +1,7 @@
 export default function() {
   this.route('admin', { resetNamespace: true }, function() {
-    this.route('dashboard', { path: '/' });
-    this.route('dashboardNext', { path: '/dashboard-next' });
+    this.route('dashboard', { path: '/dashboard-old' });
+    this.route('dashboardNext', { path: '/' });
     this.route('adminSiteSettings', { path: '/site_settings', resetNamespace: true }, function() {
       this.route('adminSiteSettingsCategory', { path: 'category/:category_id', resetNamespace: true} );
     });
diff --git a/app/assets/javascripts/admin/templates/admin.hbs b/app/assets/javascripts/admin/templates/admin.hbs
index 092133b7c17..cf4d231d4ed 100644
--- a/app/assets/javascripts/admin/templates/admin.hbs
+++ b/app/assets/javascripts/admin/templates/admin.hbs
@@ -3,7 +3,7 @@
     <div class="full-width">
 
       <ul class="nav nav-pills">
-        {{nav-item route='admin.dashboard' label='admin.dashboard.title'}}
+        {{nav-item route='admin.dashboardNext' label='admin.dashboard.title'}}
         {{#if currentUser.admin}}
           {{nav-item route='adminSiteSettings' label='admin.site_settings.title'}}
         {{/if}}
diff --git a/app/assets/javascripts/admin/templates/dashboard-problems.hbs b/app/assets/javascripts/admin/templates/dashboard-problems.hbs
new file mode 100644
index 00000000000..3c43f979c1d
--- /dev/null
+++ b/app/assets/javascripts/admin/templates/dashboard-problems.hbs
@@ -0,0 +1,35 @@
+{{#if foundProblems}}
+  <div class="dashboard-stats detected-problems">
+    <div class="look-here">{{d-icon "exclamation-triangle"}}</div>
+    <div class="problem-messages">
+      {{#conditional-loading-spinner condition=loadingProblems}}
+        <p>
+          {{i18n 'admin.dashboard.problems_found'}}
+          <ul class="{{if loadingProblems 'invisible'}}">
+            {{#each problems as |problem|}}
+              <li>{{{problem}}}</li>
+            {{/each}}
+          </ul>
+        </p>
+        <p class="actions">
+          <small>{{i18n 'admin.dashboard.last_checked'}}: {{problemsTimestamp}}</small>
+          {{d-button action="refreshProblems" class="btn-small" icon="refresh" label="admin.dashboard.refresh_problems"}}
+        </p>
+      {{/conditional-loading-spinner}}
+    </div>
+    <div class="clearfix"></div>
+  </div>
+{{else}}
+  {{#if thereWereProblems}}
+    <div class="dashboard-stats detected-problems">
+      <div class="look-here">&nbsp;</div>
+      <div class="problem-messages">
+        <p>
+          {{i18n 'admin.dashboard.no_problems'}}
+          {{d-button action="refreshProblems" class="btn-small" icon="refresh" label="admin.dashboard.refresh_problems"}}
+        </p>
+      </div>
+      <div class="clearfix"></div>
+    </div>
+  {{/if}}
+{{/if}}
diff --git a/app/assets/javascripts/admin/templates/dashboard.hbs b/app/assets/javascripts/admin/templates/dashboard.hbs
index a761b4990c3..6018b64572f 100644
--- a/app/assets/javascripts/admin/templates/dashboard.hbs
+++ b/app/assets/javascripts/admin/templates/dashboard.hbs
@@ -1,11 +1,5 @@
-{{plugin-outlet name="admin-dashboard-top"}}
-
 {{#conditional-loading-spinner condition=loading}}
   <div class="dashboard-left">
-    {{#if showVersionChecks}}
-      {{partial 'admin/templates/version-checks'}}
-    {{/if}}
-
     <div class="dashboard-stats trust-levels">
       <table class="table table-condensed table-hover">
         <thead>
@@ -174,42 +168,6 @@
   </div>
 
   <div class="dashboard-right">
-    {{#if foundProblems}}
-      <div class="dashboard-stats detected-problems">
-        <div class="look-here">{{d-icon "exclamation-triangle"}}</div>
-        <div class="problem-messages">
-          {{#conditional-loading-spinner condition=loadingProblems}}
-            <p>
-              {{i18n 'admin.dashboard.problems_found'}}
-              <ul class="{{if loadingProblems 'invisible'}}">
-                {{#each problems as |problem|}}
-                  <li>{{{problem}}}</li>
-                {{/each}}
-              </ul>
-            </p>
-            <p class="actions">
-              <small>{{i18n 'admin.dashboard.last_checked'}}: {{problemsTimestamp}}</small>
-              {{d-button action="refreshProblems" class="btn-small" icon="refresh" label="admin.dashboard.refresh_problems"}}
-            </p>
-          {{/conditional-loading-spinner}}
-        </div>
-        <div class="clearfix"></div>
-      </div>
-    {{else}}
-      {{#if thereWereProblems}}
-        <div class="dashboard-stats detected-problems">
-          <div class="look-here">&nbsp;</div>
-          <div class="problem-messages">
-            <p>
-              {{i18n 'admin.dashboard.no_problems'}}
-              {{d-button action="refreshProblems" class="btn-small" icon="refresh" label="admin.dashboard.refresh_problems"}}
-            </p>
-          </div>
-          <div class="clearfix"></div>
-        </div>
-      {{/if}}
-    {{/if}}
-
     <div class="dashboard-stats">
       <table class="table table-condensed table-hover">
         <thead>
diff --git a/app/assets/javascripts/admin/templates/dashboard_next.hbs b/app/assets/javascripts/admin/templates/dashboard_next.hbs
index b662dcd230f..3f7ad4f6d11 100644
--- a/app/assets/javascripts/admin/templates/dashboard_next.hbs
+++ b/app/assets/javascripts/admin/templates/dashboard_next.hbs
@@ -1,4 +1,16 @@
- {{plugin-outlet name="admin-dashboard-top"}}
+{{plugin-outlet name="admin-dashboard-top"}}
+
+<div class="section-top">
+{{#if showVersionChecks}}
+  <div class="dashboard-left">
+    {{partial 'admin/templates/version-checks'}}
+  </div>
+  <div class="dashboard-right">
+    {{partial 'admin/templates/dashboard-problems'}}
+  </div>
+{{/if}}
+  <div class='clearfix'></div>
+</div>
 
 <div class="community-health section">
   <div class="section-title">
@@ -105,6 +117,12 @@
 
         <hr />
 
+        <p>
+          {{i18n 'admin.dashboard.find_old'}} {{#link-to 'admin.dashboard'}}{{i18n "admin.dashboard.old_link"}}{{/link-to}}
+        </p>
+
+        <hr />
+
         <p class="last-dashboard-update">
           {{i18n "admin.dashboard.last_updated"}} {{updatedTimestamp}}
         </p>
diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb
index 51be59fcde2..f14f66d5628 100644
--- a/app/controllers/admin/dashboard_controller.rb
+++ b/app/controllers/admin/dashboard_controller.rb
@@ -3,7 +3,6 @@ class Admin::DashboardController < Admin::AdminController
   def index
     dashboard_data = AdminDashboardData.fetch_cached_stats || Jobs::DashboardStats.new.execute({})
     dashboard_data.merge!(version_check: DiscourseUpdates.check_version.as_json) if SiteSetting.version_checks?
-
     dashboard_data[:disk_space] = DiskSpace.cached_stats
     render json: dashboard_data
   end
diff --git a/app/controllers/admin/dashboard_next_controller.rb b/app/controllers/admin/dashboard_next_controller.rb
index 908a4206d45..47eef7b5f4c 100644
--- a/app/controllers/admin/dashboard_next_controller.rb
+++ b/app/controllers/admin/dashboard_next_controller.rb
@@ -3,6 +3,7 @@ require 'disk_space'
 class Admin::DashboardNextController < Admin::AdminController
   def index
     dashboard_data = AdminDashboardNextData.fetch_cached_stats
+    dashboard_data.merge!(version_check: DiscourseUpdates.check_version.as_json) if SiteSetting.version_checks?
     dashboard_data[:disk_space] = DiskSpace.cached_stats
     render json: dashboard_data
   end
diff --git a/app/jobs/scheduled/dashboard_stats.rb b/app/jobs/scheduled/dashboard_stats.rb
index 7e5fe8c4233..d475075c4df 100644
--- a/app/jobs/scheduled/dashboard_stats.rb
+++ b/app/jobs/scheduled/dashboard_stats.rb
@@ -15,8 +15,8 @@ module Jobs
       end
 
       # TODO: decide if we want to keep caching this every 30 minutes
-      AdminDashboardData.refresh_stats
       AdminDashboardNextData.refresh_stats
+      AdminDashboardData.refresh_stats
     end
   end
 end
diff --git a/app/models/admin_dashboard_next_data.rb b/app/models/admin_dashboard_next_data.rb
index 4fff1a40dc4..b588561440a 100644
--- a/app/models/admin_dashboard_next_data.rb
+++ b/app/models/admin_dashboard_next_data.rb
@@ -1,7 +1,7 @@
 class AdminDashboardNextData
   include StatsCacheable
 
-  REPORTS = [ "visits", "posts", "time_to_first_response", "likes", "flags" ]
+  REPORTS = ["page_view_total_reqs", "visits", "posts", "time_to_first_response", "likes", "flags" ]
 
   def initialize(opts = {})
     @opts = opts
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 525ed566fcc..2f4fc5f510e 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -2713,6 +2713,8 @@ en:
       dashboard:
         title: "Dashboard"
         last_updated: "Dashboard last updated:"
+        find_old: "Looking for the old dashboard?"
+        old_link: "visit it here"
         version: "Version"
         up_to_date: "You're up to date!"
         critical_available: "A critical update is available."
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 127bcb635b0..f49749e9881 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -972,7 +972,7 @@ en:
       xaxis: "Day"
       yaxis: "Web Crawler Pageviews"
     page_view_total_reqs:
-      title: "Total"
+      title: "Pageviews"
       xaxis: "Day"
       yaxis: "Total Pageviews"
     page_view_logged_in_mobile_reqs: