From 7f2f3b8b226c9795cb609cb25155d08d580df5e1 Mon Sep 17 00:00:00 2001 From: Joffrey JAFFEUX Date: Mon, 6 Aug 2018 16:57:40 -0400 Subject: [PATCH] FIX: improves reports resilience (#6239) This commit makes most of the reports now lazy loaded, and making them benefits from graceful failures. --- .../components/admin-report-counters.js.es6 | 3 + .../admin-dashboard-next-general.js.es6 | 32 +++-- .../components/admin-report-counters.hbs | 20 +++ .../templates/components/admin-report.hbs | 2 +- .../templates/dashboard_next_general.hbs | 79 +++++------- .../stylesheets/common/admin/admin_base.scss | 1 + .../common/admin/admin_report.scss | 4 +- .../common/admin/admin_report_counters.scss | 122 ++++++++++++++++++ .../common/admin/dashboard_next.scss | 94 +------------- .../admin/dashboard_next_controller.rb | 3 +- .../admin_dashboard_next_general_data.rb | 6 - app/models/report.rb | 1 + test/javascripts/fixtures/flags.js.es6 | 7 + test/javascripts/fixtures/likes.js.es6 | 7 + .../fixtures/page_view_total_reqs.js.es6 | 7 + .../fixtures/time_to_first_response.js.es6 | 7 + ..._user_private_messages_with_replies.js.es6 | 7 + test/javascripts/fixtures/visits.js.es6 | 7 + 18 files changed, 246 insertions(+), 163 deletions(-) create mode 100644 app/assets/javascripts/admin/components/admin-report-counters.js.es6 create mode 100644 app/assets/javascripts/admin/templates/components/admin-report-counters.hbs create mode 100644 app/assets/stylesheets/common/admin/admin_report_counters.scss create mode 100644 test/javascripts/fixtures/flags.js.es6 create mode 100644 test/javascripts/fixtures/likes.js.es6 create mode 100644 test/javascripts/fixtures/page_view_total_reqs.js.es6 create mode 100644 test/javascripts/fixtures/time_to_first_response.js.es6 create mode 100644 test/javascripts/fixtures/user_to_user_private_messages_with_replies.js.es6 create mode 100644 test/javascripts/fixtures/visits.js.es6 diff --git a/app/assets/javascripts/admin/components/admin-report-counters.js.es6 b/app/assets/javascripts/admin/components/admin-report-counters.js.es6 new file mode 100644 index 00000000000..3806e29ecbf --- /dev/null +++ b/app/assets/javascripts/admin/components/admin-report-counters.js.es6 @@ -0,0 +1,3 @@ +export default Ember.Component.extend({ + classNames: ["admin-report-counters"] +}); diff --git a/app/assets/javascripts/admin/controllers/admin-dashboard-next-general.js.es6 b/app/assets/javascripts/admin/controllers/admin-dashboard-next-general.js.es6 index ddc8c319d0c..8a8af1bc2a4 100644 --- a/app/assets/javascripts/admin/controllers/admin-dashboard-next-general.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-dashboard-next-general.js.es6 @@ -4,18 +4,11 @@ import AdminDashboardNext from "admin/models/admin-dashboard-next"; import Report from "admin/models/report"; import PeriodComputationMixin from "admin/mixins/period-computation"; -const ACTIVITY_METRICS_REPORTS = [ - "page_view_total_reqs", - "visits", - "time_to_first_response", - "likes", - "flags", - "user_to_user_private_messages_with_replies" -]; - function staticReport(reportType) { return function() { - return this.get("reports").find(x => x.type === reportType); + return Ember.makeArray(this.get("reports")).find( + report => report.type === reportType + ); }.property("reports.[]"); } @@ -35,6 +28,18 @@ export default Ember.Controller.extend(PeriodComputationMixin, { return { table: { total: false, limit: 8 } }; }, + @computed + activityMetrics() { + return [ + "page_view_total_reqs", + "visits", + "time_to_first_response", + "likes", + "flags", + "user_to_user_private_messages_with_replies" + ]; + }, + @computed trendingSearchOptions() { return { table: { total: false, limit: 8 } }; @@ -43,13 +48,6 @@ export default Ember.Controller.extend(PeriodComputationMixin, { usersByTypeReport: staticReport("users_by_type"), usersByTrustLevelReport: staticReport("users_by_trust_level"), - @computed("reports.[]") - activityMetricsReports(reports) { - return reports.filter(report => - ACTIVITY_METRICS_REPORTS.includes(report.type) - ); - }, - fetchDashboard() { if (this.get("isLoading")) return; diff --git a/app/assets/javascripts/admin/templates/components/admin-report-counters.hbs b/app/assets/javascripts/admin/templates/components/admin-report-counters.hbs new file mode 100644 index 00000000000..605119360c6 --- /dev/null +++ b/app/assets/javascripts/admin/templates/components/admin-report-counters.hbs @@ -0,0 +1,20 @@ +
+ {{#if model.icon}} + {{d-icon model.icon}} + {{/if}} + {{model.title}} +
+ +
{{number model.todayCount}}
+ +
+ {{number model.yesterdayCount}} {{d-icon model.yesterdayTrendIcon}} +
+ +
+ {{number model.lastSevenDaysCount}} {{d-icon model.sevenDaysTrendIcon}} +
+ +
+ {{number model.lastThirtyDaysCount}} {{d-icon model.thirtyDaysTrendIcon}} +
diff --git a/app/assets/javascripts/admin/templates/components/admin-report.hbs b/app/assets/javascripts/admin/templates/components/admin-report.hbs index 716a893fe0b..6e2548a9f6d 100644 --- a/app/assets/javascripts/admin/templates/components/admin-report.hbs +++ b/app/assets/javascripts/admin/templates/components/admin-report.hbs @@ -68,7 +68,7 @@ {{else}}
{{d-icon "pie-chart"}} - {{i18n 'admin.dashboard.reports.no_data'}} + {{i18n "admin.dashboard.reports.no_data"}}
{{/if}} {{else}} diff --git a/app/assets/javascripts/admin/templates/dashboard_next_general.hbs b/app/assets/javascripts/admin/templates/dashboard_next_general.hbs index 0d03c548aae..76f1a342dac 100644 --- a/app/assets/javascripts/admin/templates/dashboard_next_general.hbs +++ b/app/assets/javascripts/admin/templates/dashboard_next_general.hbs @@ -57,61 +57,50 @@
- {{#conditional-loading-section isLoading=isLoading title=(i18n "admin.dashboard.activity_metrics")}} -
-
-

- {{#link-to "adminReports" class="report-link"}} - {{i18n "admin.dashboard.activity_metrics"}} - {{/link-to}} -

-
+
+
+

+ {{#link-to "adminReports" class="report-link"}} + {{i18n "admin.dashboard.activity_metrics"}} + {{/link-to}} +

+
+
+
+
+
+
{{i18n 'admin.dashboard.reports.today'}}
+
{{i18n 'admin.dashboard.reports.yesterday'}}
+
{{i18n 'admin.dashboard.reports.last_7_days'}}
+
{{i18n 'admin.dashboard.reports.last_30_days'}}
+
-
-
- - - - - - - - - - - - {{#each activityMetricsReports as |report|}} - {{admin-report-counts report=report allTime=false class="admin-report-table-row"}} - {{/each}} - -
- {{i18n 'admin.dashboard.reports.today'}} - - {{i18n 'admin.dashboard.reports.yesterday'}} - - {{i18n 'admin.dashboard.reports.last_7_days'}} - - {{i18n 'admin.dashboard.reports.last_30_days'}} -
-
+ {{#each activityMetrics as |metric|}} + {{admin-report + showHeader=false + forcedModes="counters" + dataSourceName=metric}} + {{/each}}
- {{/conditional-loading-section}} +
{{#link-to "adminReports"}} {{i18n "admin.dashboard.all_reports"}} {{/link-to}}
- {{admin-report - forcedModes="inline-table" - report=usersByTypeReport - lastRefreshedAt=lastRefreshedAt}} + {{#conditional-loading-section isLoading=isLoading}} + {{admin-report + forcedModes="inline-table" + report=usersByTypeReport + lastRefreshedAt=lastRefreshedAt}} - {{admin-report - forcedModes="inline-table" - report=usersByTrustLevelReport - lastRefreshedAt=lastRefreshedAt}} + {{admin-report + forcedModes="inline-table" + report=usersByTrustLevelReport + lastRefreshedAt=lastRefreshedAt}} + {{/conditional-loading-section}}
{{#conditional-loading-section isLoading=isLoading title=(i18n "admin.dashboard.backups")}} diff --git a/app/assets/stylesheets/common/admin/admin_base.scss b/app/assets/stylesheets/common/admin/admin_base.scss index f7a1fcb31a6..b302b7834c1 100644 --- a/app/assets/stylesheets/common/admin/admin_base.scss +++ b/app/assets/stylesheets/common/admin/admin_base.scss @@ -951,6 +951,7 @@ table#user-badges { @import "common/admin/plugins"; @import "common/admin/admin_reports"; @import "common/admin/admin_report"; +@import "common/admin/admin_report_counters"; @import "common/admin/admin_report_chart"; @import "common/admin/admin_report_table"; @import "common/admin/admin_report_inline_table"; diff --git a/app/assets/stylesheets/common/admin/admin_report.scss b/app/assets/stylesheets/common/admin/admin_report.scss index 96709f07777..f5f058ba1fa 100644 --- a/app/assets/stylesheets/common/admin/admin_report.scss +++ b/app/assets/stylesheets/common/admin/admin_report.scss @@ -27,9 +27,9 @@ } } - .conditional-loading-section.is-loading { + .conditional-loading-section { flex: 1; - margin: 0.5em 0; + margin: 0; } .report-header { diff --git a/app/assets/stylesheets/common/admin/admin_report_counters.scss b/app/assets/stylesheets/common/admin/admin_report_counters.scss new file mode 100644 index 00000000000..63dc889f80e --- /dev/null +++ b/app/assets/stylesheets/common/admin/admin_report_counters.scss @@ -0,0 +1,122 @@ +.admin-report-counters-list { + display: flex; + flex: 1; + flex-direction: column; + + .counters-header { + display: grid; + flex: 1; + grid-template-columns: 33% repeat(auto-fit, minmax(20px, 1fr)); + border: 1px solid $primary-low; + border-bottom: 0; + padding: 0.25em; + font-weight: 700; + text-align: right; + } + + .conditional-loading-section.is-loading { + padding: 0.5em; + margin: 0; + flex-direction: row; + justify-content: flex-start; + + .title { + font-weight: normal; + font-size: $font-down-1; + } + + .spinner { + margin: 0 0 0 0.5em; + height: 5px; + width: 5px; + } + } +} + +.admin-report.counters { + &:last-child .admin-report-counters { + border-bottom: 1px solid $primary-low; + } + + .admin-report-counters { + display: grid; + flex: 1; + grid-template-columns: 33% repeat(auto-fit, minmax(20px, 1fr)); + grid-template-rows: repeat(auto-fit, minmax(32px, 1fr)); + border: 1px solid $primary-low; + align-items: center; + border-bottom: 0; + + .cell { + padding: 0.25em; + text-align: right; + white-space: nowrap; + padding: 8px 21px 8px 8px; // accounting for negative right caret margin + &:nth-of-type(2) { + padding: 8px 12px 8px; + } + i { + margin-right: -12px; // align on caret + @media screen and (max-width: 650px) { + margin-right: -9px; + } + } + + &.title { + text-align: left; + padding: 8px; + + .d-icon { + color: $primary-low-mid; + min-width: 14px; + text-align: center; + } + + i { + margin: 0; + } + } + + @media screen and (max-width: 400px) { + &.title { + padding: 8px 0 8px 4px; + font-size: $font-down-1; + + .d-icon { + display: none; + } + } + } + + &.high-trending-up, + &.trending-up { + i { + color: $success; + } + } + &.high-trending-down, + &.trending-down { + i { + color: $danger; + } + } + } + } + + .no-data { + margin: 0; + padding: 8px; + display: flex; + flex-direction: row; + align-items: center; + font-size: $font-0; + border: 0; + background: $primary-low; + color: $primary-medium; + .d-icon { + font-size: $font-up-1; + margin: 0 0.25em 0 0; + color: $primary-low-mid; + } + } +} diff --git a/app/assets/stylesheets/common/admin/dashboard_next.scss b/app/assets/stylesheets/common/admin/dashboard_next.scss index aa9e1564474..1f53e3662cf 100644 --- a/app/assets/stylesheets/common/admin/dashboard_next.scss +++ b/app/assets/stylesheets/common/admin/dashboard_next.scss @@ -262,6 +262,10 @@ } } +.activity-metrics { + margin-bottom: 1em; +} + .user-metrics { display: flex; flex-wrap: wrap; @@ -330,85 +334,6 @@ } } -.admin-report.activity-metrics { - .report-table { - @media screen and (min-width: 400px) { - table-layout: auto; - } - tr th { - text-align: right; - } - .d-icon { - color: $primary-low-mid; - min-width: 14px; - text-align: center; - } - @media screen and (max-width: 400px) { - .d-icon { - display: none; - } - td.title { - padding: 8px 0 8px 4px; - } - } - - tr { - td { - text-overflow: unset; - overflow: auto; - white-space: normal; - } - - td:first-child { - text-overflow: ellipsis; - overflow: hidden; - white-space: normal; - } - } - - td { - text-align: center; - padding: 8px; - } - - td.left { - text-align: left; - } - - td.title { - text-align: left; - } - - td.value { - text-align: right; - white-space: nowrap; - padding: 8px 21px 8px 8px; // accounting for negative right caret margin - &:nth-of-type(2) { - padding: 8px 12px 8px; - } - i { - margin-right: -12px; // align on caret - @media screen and (max-width: 650px) { - margin-right: -9px; - } - } - - &.high-trending-up, - &.trending-up { - i { - color: $success; - } - } - &.high-trending-down, - &.trending-down { - i { - color: $danger; - } - } - } - } -} - .rtl .dashboard-next { .section-column { &:last-child { @@ -422,17 +347,6 @@ } } - .dashboard-table table tbody tr { - td.title { - text-align: right; - } - - td.value i { - margin-right: 0; - margin-left: -12px; - } - } - .user-metrics .table-cell { margin: 0 0 5px 10px; } diff --git a/app/controllers/admin/dashboard_next_controller.rb b/app/controllers/admin/dashboard_next_controller.rb index a479e20175a..ff2c6f71807 100644 --- a/app/controllers/admin/dashboard_next_controller.rb +++ b/app/controllers/admin/dashboard_next_controller.rb @@ -11,8 +11,7 @@ class Admin::DashboardNextController < Admin::AdminController render json: data end - def moderation - end + def moderation; end def general data = AdminDashboardNextGeneralData.fetch_cached_stats diff --git a/app/models/admin_dashboard_next_general_data.rb b/app/models/admin_dashboard_next_general_data.rb index 2028392f3f0..5cff33db700 100644 --- a/app/models/admin_dashboard_next_general_data.rb +++ b/app/models/admin_dashboard_next_general_data.rb @@ -1,12 +1,6 @@ class AdminDashboardNextGeneralData < AdminDashboardNextData def reports @reports ||= %w{ - page_view_total_reqs - visits - time_to_first_response - likes - flags - user_to_user_private_messages_with_replies users_by_type users_by_trust_level } diff --git a/app/models/report.rb b/app/models/report.rb index d1fa4740cb5..7593f790b37 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -107,6 +107,7 @@ class Report group_filtering: self.group_filtering, modes: self.modes, }.tap do |json| + json[:icon] = self.icon if self.icon json[:error] = self.error if self.error json[:total] = self.total if self.total json[:prev_period] = self.prev_period if self.prev_period diff --git a/test/javascripts/fixtures/flags.js.es6 b/test/javascripts/fixtures/flags.js.es6 new file mode 100644 index 00000000000..ed72a10dbf4 --- /dev/null +++ b/test/javascripts/fixtures/flags.js.es6 @@ -0,0 +1,7 @@ +export default { + "/admin/reports/flags": { + report: { + report_key: "flags" + } + } +}; diff --git a/test/javascripts/fixtures/likes.js.es6 b/test/javascripts/fixtures/likes.js.es6 new file mode 100644 index 00000000000..5c4d7c4eff8 --- /dev/null +++ b/test/javascripts/fixtures/likes.js.es6 @@ -0,0 +1,7 @@ +export default { + "/admin/reports/likes": { + report: { + report_key: "likes" + } + } +}; diff --git a/test/javascripts/fixtures/page_view_total_reqs.js.es6 b/test/javascripts/fixtures/page_view_total_reqs.js.es6 new file mode 100644 index 00000000000..9ad51ed7864 --- /dev/null +++ b/test/javascripts/fixtures/page_view_total_reqs.js.es6 @@ -0,0 +1,7 @@ +export default { + "/admin/reports/page_view_total_reqs": { + report: { + report_key: "page_view_total_reqs" + } + } +}; diff --git a/test/javascripts/fixtures/time_to_first_response.js.es6 b/test/javascripts/fixtures/time_to_first_response.js.es6 new file mode 100644 index 00000000000..5d7135f38a8 --- /dev/null +++ b/test/javascripts/fixtures/time_to_first_response.js.es6 @@ -0,0 +1,7 @@ +export default { + "/admin/reports/time_to_first_response": { + report: { + report_key: "time_to_first_response" + } + } +}; diff --git a/test/javascripts/fixtures/user_to_user_private_messages_with_replies.js.es6 b/test/javascripts/fixtures/user_to_user_private_messages_with_replies.js.es6 new file mode 100644 index 00000000000..2030d982a1f --- /dev/null +++ b/test/javascripts/fixtures/user_to_user_private_messages_with_replies.js.es6 @@ -0,0 +1,7 @@ +export default { + "/admin/reports/user_to_user_private_messages_with_replies": { + report: { + report_key: "user_to_user_private_messages_with_replies" + } + } +}; diff --git a/test/javascripts/fixtures/visits.js.es6 b/test/javascripts/fixtures/visits.js.es6 new file mode 100644 index 00000000000..de7937e2cff --- /dev/null +++ b/test/javascripts/fixtures/visits.js.es6 @@ -0,0 +1,7 @@ +export default { + "/admin/reports/visits": { + report: { + report_key: "posts" + } + } +};