FEATURE: add custom date range filter for admin dashboard reports (#23702)
* FEATURE: add custom date range filter for admin dashboard reports * Improvements per David's review
This commit is contained in:
parent
48e3d5b409
commit
b39f823fd3
|
@ -0,0 +1,22 @@
|
||||||
|
<DModal
|
||||||
|
class="custom-date-range-modal"
|
||||||
|
@title={{i18n "admin.dashboard.reports.dates"}}
|
||||||
|
@closeModal={{@closeModal}}
|
||||||
|
>
|
||||||
|
<:body>
|
||||||
|
<DateTimeInputRange
|
||||||
|
@from={{this.startDate}}
|
||||||
|
@to={{this.endDate}}
|
||||||
|
@onChange={{this.onChangeDateRange}}
|
||||||
|
@showFromTime={{false}}
|
||||||
|
@showToTime={{false}}
|
||||||
|
/>
|
||||||
|
</:body>
|
||||||
|
<:footer>
|
||||||
|
<DButton
|
||||||
|
@action={{this.updateDateRange}}
|
||||||
|
@label="admin.dashboard.reports.refresh_report"
|
||||||
|
@icon="sync"
|
||||||
|
/>
|
||||||
|
</:footer>
|
||||||
|
</DModal>
|
|
@ -0,0 +1,20 @@
|
||||||
|
import Component from "@glimmer/component";
|
||||||
|
import { action } from "@ember/object";
|
||||||
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
|
||||||
|
export default class CustomDateRange extends Component {
|
||||||
|
@tracked startDate = this.args.model.startDate;
|
||||||
|
@tracked endDate = this.args.model.endDate;
|
||||||
|
|
||||||
|
@action
|
||||||
|
onChangeDateRange(range) {
|
||||||
|
this.startDate = range.from;
|
||||||
|
this.endDate = range.to;
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
updateDateRange() {
|
||||||
|
this.args.model.setCustomDateRange(this.startDate, this.endDate);
|
||||||
|
this.args.closeModal();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import { computed } from "@ember/object";
|
import { action, computed } from "@ember/object";
|
||||||
import Controller, { inject as controller } from "@ember/controller";
|
import Controller, { inject as controller } from "@ember/controller";
|
||||||
import AdminDashboard from "admin/models/admin-dashboard";
|
import AdminDashboard from "admin/models/admin-dashboard";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
|
@ -9,6 +9,7 @@ import getURL from "discourse-common/lib/get-url";
|
||||||
import { makeArray } from "discourse-common/lib/helpers";
|
import { makeArray } from "discourse-common/lib/helpers";
|
||||||
import { setting } from "discourse/lib/computed";
|
import { setting } from "discourse/lib/computed";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
import CustomDateRangeModal from "../components/modal/custom-date-range";
|
||||||
|
|
||||||
function staticReport(reportType) {
|
function staticReport(reportType) {
|
||||||
return computed("reports.[]", function () {
|
return computed("reports.[]", function () {
|
||||||
|
@ -19,6 +20,7 @@ function staticReport(reportType) {
|
||||||
export default class AdminDashboardGeneralController extends Controller.extend(
|
export default class AdminDashboardGeneralController extends Controller.extend(
|
||||||
PeriodComputationMixin
|
PeriodComputationMixin
|
||||||
) {
|
) {
|
||||||
|
@service modal;
|
||||||
@service router;
|
@service router;
|
||||||
@service siteSettings;
|
@service siteSettings;
|
||||||
@controller("exception") exceptionController;
|
@controller("exception") exceptionController;
|
||||||
|
@ -154,4 +156,20 @@ export default class AdminDashboardGeneralController extends Controller.extend(
|
||||||
_reportsForPeriodURL(period) {
|
_reportsForPeriodURL(period) {
|
||||||
return getURL(`/admin?period=${period}`);
|
return getURL(`/admin?period=${period}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
setCustomDateRange(startDate, endDate) {
|
||||||
|
this.setProperties({ startDate, endDate });
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
openCustomDateRangeModal() {
|
||||||
|
this.modal.show(CustomDateRangeModal, {
|
||||||
|
model: {
|
||||||
|
startDate: this.startDate,
|
||||||
|
endDate: this.endDate,
|
||||||
|
setCustomDateRange: this.setCustomDateRange,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
import { computed } from "@ember/object";
|
import { action, computed } from "@ember/object";
|
||||||
import Controller from "@ember/controller";
|
import Controller from "@ember/controller";
|
||||||
import PeriodComputationMixin from "admin/mixins/period-computation";
|
import PeriodComputationMixin from "admin/mixins/period-computation";
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
import getURL from "discourse-common/lib/get-url";
|
import getURL from "discourse-common/lib/get-url";
|
||||||
|
import { inject as service } from "@ember/service";
|
||||||
|
import CustomDateRangeModal from "../components/modal/custom-date-range";
|
||||||
|
|
||||||
export default class AdminDashboardModerationController extends Controller.extend(
|
export default class AdminDashboardModerationController extends Controller.extend(
|
||||||
PeriodComputationMixin
|
PeriodComputationMixin
|
||||||
) {
|
) {
|
||||||
|
@service modal;
|
||||||
|
|
||||||
@discourseComputed
|
@discourseComputed
|
||||||
flagsStatusOptions() {
|
flagsStatusOptions() {
|
||||||
return {
|
return {
|
||||||
|
@ -48,4 +52,20 @@ export default class AdminDashboardModerationController extends Controller.exten
|
||||||
_reportsForPeriodURL(period) {
|
_reportsForPeriodURL(period) {
|
||||||
return getURL(`/admin/dashboard/moderation?period=${period}`);
|
return getURL(`/admin/dashboard/moderation?period=${period}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
setCustomDateRange(startDate, endDate) {
|
||||||
|
this.setProperties({ startDate, endDate });
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
openCustomDateRangeModal() {
|
||||||
|
this.modal.show(CustomDateRangeModal, {
|
||||||
|
model: {
|
||||||
|
startDate: this.startDate,
|
||||||
|
endDate: this.endDate,
|
||||||
|
setCustomDateRange: this.setCustomDateRange,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,20 @@
|
||||||
{{i18n "admin.dashboard.community_health"}}
|
{{i18n "admin.dashboard.community_health"}}
|
||||||
</a>
|
</a>
|
||||||
</h2>
|
</h2>
|
||||||
<PeriodChooser
|
<span>
|
||||||
@period={{this.period}}
|
<PeriodChooser
|
||||||
@action={{action "changePeriod"}}
|
@period={{this.period}}
|
||||||
@content={{this.availablePeriods}}
|
@action={{action "changePeriod"}}
|
||||||
@fullDay={{false}}
|
@content={{this.availablePeriods}}
|
||||||
/>
|
@fullDay={{false}}
|
||||||
|
/>
|
||||||
|
<DButton
|
||||||
|
@icon="cog"
|
||||||
|
class="custom-date-range-button"
|
||||||
|
@action={{this.openCustomDateRangeModal}}
|
||||||
|
@title="admin.dashboard.custom_date_range"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section-body">
|
<div class="section-body">
|
||||||
|
|
|
@ -14,12 +14,20 @@
|
||||||
{{i18n "admin.dashboard.moderators_activity"}}
|
{{i18n "admin.dashboard.moderators_activity"}}
|
||||||
</a>
|
</a>
|
||||||
</h2>
|
</h2>
|
||||||
<PeriodChooser
|
<span>
|
||||||
@period={{this.period}}
|
<PeriodChooser
|
||||||
@action={{action "changePeriod"}}
|
@period={{this.period}}
|
||||||
@content={{this.availablePeriods}}
|
@action={{action "changePeriod"}}
|
||||||
@fullDay={{false}}
|
@content={{this.availablePeriods}}
|
||||||
/>
|
@fullDay={{false}}
|
||||||
|
/>
|
||||||
|
<DButton
|
||||||
|
@icon="cog"
|
||||||
|
class="custom-date-range-button"
|
||||||
|
@action={{this.openCustomDateRangeModal}}
|
||||||
|
@title="admin.dashboard.custom_date_range"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section-body">
|
<div class="section-body">
|
||||||
|
|
|
@ -48,6 +48,7 @@ acceptance("Dashboard", function (needs) {
|
||||||
test("general tab", async function (assert) {
|
test("general tab", async function (assert) {
|
||||||
await visit("/admin");
|
await visit("/admin");
|
||||||
|
|
||||||
|
assert.ok(exists(".custom-date-range-button"), "custom date range button");
|
||||||
assert.ok(exists(".admin-report.signups"), "signups report");
|
assert.ok(exists(".admin-report.signups"), "signups report");
|
||||||
assert.ok(exists(".admin-report.posts"), "posts report");
|
assert.ok(exists(".admin-report.posts"), "posts report");
|
||||||
assert.ok(exists(".admin-report.dau-by-mau"), "dau-by-mau report");
|
assert.ok(exists(".admin-report.dau-by-mau"), "dau-by-mau report");
|
||||||
|
@ -68,6 +69,17 @@ acceptance("Dashboard", function (needs) {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("moderation tab", async function (assert) {
|
||||||
|
await visit("/admin");
|
||||||
|
await click(".dashboard .navigation-item.moderation .navigation-link");
|
||||||
|
|
||||||
|
assert.ok(exists(".custom-date-range-button"), "custom date range button");
|
||||||
|
assert.ok(
|
||||||
|
exists(".admin-report.moderators-activity"),
|
||||||
|
"moderators activity report"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test("activity metrics", async function (assert) {
|
test("activity metrics", async function (assert) {
|
||||||
await visit("/admin");
|
await visit("/admin");
|
||||||
|
|
||||||
|
|
|
@ -4677,6 +4677,7 @@ en:
|
||||||
too_many_requests: You’ve performed this action too many times. Please wait before trying again.
|
too_many_requests: You’ve performed this action too many times. Please wait before trying again.
|
||||||
not_found_error: Sorry, this report doesn’t exist
|
not_found_error: Sorry, this report doesn’t exist
|
||||||
filter_reports: Filter reports
|
filter_reports: Filter reports
|
||||||
|
custom_date_range: Custom date range
|
||||||
|
|
||||||
reports:
|
reports:
|
||||||
trend_title: "%{percent} change. Currently %{current}, was %{prev} in previous period."
|
trend_title: "%{percent} change. Currently %{current}, was %{prev} in previous period."
|
||||||
|
|
Loading…
Reference in New Issue