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:
Arpit Jalan 2023-09-29 14:44:17 +05:30 committed by GitHub
parent 48e3d5b409
commit b39f823fd3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 123 additions and 14 deletions

View File

@ -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>

View File

@ -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();
}
}

View File

@ -1,4 +1,4 @@
import { computed } from "@ember/object";
import { action, computed } from "@ember/object";
import Controller, { inject as controller } from "@ember/controller";
import AdminDashboard from "admin/models/admin-dashboard";
import I18n from "I18n";
@ -9,6 +9,7 @@ import getURL from "discourse-common/lib/get-url";
import { makeArray } from "discourse-common/lib/helpers";
import { setting } from "discourse/lib/computed";
import { inject as service } from "@ember/service";
import CustomDateRangeModal from "../components/modal/custom-date-range";
function staticReport(reportType) {
return computed("reports.[]", function () {
@ -19,6 +20,7 @@ function staticReport(reportType) {
export default class AdminDashboardGeneralController extends Controller.extend(
PeriodComputationMixin
) {
@service modal;
@service router;
@service siteSettings;
@controller("exception") exceptionController;
@ -154,4 +156,20 @@ export default class AdminDashboardGeneralController extends Controller.extend(
_reportsForPeriodURL(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,
},
});
}
}

View File

@ -1,12 +1,16 @@
import { computed } from "@ember/object";
import { action, computed } from "@ember/object";
import Controller from "@ember/controller";
import PeriodComputationMixin from "admin/mixins/period-computation";
import discourseComputed from "discourse-common/utils/decorators";
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(
PeriodComputationMixin
) {
@service modal;
@discourseComputed
flagsStatusOptions() {
return {
@ -48,4 +52,20 @@ export default class AdminDashboardModerationController extends Controller.exten
_reportsForPeriodURL(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,
},
});
}
}

View File

@ -12,12 +12,20 @@
{{i18n "admin.dashboard.community_health"}}
</a>
</h2>
<PeriodChooser
@period={{this.period}}
@action={{action "changePeriod"}}
@content={{this.availablePeriods}}
@fullDay={{false}}
/>
<span>
<PeriodChooser
@period={{this.period}}
@action={{action "changePeriod"}}
@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 class="section-body">

View File

@ -14,12 +14,20 @@
{{i18n "admin.dashboard.moderators_activity"}}
</a>
</h2>
<PeriodChooser
@period={{this.period}}
@action={{action "changePeriod"}}
@content={{this.availablePeriods}}
@fullDay={{false}}
/>
<span>
<PeriodChooser
@period={{this.period}}
@action={{action "changePeriod"}}
@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 class="section-body">

View File

@ -48,6 +48,7 @@ acceptance("Dashboard", function (needs) {
test("general tab", async function (assert) {
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.posts"), "posts 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) {
await visit("/admin");

View File

@ -4677,6 +4677,7 @@ en:
too_many_requests: Youve performed this action too many times. Please wait before trying again.
not_found_error: Sorry, this report doesnt exist
filter_reports: Filter reports
custom_date_range: Custom date range
reports:
trend_title: "%{percent} change. Currently %{current}, was %{prev} in previous period."