diff --git a/app/assets/javascripts/admin/controllers/admin-reports.js.es6 b/app/assets/javascripts/admin/controllers/admin-reports-show.js.es6 similarity index 98% rename from app/assets/javascripts/admin/controllers/admin-reports.js.es6 rename to app/assets/javascripts/admin/controllers/admin-reports-show.js.es6 index c8d04a334a7..bd6ff8c49c8 100644 --- a/app/assets/javascripts/admin/controllers/admin-reports.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-reports-show.js.es6 @@ -4,7 +4,6 @@ import Report from "admin/models/report"; import computed from "ember-addons/ember-computed-decorators"; export default Ember.Controller.extend({ - classNames: ["admin-reports"], queryParams: ["mode", "start_date", "end_date", "category_id", "group_id"], viewMode: "graph", viewingTable: Em.computed.equal("viewMode", "table"), diff --git a/app/assets/javascripts/admin/routes/admin-reports-index.js.es6 b/app/assets/javascripts/admin/routes/admin-reports-index.js.es6 new file mode 100644 index 00000000000..da0bda906e0 --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-reports-index.js.es6 @@ -0,0 +1,13 @@ +import { ajax } from "discourse/lib/ajax"; + +export default Discourse.Route.extend({ + model() { + return ajax("/admin/reports").then(json => { + return json; + }); + }, + + setupController(controller, model) { + controller.setProperties({ model: model.reports }); + } +}); diff --git a/app/assets/javascripts/admin/routes/admin-reports.js.es6 b/app/assets/javascripts/admin/routes/admin-reports-show.js.es6 similarity index 93% rename from app/assets/javascripts/admin/routes/admin-reports.js.es6 rename to app/assets/javascripts/admin/routes/admin-reports-show.js.es6 index 93e7d771d65..9c485c41ef1 100644 --- a/app/assets/javascripts/admin/routes/admin-reports.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-reports-show.js.es6 @@ -19,7 +19,7 @@ export default Discourse.Route.extend({ ); }, - setupController: function(controller, model) { + setupController(controller, model) { controller.setProperties({ model: model, categoryId: model.get("category_id") || "all", 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 fa588888f80..2bf0591af98 100644 --- a/app/assets/javascripts/admin/routes/admin-route-map.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-route-map.js.es6 @@ -95,10 +95,13 @@ export default function() { } ); - this.route("adminReports", { - path: "/reports/:type", - resetNamespace: true - }); + this.route( + "adminReports", + { path: "/reports", resetNamespace: true }, + function() { + this.route("show", { path: ":type" }); + } + ); this.route( "adminFlags", diff --git a/app/assets/javascripts/admin/templates/dashboard_next.hbs b/app/assets/javascripts/admin/templates/dashboard_next.hbs index 4930c46bf00..f5470dfd7a8 100644 --- a/app/assets/javascripts/admin/templates/dashboard_next.hbs +++ b/app/assets/javascripts/admin/templates/dashboard_next.hbs @@ -79,6 +79,10 @@ {{/conditional-loading-section}} + {{#link-to "adminReports"}} + {{i18n "admin.dashboard.all_reports"}} + {{/link-to}} +
{{dashboard-inline-table dataSourceNames="users_by_type" lastRefreshedAt=lastRefreshedAt}} diff --git a/app/assets/javascripts/admin/templates/reports-index.hbs b/app/assets/javascripts/admin/templates/reports-index.hbs new file mode 100644 index 00000000000..0c88b789587 --- /dev/null +++ b/app/assets/javascripts/admin/templates/reports-index.hbs @@ -0,0 +1,17 @@ +

{{i18n "admin.reports.title"}}

+ + diff --git a/app/assets/javascripts/admin/templates/reports.hbs b/app/assets/javascripts/admin/templates/reports-show.hbs similarity index 93% rename from app/assets/javascripts/admin/templates/reports.hbs rename to app/assets/javascripts/admin/templates/reports-show.hbs index 26b5bfb4fe6..bfd8781989b 100644 --- a/app/assets/javascripts/admin/templates/reports.hbs +++ b/app/assets/javascripts/admin/templates/reports-show.hbs @@ -1,4 +1,12 @@ -

{{model.title}}

+

+ {{#link-to "adminReports"}} + {{i18n "admin.dashboard.all_reports"}} + {{/link-to}} + + | + + {{model.title}} +

{{#if model.description}}

{{model.description}}

diff --git a/app/assets/stylesheets/common/admin/admin_reports.scss b/app/assets/stylesheets/common/admin/admin_reports.scss index 26c54cccc89..88f6421ced1 100644 --- a/app/assets/stylesheets/common/admin/admin_reports.scss +++ b/app/assets/stylesheets/common/admin/admin_reports.scss @@ -5,6 +5,20 @@ padding-bottom: 0.5em; } + .reports-list { + list-style: none; + margin: 0; + + .report { + padding-bottom: 0.5em; + margin-bottom: 0.5em; + + .report-description { + margin: 0; + } + } + } + .report-container { display: flex; diff --git a/app/controllers/admin/reports_controller.rb b/app/controllers/admin/reports_controller.rb index d67ee854329..945283cab9a 100644 --- a/app/controllers/admin/reports_controller.rb +++ b/app/controllers/admin/reports_controller.rb @@ -1,6 +1,22 @@ require_dependency 'report' class Admin::ReportsController < Admin::AdminController + def index + reports_methods = Report.singleton_methods.grep(/^report_(?!about)/) + + reports = reports_methods.map do |name| + type = name.to_s.gsub('report_', '') + description = I18n.t("reports.#{type}.description", default: '') + + { + type: type, + title: I18n.t("reports.#{type}.title"), + description: description.presence ? description : nil, + } + end + + render_json_dump(reports: reports.sort_by { |report| report[:title] }) + end def show report_type = params[:type] diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index e53ccbffd6b..7442f5e7417 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -2711,6 +2711,9 @@ en: title: 'Discourse Admin' moderator: 'Moderator' + reports: + title: "List of available reports" + dashboard: title: "Dashboard" last_updated: "Dashboard last updated:" @@ -2749,6 +2752,7 @@ en: community_health: Community health whats_new_in_discourse: What’s new in Discourse? activity_metrics: Activity Metrics + all_reports: "All reports" reports: trend_title: "%{percent} change. Currently %{current}, was %{prev} in previous period." diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 68d86a50fd8..c01242e4af0 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -1012,7 +1012,7 @@ en: xaxis: "Day" yaxis: "Total" mobile_visits: - title: "User Visits" + title: "User Visits (mobile)" xaxis: "Day" yaxis: "Number of visits" web_crawlers: diff --git a/config/routes.rb b/config/routes.rb index b81b84283e8..030fd7aad2d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -74,6 +74,7 @@ Discourse::Application.routes.draw do end end + get "reports" => "reports#index" get "reports/:type" => "reports#show" resources :groups, constraints: AdminConstraint.new do diff --git a/test/javascripts/acceptance/reports-test.js.es6 b/test/javascripts/acceptance/reports-test.js.es6 new file mode 100644 index 00000000000..55f4030ae15 --- /dev/null +++ b/test/javascripts/acceptance/reports-test.js.es6 @@ -0,0 +1,31 @@ +import { acceptance } from "helpers/qunit-helpers"; + +acceptance("Reports", { + loggedIn: true +}); + +QUnit.test("Visit reports page", assert => { + visit("/admin/reports"); + + andThen(() => { + assert.equal($(".reports-list .report").length, 1); + + const $report = $(".reports-list .report:first-child"); + + assert.equal( + $report + .find(".report-title") + .html() + .trim(), + "My report" + ); + + assert.equal( + $report + .find(".report-description") + .html() + .trim(), + "List of my activities" + ); + }); +}); diff --git a/test/javascripts/fixtures/reports.js.es6 b/test/javascripts/fixtures/reports.js.es6 new file mode 100644 index 00000000000..5d818be8332 --- /dev/null +++ b/test/javascripts/fixtures/reports.js.es6 @@ -0,0 +1,11 @@ +export default { + "/admin/reports": { + reports: [ + { + title: "My report", + description: "List of my activities", + type: "my_report" + } + ] + } +};