DEV: removes old dashboard (#7295)
This commit is contained in:
parent
d81f3ee2c2
commit
e986e96227
|
@ -1,6 +1,6 @@
|
|||
import { setting } from "discourse/lib/computed";
|
||||
import computed from "ember-addons/ember-computed-decorators";
|
||||
import AdminDashboardNext from "admin/models/admin-dashboard-next";
|
||||
import AdminDashboard from "admin/models/admin-dashboard";
|
||||
import Report from "admin/models/report";
|
||||
import PeriodComputationMixin from "admin/mixins/period-computation";
|
||||
|
||||
|
@ -88,12 +88,12 @@ export default Ember.Controller.extend(PeriodComputationMixin, {
|
|||
) {
|
||||
this.set("isLoading", true);
|
||||
|
||||
AdminDashboardNext.fetchGeneral()
|
||||
.then(adminDashboardNextModel => {
|
||||
AdminDashboard.fetchGeneral()
|
||||
.then(adminDashboardModel => {
|
||||
this.setProperties({
|
||||
dashboardFetchedAt: new Date(),
|
||||
model: adminDashboardNextModel,
|
||||
reports: Ember.makeArray(adminDashboardNextModel.reports).map(x =>
|
||||
model: adminDashboardModel,
|
||||
reports: Ember.makeArray(adminDashboardModel.reports).map(x =>
|
||||
Report.create(x)
|
||||
)
|
||||
});
|
|
@ -1,90 +0,0 @@
|
|||
import { setting } from "discourse/lib/computed";
|
||||
import computed from "ember-addons/ember-computed-decorators";
|
||||
import AdminDashboardNext from "admin/models/admin-dashboard-next";
|
||||
import VersionCheck from "admin/models/version-check";
|
||||
|
||||
const PROBLEMS_CHECK_MINUTES = 1;
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
isLoading: false,
|
||||
dashboardFetchedAt: null,
|
||||
exceptionController: Ember.inject.controller("exception"),
|
||||
showVersionChecks: setting("version_checks"),
|
||||
|
||||
@computed("problems.length")
|
||||
foundProblems(problemsLength) {
|
||||
return this.currentUser.get("admin") && (problemsLength || 0) > 0;
|
||||
},
|
||||
|
||||
fetchProblems() {
|
||||
if (this.get("isLoadingProblems")) return;
|
||||
|
||||
if (
|
||||
!this.get("problemsFetchedAt") ||
|
||||
moment()
|
||||
.subtract(PROBLEMS_CHECK_MINUTES, "minutes")
|
||||
.toDate() > this.get("problemsFetchedAt")
|
||||
) {
|
||||
this._loadProblems();
|
||||
}
|
||||
},
|
||||
|
||||
fetchDashboard() {
|
||||
const versionChecks = this.siteSettings.version_checks;
|
||||
|
||||
if (this.get("isLoading") || !versionChecks) return;
|
||||
|
||||
if (
|
||||
!this.get("dashboardFetchedAt") ||
|
||||
moment()
|
||||
.subtract(30, "minutes")
|
||||
.toDate() > this.get("dashboardFetchedAt")
|
||||
) {
|
||||
this.set("isLoading", true);
|
||||
|
||||
AdminDashboardNext.fetch()
|
||||
.then(model => {
|
||||
let properties = {
|
||||
dashboardFetchedAt: new Date()
|
||||
};
|
||||
|
||||
if (versionChecks) {
|
||||
properties.versionCheck = VersionCheck.create(model.version_check);
|
||||
}
|
||||
|
||||
this.setProperties(properties);
|
||||
})
|
||||
.catch(e => {
|
||||
this.get("exceptionController").set("thrown", e.jqXHR);
|
||||
this.replaceRoute("exception");
|
||||
})
|
||||
.finally(() => {
|
||||
this.set("isLoading", false);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_loadProblems() {
|
||||
this.setProperties({
|
||||
loadingProblems: true,
|
||||
problemsFetchedAt: new Date()
|
||||
});
|
||||
|
||||
AdminDashboardNext.fetchProblems()
|
||||
.then(model => this.set("problems", model.problems))
|
||||
.finally(() => this.set("loadingProblems", false));
|
||||
},
|
||||
|
||||
@computed("problemsFetchedAt")
|
||||
problemsTimestamp(problemsFetchedAt) {
|
||||
return moment(problemsFetchedAt)
|
||||
.locale("en")
|
||||
.format("LLL");
|
||||
},
|
||||
|
||||
actions: {
|
||||
refreshProblems() {
|
||||
this._loadProblems();
|
||||
}
|
||||
}
|
||||
});
|
|
@ -1,78 +1,90 @@
|
|||
import AdminDashboard from "admin/models/admin-dashboard";
|
||||
import Report from "admin/models/report";
|
||||
import AdminUser from "admin/models/admin-user";
|
||||
import { setting } from "discourse/lib/computed";
|
||||
import computed from "ember-addons/ember-computed-decorators";
|
||||
import AdminDashboard from "admin/models/admin-dashboard";
|
||||
import VersionCheck from "admin/models/version-check";
|
||||
|
||||
const ATTRIBUTES = [
|
||||
"admins",
|
||||
"moderators",
|
||||
"silenced",
|
||||
"suspended",
|
||||
"top_traffic_sources",
|
||||
"top_referred_topics",
|
||||
"updated_at"
|
||||
];
|
||||
const PROBLEMS_CHECK_MINUTES = 1;
|
||||
|
||||
const REPORTS = [
|
||||
"global_reports",
|
||||
"page_view_reports",
|
||||
"private_message_reports",
|
||||
"http_reports",
|
||||
"user_reports",
|
||||
"mobile_reports"
|
||||
];
|
||||
|
||||
// This controller supports the default interface when you enter the admin section.
|
||||
export default Ember.Controller.extend({
|
||||
loading: null,
|
||||
versionCheck: null,
|
||||
isLoading: false,
|
||||
dashboardFetchedAt: null,
|
||||
exceptionController: Ember.inject.controller("exception"),
|
||||
showVersionChecks: setting("version_checks"),
|
||||
|
||||
@computed("problems.length")
|
||||
foundProblems(problemsLength) {
|
||||
return this.currentUser.get("admin") && (problemsLength || 0) > 0;
|
||||
},
|
||||
|
||||
fetchProblems() {
|
||||
if (this.get("isLoadingProblems")) return;
|
||||
|
||||
if (
|
||||
!this.get("problemsFetchedAt") ||
|
||||
moment()
|
||||
.subtract(PROBLEMS_CHECK_MINUTES, "minutes")
|
||||
.toDate() > this.get("problemsFetchedAt")
|
||||
) {
|
||||
this._loadProblems();
|
||||
}
|
||||
},
|
||||
|
||||
fetchDashboard() {
|
||||
const versionChecks = this.siteSettings.version_checks;
|
||||
|
||||
if (this.get("isLoading") || !versionChecks) return;
|
||||
|
||||
if (
|
||||
!this.get("dashboardFetchedAt") ||
|
||||
moment()
|
||||
.subtract(30, "minutes")
|
||||
.toDate() > this.get("dashboardFetchedAt")
|
||||
) {
|
||||
this.set("loading", true);
|
||||
AdminDashboard.find()
|
||||
.then(d => {
|
||||
this.set("dashboardFetchedAt", new Date());
|
||||
this.set("isLoading", true);
|
||||
|
||||
REPORTS.forEach(name =>
|
||||
this.set(name, d[name].map(r => Report.create(r)))
|
||||
);
|
||||
AdminDashboard.fetch()
|
||||
.then(model => {
|
||||
let properties = {
|
||||
dashboardFetchedAt: new Date()
|
||||
};
|
||||
|
||||
const topReferrers = d.top_referrers;
|
||||
if (topReferrers && topReferrers.data) {
|
||||
d.top_referrers.data = topReferrers.data.map(user =>
|
||||
AdminUser.create(user)
|
||||
);
|
||||
this.set("top_referrers", topReferrers);
|
||||
if (versionChecks) {
|
||||
properties.versionCheck = VersionCheck.create(model.version_check);
|
||||
}
|
||||
|
||||
ATTRIBUTES.forEach(a => this.set(a, d[a]));
|
||||
this.setProperties(properties);
|
||||
})
|
||||
.catch(e => {
|
||||
this.get("exceptionController").set("thrown", e.jqXHR);
|
||||
this.replaceRoute("exception");
|
||||
})
|
||||
.finally(() => {
|
||||
this.set("loading", false);
|
||||
this.set("isLoading", false);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@computed("updated_at")
|
||||
updatedTimestamp(updatedAt) {
|
||||
return moment(updatedAt).format("LLL");
|
||||
_loadProblems() {
|
||||
this.setProperties({
|
||||
loadingProblems: true,
|
||||
problemsFetchedAt: new Date()
|
||||
});
|
||||
|
||||
AdminDashboard.fetchProblems()
|
||||
.then(model => this.set("problems", model.problems))
|
||||
.finally(() => this.set("loadingProblems", false));
|
||||
},
|
||||
|
||||
@computed("problemsFetchedAt")
|
||||
problemsTimestamp(problemsFetchedAt) {
|
||||
return moment(problemsFetchedAt)
|
||||
.locale("en")
|
||||
.format("LLL");
|
||||
},
|
||||
|
||||
actions: {
|
||||
showTrafficReport() {
|
||||
this.set("showTrafficReport", true);
|
||||
refreshProblems() {
|
||||
this._loadProblems();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -15,7 +15,7 @@ export default Ember.Controller.extend({
|
|||
|
||||
@computed("application.currentPath")
|
||||
adminContentsClassName(currentPath) {
|
||||
return currentPath
|
||||
let cssClasses = currentPath
|
||||
.split(".")
|
||||
.filter(segment => {
|
||||
return (
|
||||
|
@ -27,5 +27,12 @@ export default Ember.Controller.extend({
|
|||
})
|
||||
.map(Ember.String.dasherize)
|
||||
.join(" ");
|
||||
|
||||
// this is done to avoid breaking css customizations
|
||||
if (cssClasses.includes("dashboard")) {
|
||||
cssClasses = `${cssClasses} dashboard-next`;
|
||||
}
|
||||
|
||||
return cssClasses;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
import { ajax } from "discourse/lib/ajax";
|
||||
|
||||
const GENERAL_ATTRIBUTES = ["updated_at"];
|
||||
|
||||
const AdminDashboardNext = Discourse.Model.extend({});
|
||||
|
||||
AdminDashboardNext.reopenClass({
|
||||
fetch() {
|
||||
return ajax("/admin/dashboard.json").then(json => {
|
||||
const model = AdminDashboardNext.create();
|
||||
model.set("version_check", json.version_check);
|
||||
return model;
|
||||
});
|
||||
},
|
||||
|
||||
fetchGeneral() {
|
||||
return ajax("/admin/dashboard/general.json").then(json => {
|
||||
const model = AdminDashboardNext.create();
|
||||
|
||||
const attributes = {};
|
||||
GENERAL_ATTRIBUTES.forEach(a => (attributes[a] = json[a]));
|
||||
|
||||
model.setProperties({
|
||||
reports: json.reports,
|
||||
attributes,
|
||||
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;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export default AdminDashboardNext;
|
|
@ -1,18 +1,38 @@
|
|||
import { ajax } from "discourse/lib/ajax";
|
||||
|
||||
const GENERAL_ATTRIBUTES = ["updated_at"];
|
||||
|
||||
const AdminDashboard = Discourse.Model.extend({});
|
||||
|
||||
AdminDashboard.reopenClass({
|
||||
/**
|
||||
Fetch all dashboard data. This can be an expensive request when the cached data
|
||||
has expired and the server must collect the data again.
|
||||
fetch() {
|
||||
return ajax("/admin/dashboard.json").then(json => {
|
||||
const model = AdminDashboard.create();
|
||||
model.set("version_check", json.version_check);
|
||||
return model;
|
||||
});
|
||||
},
|
||||
|
||||
@method find
|
||||
@return {jqXHR} a jQuery Promise object
|
||||
**/
|
||||
find: function() {
|
||||
return ajax("/admin/dashboard-old.json").then(function(json) {
|
||||
var model = AdminDashboard.create(json);
|
||||
fetchGeneral() {
|
||||
return ajax("/admin/dashboard/general.json").then(json => {
|
||||
const model = AdminDashboard.create();
|
||||
|
||||
const attributes = {};
|
||||
GENERAL_ATTRIBUTES.forEach(a => (attributes[a] = json[a]));
|
||||
|
||||
model.setProperties({
|
||||
reports: json.reports,
|
||||
attributes,
|
||||
loaded: true
|
||||
});
|
||||
|
||||
return model;
|
||||
});
|
||||
},
|
||||
|
||||
fetchProblems() {
|
||||
return ajax("/admin/dashboard/problems.json").then(json => {
|
||||
const model = AdminDashboard.create(json);
|
||||
model.set("loaded", true);
|
||||
return model;
|
||||
});
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
export default Discourse.Route.extend({
|
||||
activate() {
|
||||
this.controllerFor("admin-dashboard-general").fetchDashboard();
|
||||
}
|
||||
});
|
|
@ -1,5 +0,0 @@
|
|||
export default Discourse.Route.extend({
|
||||
activate() {
|
||||
this.controllerFor("admin-dashboard-next-general").fetchDashboard();
|
||||
}
|
||||
});
|
|
@ -1,9 +0,0 @@
|
|||
import { scrollTop } from "discourse/mixins/scroll-top";
|
||||
|
||||
export default Discourse.Route.extend({
|
||||
activate() {
|
||||
this.controllerFor("admin-dashboard-next").fetchProblems();
|
||||
this.controllerFor("admin-dashboard-next").fetchDashboard();
|
||||
scrollTop();
|
||||
}
|
||||
});
|
|
@ -1,5 +1,9 @@
|
|||
import { scrollTop } from "discourse/mixins/scroll-top";
|
||||
|
||||
export default Discourse.Route.extend({
|
||||
setupController(controller) {
|
||||
controller.fetchDashboard();
|
||||
activate() {
|
||||
this.controllerFor("admin-dashboard").fetchProblems();
|
||||
this.controllerFor("admin-dashboard").fetchDashboard();
|
||||
scrollTop();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export default Discourse.Route.extend({
|
||||
beforeModel() {
|
||||
this.transitionTo("admin.dashboardNextReports");
|
||||
this.transitionTo("admin.dashboardReports");
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
export default function() {
|
||||
this.route("admin", { resetNamespace: true }, function() {
|
||||
this.route("dashboard", { path: "/dashboard-old" });
|
||||
|
||||
this.route("dashboardNext", { path: "/" }, function() {
|
||||
this.route("dashboard", { path: "/" }, function() {
|
||||
this.route("general", { path: "/" });
|
||||
this.route("admin.dashboardNextModeration", {
|
||||
this.route("admin.dashboardModeration", {
|
||||
path: "/dashboard/moderation",
|
||||
resetNamespace: true
|
||||
});
|
||||
this.route("admin.dashboardNextSecurity", {
|
||||
this.route("admin.dashboardSecurity", {
|
||||
path: "/dashboard/security",
|
||||
resetNamespace: true
|
||||
});
|
||||
this.route("admin.dashboardNextReports", {
|
||||
this.route("admin.dashboardReports", {
|
||||
path: "/dashboard/reports",
|
||||
resetNamespace: true
|
||||
});
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
{{#admin-wrapper class="container"}}
|
||||
<div class="row">
|
||||
<div class="full-width">
|
||||
<div class="full-width">
|
||||
<div class="admin-main-nav">
|
||||
|
||||
<ul class="nav nav-pills">
|
||||
|
||||
{{nav-item route='admin.dashboardNext' label='admin.dashboard.title'}}
|
||||
{{nav-item route='admin.dashboard' label='admin.dashboard.title'}}
|
||||
{{#if currentUser.admin}}
|
||||
{{nav-item route='adminSiteSettings' label='admin.site_settings.title'}}
|
||||
{{/if}}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<ul class="breadcrumb">
|
||||
{{#if showAllReportsLink}}
|
||||
<li class="item all-reports">
|
||||
{{#link-to "admin.dashboardNextReports" class="report-url"}}
|
||||
{{#link-to "admin.dashboardReports" class="report-url"}}
|
||||
{{i18n "admin.dashboard.all_reports"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
|
|
|
@ -1,227 +1,38 @@
|
|||
{{#conditional-loading-spinner condition=loading}}
|
||||
<div class="alert alert-info">
|
||||
The old dashboard is going to be removed in Discourse 2.2
|
||||
</div>
|
||||
<div class="dashboard-left">
|
||||
<div class="dashboard-stats trust-levels">
|
||||
<table class="table table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th>0</th>
|
||||
<th>1</th>
|
||||
<th>2</th>
|
||||
<th>3</th>
|
||||
<th>4</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each user_reports as |r|}}
|
||||
{{admin-report-trust-level-counts report=r}}
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{plugin-outlet name="admin-dashboard-top"}}
|
||||
|
||||
<div class="dashboard-stats totals">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="title">{{d-icon "shield-alt"}} {{i18n 'admin.dashboard.admins'}}</td>
|
||||
<td class="value">{{#link-to 'adminUsersList.show' 'admins'}}{{admins}}{{/link-to}}</td>
|
||||
<td class="title">{{d-icon "ban"}} {{i18n 'admin.dashboard.suspended'}}</td>
|
||||
<td class="value">{{#link-to 'adminUsersList.show' 'suspended'}}{{suspended}}{{/link-to}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">{{d-icon "shield-alt"}} {{i18n 'admin.dashboard.moderators'}}</td>
|
||||
<td class="value">{{#link-to 'adminUsersList.show' 'moderators'}}{{moderators}}{{/link-to}}</td>
|
||||
<td class="title">{{d-icon "ban"}} {{i18n 'admin.dashboard.silenced'}}</td>
|
||||
<td class="value">{{#link-to 'adminUsersList.show' 'silenced'}}{{silenced}}{{/link-to}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="dashboard-stats">
|
||||
<table class="table table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th>{{i18n 'admin.dashboard.reports.today'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.yesterday'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.last_7_days'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.last_30_days'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.all'}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each global_reports as |r|}}
|
||||
{{admin-report-counts report=r}}
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="dashboard-stats">
|
||||
<table class="table table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="title" title="{{i18n 'admin.dashboard.page_views'}}">{{i18n 'admin.dashboard.page_views_short'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.today'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.yesterday'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.last_7_days'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.last_30_days'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.all'}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each page_view_reports as |r|}}
|
||||
{{admin-report-counts report=r}}
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="dashboard-stats">
|
||||
<table class="table table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="title" title="{{i18n 'admin.dashboard.private_messages_title'}}">{{d-icon "envelope"}} {{i18n 'admin.dashboard.private_messages_short'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.today'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.yesterday'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.last_7_days'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.last_30_days'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.all'}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each private_message_reports as |r|}}
|
||||
{{admin-report-counts report=r}}
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="dashboard-stats">
|
||||
<table class="table table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="title" title="{{i18n 'admin.dashboard.mobile_title'}}">{{i18n 'admin.dashboard.mobile_title'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.today'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.yesterday'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.last_7_days'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.last_30_days'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.all'}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each mobile_reports as |r|}}
|
||||
{{admin-report-counts report=r}}
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{#if showTrafficReport}}
|
||||
<div class="dashboard-stats">
|
||||
<table class="table table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="title" title="{{i18n 'admin.dashboard.traffic'}}">{{i18n 'admin.dashboard.traffic_short'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.today'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.yesterday'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.last_7_days'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.last_30_days'}}</th>
|
||||
<th>{{i18n 'admin.dashboard.reports.all'}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#unless loading}}
|
||||
{{#each http_reports as |r|}}
|
||||
{{admin-report-counts report=r}}
|
||||
{{/each}}
|
||||
{{/unless}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="dashboard-stats">
|
||||
<a href {{action 'showTrafficReport'}}>{{i18n 'admin.dashboard.show_traffic_report'}}</a>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="dashboard-right">
|
||||
<div class="dashboard-stats">
|
||||
<table class="table table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="title">{{top_referred_topics.title}} ({{i18n 'admin.dashboard.reports.last_30_days'}})</th>
|
||||
<th>{{top_referred_topics.ytitles.num_clicks}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{{#each top_referred_topics.data as |data|}}
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="title">
|
||||
<div class="referred-topic-title">
|
||||
<div class="overflow-ellipsis">
|
||||
<a href="{{unbound data.topic_url}}">{{data.topic_title}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="value">{{number data.num_clicks}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
{{/each}}
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="dashboard-stats">
|
||||
<table class="table table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="title">{{top_traffic_sources.title}} ({{i18n 'admin.dashboard.reports.last_30_days'}})</th>
|
||||
<th>{{top_traffic_sources.ytitles.num_clicks}}</th>
|
||||
<th>{{top_traffic_sources.ytitles.num_topics}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{{#each top_traffic_sources.data as |s|}}
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="title">{{s.domain}}</td>
|
||||
<td class="value">{{number s.num_clicks}}</td>
|
||||
<td class="value">{{number s.num_topics}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
{{/each}}
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="dashboard-stats">
|
||||
<table class="table table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="title">{{top_referrers.title}} ({{i18n 'admin.dashboard.reports.last_30_days'}})</th>
|
||||
<th>{{top_referrers.ytitles.num_clicks}}</th>
|
||||
<th>{{top_referrers.ytitles.num_topics}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{{#each top_referrers.data as |r|}}
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="title">{{#link-to 'adminUser' r.user_id r.username}}{{unbound r.username}}{{/link-to}}</td>
|
||||
<td class="value">{{number r.num_clicks}}</td>
|
||||
<td class="value">{{number r.num_topics}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
{{/each}}
|
||||
</table>
|
||||
{{#if showVersionChecks}}
|
||||
<div class="section-top">
|
||||
<div class="version-checks">
|
||||
{{partial "admin/templates/version-checks"}}
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearfix'></div>
|
||||
{{/if}}
|
||||
|
||||
<div class="dashboard-stats pull-right">
|
||||
<div class="pull-right">{{i18n 'admin.dashboard.last_updated'}} {{updatedTimestamp}}</div>
|
||||
<div class='clearfix'></div>
|
||||
</div>
|
||||
<div class='clearfix'></div>
|
||||
{{/conditional-loading-spinner}}
|
||||
{{partial "admin/templates/dashboard-problems"}}
|
||||
|
||||
<ul class="navigation">
|
||||
<li class="navigation-item general">
|
||||
{{#link-to "admin.dashboard.general" class="navigation-link"}}
|
||||
{{i18n "admin.dashboard.general_tab"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="navigation-item moderation">
|
||||
{{#link-to "admin.dashboardModeration" class="navigation-link"}}
|
||||
{{i18n "admin.dashboard.moderation_tab"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="navigation-item security">
|
||||
{{#link-to "admin.dashboardSecurity" class="navigation-link"}}
|
||||
{{i18n "admin.dashboard.security_tab"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="navigation-item reports">
|
||||
{{#link-to "admin.dashboardReports" class="navigation-link"}}
|
||||
{{i18n "admin.dashboard.reports_tab"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{{outlet}}
|
||||
|
||||
{{plugin-outlet name="admin-dashboard-bottom"}}
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
{{plugin-outlet name="admin-dashboard-top"}}
|
||||
|
||||
{{#if showVersionChecks}}
|
||||
<div class="section-top">
|
||||
<div class="version-checks">
|
||||
{{partial "admin/templates/version-checks"}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{partial "admin/templates/dashboard-problems"}}
|
||||
|
||||
<ul class="navigation">
|
||||
<li class="navigation-item general">
|
||||
{{#link-to "admin.dashboardNext.general" class="navigation-link"}}
|
||||
{{i18n "admin.dashboard.general_tab"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="navigation-item moderation">
|
||||
{{#link-to "admin.dashboardNextModeration" class="navigation-link"}}
|
||||
{{i18n "admin.dashboard.moderation_tab"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="navigation-item security">
|
||||
{{#link-to "admin.dashboardNextSecurity" class="navigation-link"}}
|
||||
{{i18n "admin.dashboard.security_tab"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="navigation-item reports">
|
||||
{{#link-to "admin.dashboardNextReports" class="navigation-link"}}
|
||||
{{i18n "admin.dashboard.reports_tab"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{{outlet}}
|
||||
|
||||
{{plugin-outlet name="admin-dashboard-bottom"}}
|
|
@ -961,7 +961,7 @@ table#user-badges {
|
|||
}
|
||||
|
||||
// Styles for subtabs in admin
|
||||
@import "common/admin/dashboard_next";
|
||||
@import "common/admin/dashboard";
|
||||
@import "common/admin/settings";
|
||||
@import "common/admin/users";
|
||||
@import "common/admin/suspend";
|
||||
|
@ -980,4 +980,3 @@ table#user-badges {
|
|||
@import "common/admin/admin_report_stacked_chart";
|
||||
@import "common/admin/admin_report_table";
|
||||
@import "common/admin/admin_report_inline_table";
|
||||
@import "common/admin/dashboard_previous";
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
.admin-reports,
|
||||
.dashboard,
|
||||
.dashboard-next {
|
||||
&.admin-contents {
|
||||
margin: 10px 0 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.dashboard,
|
||||
.dashboard-next {
|
||||
.section-top {
|
||||
margin-bottom: 0.5em;
|
||||
|
@ -35,15 +37,15 @@
|
|||
}
|
||||
}
|
||||
|
||||
&.dashboard-next-moderation .navigation-item.moderation {
|
||||
&.dashboard-moderation .navigation-item.moderation {
|
||||
@include active-navigation-item;
|
||||
}
|
||||
|
||||
&.dashboard-next-security .navigation-item.security {
|
||||
&.dashboard-security .navigation-item.security {
|
||||
@include active-navigation-item;
|
||||
}
|
||||
|
||||
&.dashboard-next-reports .navigation-item.reports {
|
||||
&.dashboard-reports .navigation-item.reports {
|
||||
@include active-navigation-item;
|
||||
}
|
||||
|
||||
|
@ -508,8 +510,8 @@
|
|||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
.dashboard-next-moderation,
|
||||
.dashboard-next-security {
|
||||
.dashboard-moderation,
|
||||
.dashboard-security {
|
||||
.section-body {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
@ -538,7 +540,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.dashboard-next-moderation {
|
||||
.dashboard-moderation {
|
||||
.admin-dashboard-moderation-top {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(12, 1fr);
|
||||
|
@ -547,7 +549,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.dashboard-next-reports {
|
||||
.dashboard-reports {
|
||||
.reports-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
@ -576,3 +578,96 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.version-checks {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.section-title {
|
||||
flex: 1 1 100%;
|
||||
border-bottom: 1px solid $primary-low;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.version-check {
|
||||
display: flex;
|
||||
flex: 1 1 50%;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-start;
|
||||
align-self: flex-start;
|
||||
justify-content: space-between;
|
||||
padding: 10px 0 10px 0;
|
||||
.upgrade-header {
|
||||
flex: 1 1 100%;
|
||||
@media screen and (max-width: 650px) {
|
||||
margin: 0;
|
||||
}
|
||||
tr {
|
||||
border: none;
|
||||
}
|
||||
th {
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
h2 {
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
.version-number {
|
||||
font-size: $font-up-2;
|
||||
line-height: $line-height-medium;
|
||||
box-sizing: border-box;
|
||||
font-weight: bold;
|
||||
margin: 0 0 1em 0;
|
||||
padding-right: 20px;
|
||||
flex: 1 1 27%;
|
||||
h3 {
|
||||
flex: 1 0 auto;
|
||||
white-space: nowrap;
|
||||
}
|
||||
h4 {
|
||||
font-size: $font-down-2;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
.version-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 0 1em 0;
|
||||
flex: 1 1 24%;
|
||||
box-sizing: border-box;
|
||||
padding-right: 20px;
|
||||
min-width: 250px;
|
||||
@include breakpoint(medium) {
|
||||
max-width: unset;
|
||||
}
|
||||
.face {
|
||||
margin: 0 0.75em 0 0;
|
||||
font-size: $font-up-3;
|
||||
}
|
||||
}
|
||||
&.critical .version-notes .normal-note {
|
||||
display: none;
|
||||
}
|
||||
&.normal .version-notes .critical-note {
|
||||
display: none;
|
||||
}
|
||||
.fa {
|
||||
font-size: $font-up-4;
|
||||
}
|
||||
.up-to-date {
|
||||
color: $success;
|
||||
}
|
||||
.updates-available {
|
||||
color: $danger;
|
||||
}
|
||||
.critical-updates-available {
|
||||
color: $danger;
|
||||
}
|
||||
}
|
||||
|
||||
.update-nag {
|
||||
.d-icon {
|
||||
font-size: $font-up-3;
|
||||
}
|
||||
}
|
|
@ -1,268 +0,0 @@
|
|||
// Styles for admin/dashboard-old
|
||||
|
||||
.dashboard-left {
|
||||
float: left;
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.dashboard-right {
|
||||
float: right;
|
||||
width: 40%;
|
||||
.dashboard-stats {
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.version-checks {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.section-title {
|
||||
flex: 1 1 100%;
|
||||
border-bottom: 1px solid $primary-low;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.version-check {
|
||||
display: flex;
|
||||
flex: 1 1 50%;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-start;
|
||||
align-self: flex-start;
|
||||
justify-content: space-between;
|
||||
padding: 10px 0 10px 0;
|
||||
.upgrade-header {
|
||||
flex: 1 1 100%;
|
||||
@media screen and (max-width: 650px) {
|
||||
margin: 0;
|
||||
}
|
||||
tr {
|
||||
border: none;
|
||||
}
|
||||
th {
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
h2 {
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
.version-number {
|
||||
font-size: $font-up-2;
|
||||
line-height: $line-height-medium;
|
||||
box-sizing: border-box;
|
||||
font-weight: bold;
|
||||
margin: 0 0 1em 0;
|
||||
padding-right: 20px;
|
||||
flex: 1 1 27%;
|
||||
h3 {
|
||||
flex: 1 0 auto;
|
||||
white-space: nowrap;
|
||||
}
|
||||
h4 {
|
||||
font-size: $font-down-2;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
.version-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 0 1em 0;
|
||||
flex: 1 1 24%;
|
||||
box-sizing: border-box;
|
||||
padding-right: 20px;
|
||||
min-width: 250px;
|
||||
@include breakpoint(medium) {
|
||||
max-width: unset;
|
||||
}
|
||||
.face {
|
||||
margin: 0 0.75em 0 0;
|
||||
font-size: $font-up-3;
|
||||
}
|
||||
}
|
||||
&.critical .version-notes .normal-note {
|
||||
display: none;
|
||||
}
|
||||
&.normal .version-notes .critical-note {
|
||||
display: none;
|
||||
}
|
||||
.fa {
|
||||
font-size: $font-up-4;
|
||||
}
|
||||
.up-to-date {
|
||||
color: $success;
|
||||
}
|
||||
.updates-available {
|
||||
color: $danger;
|
||||
}
|
||||
.critical-updates-available {
|
||||
color: $danger;
|
||||
}
|
||||
}
|
||||
|
||||
.update-nag {
|
||||
.d-icon {
|
||||
font-size: $font-up-3;
|
||||
}
|
||||
}
|
||||
|
||||
.dashboard-stats {
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 30px;
|
||||
flex: 1 1 50%;
|
||||
box-sizing: border-box;
|
||||
&.version-check {
|
||||
margin: 0;
|
||||
}
|
||||
&.detected-problems {
|
||||
border-left: 1px solid $primary-low;
|
||||
margin: 10px 0 0 0;
|
||||
padding-left: 20px;
|
||||
}
|
||||
h4 {
|
||||
font-weight: normal;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
@media screen and (max-width: 650px) {
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
.title {
|
||||
.d-icon {
|
||||
color: $primary;
|
||||
}
|
||||
.d-icon-heart {
|
||||
color: $love;
|
||||
}
|
||||
}
|
||||
th {
|
||||
text-align: center;
|
||||
background: $primary-low;
|
||||
}
|
||||
th.title {
|
||||
text-align: left;
|
||||
}
|
||||
thead {
|
||||
tr:hover > td {
|
||||
background-color: $secondary;
|
||||
}
|
||||
}
|
||||
td.value {
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
.d-icon {
|
||||
display: none;
|
||||
}
|
||||
&.high-trending-up,
|
||||
&.trending-up {
|
||||
.up {
|
||||
color: $success;
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
&.high-trending-down,
|
||||
&.trending-down {
|
||||
.down {
|
||||
color: $danger;
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
&.no-change {
|
||||
.down {
|
||||
display: inline;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
tr.reverse-colors {
|
||||
td.value.high-trending-down .down,
|
||||
td.value.trending-down .down {
|
||||
color: $success;
|
||||
}
|
||||
td.value.high-trending-up .up,
|
||||
td.value.trending-up .up {
|
||||
color: $danger;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.detected-problems {
|
||||
display: flex;
|
||||
margin-bottom: 30px;
|
||||
.look-here {
|
||||
margin: 10px 20px;
|
||||
.fa {
|
||||
font-size: $font-up-5;
|
||||
color: $danger;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 650px) {
|
||||
border-left: none;
|
||||
border-top: 1px solid $primary-low;
|
||||
padding: 20px 0 0 0;
|
||||
.look-here {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
h3 {
|
||||
display: flex;
|
||||
}
|
||||
.problem-messages {
|
||||
display: flex;
|
||||
a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.btn {
|
||||
background: $primary-low;
|
||||
}
|
||||
ul {
|
||||
margin-left: 0;
|
||||
padding-left: 90px;
|
||||
@media screen and (max-width: 650px) {
|
||||
padding-left: 20px;
|
||||
}
|
||||
li {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
p.actions {
|
||||
padding-left: 75px;
|
||||
@media screen and (max-width: 650px) {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&.totals {
|
||||
table {
|
||||
width: auto;
|
||||
}
|
||||
margin-top: 12px;
|
||||
padding-left: 5px;
|
||||
.value {
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
padding-left: 8px;
|
||||
padding-right: 30px;
|
||||
}
|
||||
}
|
||||
&.trust-levels {
|
||||
margin-bottom: 0;
|
||||
table {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
td.value {
|
||||
width: 45px;
|
||||
}
|
||||
}
|
||||
.referred-topic-title {
|
||||
width: 355px;
|
||||
@media all and (min-width: 1000px) and (max-width: 1139px) {
|
||||
width: 305px;
|
||||
}
|
||||
@include breakpoint(medium) {
|
||||
width: 265px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@
|
|||
@import "mobile/emoji";
|
||||
@import "mobile/ring";
|
||||
@import "mobile/group";
|
||||
@import "mobile/dashboard_next";
|
||||
@import "mobile/dashboard";
|
||||
@import "mobile/admin_customize";
|
||||
@import "mobile/admin_reports";
|
||||
@import "mobile/admin_report";
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
.dashboard,
|
||||
.dashboard-next {
|
||||
.activity-metrics .counters-list {
|
||||
font-size: $font-down-1;
|
|
@ -1,8 +1,20 @@
|
|||
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?
|
||||
render json: dashboard_data
|
||||
data = AdminDashboardIndexData.fetch_cached_stats
|
||||
|
||||
if SiteSetting.version_checks?
|
||||
data.merge!(version_check: DiscourseUpdates.check_version.as_json)
|
||||
end
|
||||
|
||||
render json: data
|
||||
end
|
||||
|
||||
def moderation; end
|
||||
def security; end
|
||||
def reports; end
|
||||
|
||||
def general
|
||||
render json: AdminDashboardGeneralData.fetch_cached_stats
|
||||
end
|
||||
|
||||
def problems
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
class Admin::DashboardNextController < Admin::AdminController
|
||||
def index
|
||||
data = AdminDashboardNextIndexData.fetch_cached_stats
|
||||
|
||||
if SiteSetting.version_checks?
|
||||
data.merge!(version_check: DiscourseUpdates.check_version.as_json)
|
||||
end
|
||||
|
||||
render json: data
|
||||
end
|
||||
|
||||
def moderation; end
|
||||
def security; end
|
||||
def reports; end
|
||||
|
||||
def general
|
||||
render json: AdminDashboardNextGeneralData.fetch_cached_stats
|
||||
end
|
||||
end
|
|
@ -3,36 +3,29 @@ require_dependency 'mem_info'
|
|||
class AdminDashboardData
|
||||
include StatsCacheable
|
||||
|
||||
GLOBAL_REPORTS ||= [
|
||||
'visits',
|
||||
'signups',
|
||||
'profile_views',
|
||||
'topics',
|
||||
'posts',
|
||||
'time_to_first_response',
|
||||
'topics_with_no_response',
|
||||
'likes',
|
||||
'flags',
|
||||
'bookmarks',
|
||||
'emails',
|
||||
]
|
||||
def initialize(opts = {})
|
||||
@opts = opts
|
||||
end
|
||||
|
||||
PAGE_VIEW_REPORTS ||= ['page_view_total_reqs'] + ApplicationRequest.req_types.keys.select { |r| r =~ /^page_view_/ && r !~ /mobile/ }.map { |r| r + "_reqs" }
|
||||
def self.fetch_stats
|
||||
new.as_json
|
||||
end
|
||||
|
||||
PRIVATE_MESSAGE_REPORTS ||= [
|
||||
'user_to_user_private_messages',
|
||||
'user_to_user_private_messages_with_replies',
|
||||
'system_private_messages',
|
||||
'notify_moderators_private_messages',
|
||||
'notify_user_private_messages',
|
||||
'moderator_warning_private_messages',
|
||||
]
|
||||
def get_json
|
||||
{}
|
||||
end
|
||||
|
||||
HTTP_REPORTS ||= ApplicationRequest.req_types.keys.select { |r| r =~ /^http_/ }.map { |r| r + "_reqs" }.sort
|
||||
def as_json(_options = nil)
|
||||
@json ||= get_json
|
||||
end
|
||||
|
||||
USER_REPORTS ||= ['users_by_trust_level']
|
||||
def self.reports(source)
|
||||
source.map { |type| Report.find(type).as_json }
|
||||
end
|
||||
|
||||
MOBILE_REPORTS ||= ['mobile_visits'] + ApplicationRequest.req_types.keys.select { |r| r =~ /mobile/ }.map { |r| r + "_reqs" }
|
||||
def self.stats_cache_key
|
||||
"dashboard-data-#{Report::SCHEMA_VERSION}"
|
||||
end
|
||||
|
||||
def self.add_problem_check(*syms, &blk)
|
||||
@problem_syms.push(*syms) if syms
|
||||
|
@ -40,10 +33,6 @@ class AdminDashboardData
|
|||
end
|
||||
class << self; attr_reader :problem_syms, :problem_blocks, :problem_messages; end
|
||||
|
||||
def initialize(opts = {})
|
||||
@opts = opts
|
||||
end
|
||||
|
||||
def problems
|
||||
problems = []
|
||||
AdminDashboardData.problem_syms.each do |sym|
|
||||
|
@ -67,7 +56,7 @@ class AdminDashboardData
|
|||
end
|
||||
|
||||
def self.problems_started_key
|
||||
"dash-problems-started-at"
|
||||
'dash-problems-started-at'
|
||||
end
|
||||
|
||||
def self.set_problems_started
|
||||
|
@ -110,14 +99,6 @@ class AdminDashboardData
|
|||
end
|
||||
reset_problem_checks
|
||||
|
||||
def self.fetch_stats
|
||||
AdminDashboardData.new.as_json
|
||||
end
|
||||
|
||||
def self.stats_cache_key
|
||||
'dash-stats'
|
||||
end
|
||||
|
||||
def self.fetch_problems(opts = {})
|
||||
AdminDashboardData.new(opts).problems
|
||||
end
|
||||
|
@ -142,29 +123,6 @@ class AdminDashboardData
|
|||
"admin-problem:#{i18n_key}"
|
||||
end
|
||||
|
||||
def as_json(_options = nil)
|
||||
@json ||= {
|
||||
global_reports: AdminDashboardData.reports(GLOBAL_REPORTS),
|
||||
page_view_reports: AdminDashboardData.reports(PAGE_VIEW_REPORTS),
|
||||
private_message_reports: AdminDashboardData.reports(PRIVATE_MESSAGE_REPORTS),
|
||||
http_reports: AdminDashboardData.reports(HTTP_REPORTS),
|
||||
user_reports: AdminDashboardData.reports(USER_REPORTS),
|
||||
mobile_reports: AdminDashboardData.reports(MOBILE_REPORTS),
|
||||
admins: User.admins.count,
|
||||
moderators: User.moderators.count,
|
||||
suspended: User.suspended.count,
|
||||
silenced: User.silenced.count,
|
||||
top_referrers: IncomingLinksReport.find('top_referrers').as_json,
|
||||
top_traffic_sources: IncomingLinksReport.find('top_traffic_sources').as_json,
|
||||
top_referred_topics: IncomingLinksReport.find('top_referred_topics').as_json,
|
||||
updated_at: Time.zone.now.as_json
|
||||
}
|
||||
end
|
||||
|
||||
def self.reports(source)
|
||||
source.map { |type| Report.find(type).as_json }
|
||||
end
|
||||
|
||||
def rails_env_check
|
||||
I18n.t("dashboard.rails_env_warning", env: Rails.env) unless Rails.env.production?
|
||||
end
|
||||
|
@ -260,7 +218,7 @@ class AdminDashboardData
|
|||
|
||||
def missing_mailgun_api_key
|
||||
return unless SiteSetting.reply_by_email_enabled
|
||||
return unless ActionMailer::Base.smtp_settings[:address]["smtp.mailgun.org"]
|
||||
return unless ActionMailer::Base.smtp_settings[:address]['smtp.mailgun.org']
|
||||
return unless SiteSetting.mailgun_api_key.blank?
|
||||
I18n.t('dashboard.missing_mailgun_api_key')
|
||||
end
|
||||
|
@ -274,14 +232,14 @@ class AdminDashboardData
|
|||
old_themes = RemoteTheme.out_of_date_themes
|
||||
return unless old_themes.present?
|
||||
|
||||
themes_html_format(old_themes, "dashboard.out_of_date_themes")
|
||||
themes_html_format(old_themes, 'dashboard.out_of_date_themes')
|
||||
end
|
||||
|
||||
def unreachable_themes
|
||||
themes = RemoteTheme.unreachable_themes
|
||||
return unless themes.present?
|
||||
|
||||
themes_html_format(themes, "dashboard.unreachable_themes")
|
||||
themes_html_format(themes, 'dashboard.unreachable_themes')
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -291,8 +249,6 @@ class AdminDashboardData
|
|||
"<li><a href=\"/admin/customize/themes/#{id}\">#{CGI.escapeHTML(name)}</a></li>"
|
||||
end.join("\n")
|
||||
|
||||
message = I18n.t(i18n_key)
|
||||
message += "<ul>#{html}</ul>"
|
||||
message
|
||||
"#{I18n.t(i18n_key)}<ul>#{html}</ul>"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
class AdminDashboardNextGeneralData < AdminDashboardNextData
|
||||
class AdminDashboardGeneralData < AdminDashboardData
|
||||
def get_json
|
||||
{
|
||||
updated_at: Time.zone.now.as_json
|
|
@ -1,4 +1,4 @@
|
|||
class AdminDashboardNextIndexData < AdminDashboardNextData
|
||||
class AdminDashboardIndexData < AdminDashboardData
|
||||
def get_json
|
||||
{
|
||||
updated_at: Time.zone.now.as_json
|
|
@ -1,27 +0,0 @@
|
|||
class AdminDashboardNextData
|
||||
include StatsCacheable
|
||||
|
||||
def initialize(opts = {})
|
||||
@opts = opts
|
||||
end
|
||||
|
||||
def self.fetch_stats
|
||||
new.as_json
|
||||
end
|
||||
|
||||
def get_json
|
||||
{}
|
||||
end
|
||||
|
||||
def as_json(_options = nil)
|
||||
@json ||= get_json
|
||||
end
|
||||
|
||||
def self.reports(source)
|
||||
source.map { |type| Report.find(type).as_json }
|
||||
end
|
||||
|
||||
def self.stats_cache_key
|
||||
"dashboard-next-data-#{Report::SCHEMA_VERSION}"
|
||||
end
|
||||
end
|
|
@ -240,13 +240,11 @@ Discourse::Application.routes.draw do
|
|||
|
||||
get "version_check" => "versions#show"
|
||||
|
||||
get "dashboard" => "dashboard_next#index"
|
||||
get "dashboard/general" => "dashboard_next#general"
|
||||
get "dashboard/moderation" => "dashboard_next#moderation"
|
||||
get "dashboard/security" => "dashboard_next#security"
|
||||
get "dashboard/reports" => "dashboard_next#reports"
|
||||
|
||||
get "dashboard-old" => "dashboard#index"
|
||||
get "dashboard" => "dashboard#index"
|
||||
get "dashboard/general" => "dashboard#general"
|
||||
get "dashboard/moderation" => "dashboard#moderation"
|
||||
get "dashboard/security" => "dashboard#security"
|
||||
get "dashboard/reports" => "dashboard#reports"
|
||||
|
||||
resources :dashboard, only: [:index] do
|
||||
collection do
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { acceptance } from "helpers/qunit-helpers";
|
||||
|
||||
acceptance("Dashboard Next", {
|
||||
acceptance("Dashboard", {
|
||||
loggedIn: true,
|
||||
settings: {
|
||||
dashboard_general_tab_activity_metrics: "page_view_total_reqs"
|
||||
|
@ -9,22 +9,16 @@ acceptance("Dashboard Next", {
|
|||
|
||||
QUnit.test("Dashboard", async assert => {
|
||||
await visit("/admin");
|
||||
assert.ok(exists(".dashboard-next"), "has dashboard-next class");
|
||||
assert.ok(exists(".dashboard"), "has dashboard-next class");
|
||||
});
|
||||
|
||||
QUnit.test("tabs", async assert => {
|
||||
await visit("/admin");
|
||||
|
||||
assert.ok(exists(".dashboard-next .navigation-item.general"), "general tab");
|
||||
assert.ok(
|
||||
exists(".dashboard-next .navigation-item.moderation"),
|
||||
"moderation tab"
|
||||
);
|
||||
assert.ok(
|
||||
exists(".dashboard-next .navigation-item.security"),
|
||||
"security tab"
|
||||
);
|
||||
assert.ok(exists(".dashboard-next .navigation-item.reports"), "reports tab");
|
||||
assert.ok(exists(".dashboard .navigation-item.general"), "general tab");
|
||||
assert.ok(exists(".dashboard .navigation-item.moderation"), "moderation tab");
|
||||
assert.ok(exists(".dashboard .navigation-item.security"), "security tab");
|
||||
assert.ok(exists(".dashboard .navigation-item.reports"), "reports tab");
|
||||
});
|
||||
|
||||
QUnit.test("general tab", async assert => {
|
||||
|
@ -61,33 +55,33 @@ QUnit.test("general tab - activity metrics", async assert => {
|
|||
|
||||
QUnit.test("reports tab", async assert => {
|
||||
await visit("/admin");
|
||||
await click(".dashboard-next .navigation-item.reports .navigation-link");
|
||||
await click(".dashboard .navigation-item.reports .navigation-link");
|
||||
|
||||
assert.equal(
|
||||
find(".dashboard-next .reports-index.section .reports-list .report").length,
|
||||
find(".dashboard .reports-index.section .reports-list .report").length,
|
||||
1
|
||||
);
|
||||
|
||||
await fillIn(".dashboard-next .filter-reports-input", "flags");
|
||||
await fillIn(".dashboard .filter-reports-input", "flags");
|
||||
|
||||
assert.equal(
|
||||
find(".dashboard-next .reports-index.section .reports-list .report").length,
|
||||
find(".dashboard .reports-index.section .reports-list .report").length,
|
||||
0
|
||||
);
|
||||
|
||||
await click(".dashboard-next .navigation-item.security .navigation-link");
|
||||
await click(".dashboard-next .navigation-item.reports .navigation-link");
|
||||
await click(".dashboard .navigation-item.security .navigation-link");
|
||||
await click(".dashboard .navigation-item.reports .navigation-link");
|
||||
|
||||
assert.equal(
|
||||
find(".dashboard-next .reports-index.section .reports-list .report").length,
|
||||
find(".dashboard .reports-index.section .reports-list .report").length,
|
||||
1,
|
||||
"navigating back and forth resets filter"
|
||||
);
|
||||
|
||||
await fillIn(".dashboard-next .filter-reports-input", "activities");
|
||||
await fillIn(".dashboard .filter-reports-input", "activities");
|
||||
|
||||
assert.equal(
|
||||
find(".dashboard-next .reports-index.section .reports-list .report").length,
|
||||
find(".dashboard .reports-index.section .reports-list .report").length,
|
||||
1,
|
||||
"filter is case insensitive"
|
||||
);
|
Loading…
Reference in New Issue