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"> </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"> </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: