FIX: quality/bugfix dashboard/reports pass (#6283)
This commit is contained in:
parent
010fe479cb
commit
37d4f27c44
|
@ -1,5 +1,4 @@
|
|||
import computed from "ember-addons/ember-computed-decorators";
|
||||
import { registerTooltip, unregisterTooltip } from "discourse/lib/tooltip";
|
||||
|
||||
const PAGES_LIMIT = 8;
|
||||
|
||||
|
@ -11,19 +10,6 @@ export default Ember.Component.extend({
|
|||
perPage: Ember.computed.alias("options.perPage"),
|
||||
page: 0,
|
||||
|
||||
didRender() {
|
||||
this._super(...arguments);
|
||||
|
||||
unregisterTooltip($(".text[data-tooltip]"));
|
||||
registerTooltip($(".text[data-tooltip]"));
|
||||
},
|
||||
|
||||
willDestroyElement() {
|
||||
this._super(...arguments);
|
||||
|
||||
unregisterTooltip($(".text[data-tooltip]"));
|
||||
},
|
||||
|
||||
@computed("model.computedLabels.length")
|
||||
twoColumns(labelsLength) {
|
||||
return labelsLength === 2;
|
||||
|
@ -52,7 +38,12 @@ export default Ember.Component.extend({
|
|||
|
||||
@computed("totalsForSampleRow", "model.computedLabels")
|
||||
totalsForSample(row, labels) {
|
||||
return labels.map(label => label.compute(row));
|
||||
return labels.map(label => {
|
||||
const computedLabel = label.compute(row);
|
||||
computedLabel.type = label.type;
|
||||
computedLabel.property = label.mainProperty;
|
||||
return computedLabel;
|
||||
});
|
||||
},
|
||||
|
||||
@computed("model.data", "model.computedLabels")
|
||||
|
@ -119,7 +110,7 @@ export default Ember.Component.extend({
|
|||
return {
|
||||
page: v + 1,
|
||||
index: v,
|
||||
class: v === page ? "current" : null
|
||||
class: v === page ? "is-current" : null
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
@ -4,7 +4,10 @@ import { outputExportResult } from "discourse/lib/export-result";
|
|||
import { ajax } from "discourse/lib/ajax";
|
||||
import { SCHEMA_VERSION, default as Report } from "admin/models/report";
|
||||
import computed from "ember-addons/ember-computed-decorators";
|
||||
import { registerTooltip, unregisterTooltip } from "discourse/lib/tooltip";
|
||||
import {
|
||||
registerHoverTooltip,
|
||||
unregisterHoverTooltip
|
||||
} from "discourse/lib/tooltip";
|
||||
|
||||
const TABLE_OPTIONS = {
|
||||
perPage: 8,
|
||||
|
@ -35,12 +38,7 @@ function collapseWeekly(data, average) {
|
|||
}
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNameBindings: [
|
||||
"isEnabled",
|
||||
"isLoading",
|
||||
"dasherizedDataSourceName",
|
||||
"currentMode"
|
||||
],
|
||||
classNameBindings: ["isEnabled", "isLoading", "dasherizedDataSourceName"],
|
||||
classNames: ["admin-report"],
|
||||
isEnabled: true,
|
||||
disabledLabel: "admin.dashboard.disabled",
|
||||
|
@ -69,6 +67,7 @@ export default Ember.Component.extend({
|
|||
"showDatesOptions",
|
||||
"showGroupOptions"
|
||||
),
|
||||
shouldDisplayTrend: Ember.computed.and("showTrend", "model.prev_period"),
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
|
@ -80,6 +79,7 @@ export default Ember.Component.extend({
|
|||
this._super(...arguments);
|
||||
|
||||
const state = this.get("filters") || {};
|
||||
|
||||
this.setProperties({
|
||||
category: Category.findById(state.categoryId),
|
||||
groupId: state.groupId,
|
||||
|
@ -101,14 +101,13 @@ export default Ember.Component.extend({
|
|||
didRender() {
|
||||
this._super(...arguments);
|
||||
|
||||
unregisterTooltip($(".info[data-tooltip]"));
|
||||
registerTooltip($(".info[data-tooltip]"));
|
||||
registerHoverTooltip($(".info[data-tooltip]"));
|
||||
},
|
||||
|
||||
willDestroyElement() {
|
||||
this._super(...arguments);
|
||||
|
||||
unregisterTooltip($(".info[data-tooltip]"));
|
||||
unregisterHoverTooltip($(".info[data-tooltip]"));
|
||||
},
|
||||
|
||||
showError: Ember.computed.or("showTimeoutError", "showExceptionError"),
|
||||
|
@ -140,8 +139,8 @@ export default Ember.Component.extend({
|
|||
const modes = forcedModes ? forcedModes.split(",") : reportModes;
|
||||
|
||||
return Ember.makeArray(modes).map(mode => {
|
||||
const base = `mode-button ${mode}`;
|
||||
const cssClass = currentMode === mode ? `${base} current` : base;
|
||||
const base = `mode-btn ${mode}`;
|
||||
const cssClass = currentMode === mode ? `${base} is-current` : base;
|
||||
|
||||
return {
|
||||
mode,
|
||||
|
@ -157,7 +156,7 @@ export default Ember.Component.extend({
|
|||
{ name: I18n.t("admin.dashboard.reports.groups"), value: "all" }
|
||||
];
|
||||
return arr.concat(
|
||||
this.site.groups.map(i => {
|
||||
(this.site.groups || []).map(i => {
|
||||
return { name: i["name"], value: i["id"] };
|
||||
})
|
||||
);
|
||||
|
@ -171,15 +170,25 @@ export default Ember.Component.extend({
|
|||
@computed("startDate")
|
||||
normalizedStartDate(startDate) {
|
||||
return startDate && typeof startDate.isValid === "function"
|
||||
? startDate.format("YYYYMMDD")
|
||||
: startDate;
|
||||
? moment
|
||||
.utc(startDate.toISOString())
|
||||
.locale("en")
|
||||
.format("YYYYMMDD")
|
||||
: moment(startDate)
|
||||
.locale("en")
|
||||
.format("YYYYMMDD");
|
||||
},
|
||||
|
||||
@computed("endDate")
|
||||
normalizedEndDate(endDate) {
|
||||
return endDate && typeof endDate.isValid === "function"
|
||||
? endDate.format("YYYYMMDD")
|
||||
: endDate;
|
||||
? moment
|
||||
.utc(endDate.toISOString())
|
||||
.locale("en")
|
||||
.format("YYYYMMDD")
|
||||
: moment(endDate)
|
||||
.locale("en")
|
||||
.format("YYYYMMDD");
|
||||
},
|
||||
|
||||
@computed(
|
||||
|
@ -317,16 +326,15 @@ export default Ember.Component.extend({
|
|||
let payload = { data: { cache: true, facets } };
|
||||
|
||||
if (this.get("startDate")) {
|
||||
payload.data.start_date = moment(
|
||||
this.get("startDate"),
|
||||
"YYYY-MM-DD"
|
||||
).format("YYYY-MM-DD[T]HH:mm:ss.SSSZZ");
|
||||
payload.data.start_date = moment
|
||||
.utc(this.get("startDate"), "YYYY-MM-DD")
|
||||
.toISOString();
|
||||
}
|
||||
|
||||
if (this.get("endDate")) {
|
||||
payload.data.end_date = moment(this.get("endDate"), "YYYY-MM-DD").format(
|
||||
"YYYY-MM-DD[T]HH:mm:ss.SSSZZ"
|
||||
);
|
||||
payload.data.end_date = moment
|
||||
.utc(this.get("endDate"), "YYYY-MM-DD")
|
||||
.toISOString();
|
||||
}
|
||||
|
||||
if (this.get("groupId") && this.get("groupId") !== "all") {
|
||||
|
|
|
@ -285,7 +285,7 @@ const Report = Discourse.Model.extend({
|
|||
value,
|
||||
type,
|
||||
property: mainProperty,
|
||||
formatedValue: value ? escapeExpression(value) : "-"
|
||||
formatedValue: value ? escapeExpression(value) : "—"
|
||||
};
|
||||
}
|
||||
};
|
||||
|
@ -318,7 +318,7 @@ const Report = Discourse.Model.extend({
|
|||
|
||||
return {
|
||||
value: username,
|
||||
formatedValue: username ? formatedValue(username) : "-"
|
||||
formatedValue: username ? formatedValue(username) : "—"
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -333,7 +333,7 @@ const Report = Discourse.Model.extend({
|
|||
|
||||
return {
|
||||
value: topicTitle,
|
||||
formatedValue: topicTitle ? formatedValue() : "-"
|
||||
formatedValue: topicTitle ? formatedValue() : "—"
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -360,7 +360,7 @@ const Report = Discourse.Model.extend({
|
|||
_percentLabel(value) {
|
||||
return {
|
||||
value,
|
||||
formatedValue: value ? `${value}%` : "-"
|
||||
formatedValue: value ? `${value}%` : "—"
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -373,14 +373,14 @@ const Report = Discourse.Model.extend({
|
|||
|
||||
return {
|
||||
value,
|
||||
formatedValue: value ? formatedValue() : "-"
|
||||
formatedValue: value ? formatedValue() : "—"
|
||||
};
|
||||
},
|
||||
|
||||
_dateLabel(value, date) {
|
||||
return {
|
||||
value,
|
||||
formatedValue: value ? date.format("LL") : "-"
|
||||
formatedValue: value ? date.format("LL") : "—"
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -389,7 +389,7 @@ const Report = Discourse.Model.extend({
|
|||
|
||||
return {
|
||||
value,
|
||||
formatedValue: value ? escaped : "-"
|
||||
formatedValue: value ? escaped : "—"
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -404,7 +404,7 @@ const Report = Discourse.Model.extend({
|
|||
|
||||
return {
|
||||
value,
|
||||
formatedValue: value ? formatedValue(value, row[properties[1]]) : "-"
|
||||
formatedValue: value ? formatedValue(value, row[properties[1]]) : "—"
|
||||
};
|
||||
},
|
||||
|
||||
|
|
|
@ -5,14 +5,23 @@ export default Discourse.Route.extend({
|
|||
if (!controller.get("start_date")) {
|
||||
controller.set(
|
||||
"start_date",
|
||||
moment()
|
||||
.subtract("30", "day")
|
||||
moment
|
||||
.utc()
|
||||
.subtract(1, "day")
|
||||
.subtract(1, "month")
|
||||
.startOf("day")
|
||||
.format("YYYY-MM-DD")
|
||||
);
|
||||
}
|
||||
|
||||
if (!controller.get("end_date")) {
|
||||
controller.set("end_date", moment().format("YYYY-MM-DD"));
|
||||
controller.set(
|
||||
"end_date",
|
||||
moment()
|
||||
.utc()
|
||||
.endOf("day")
|
||||
.format("YYYY-MM-DD")
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{{#if showSortingUI}}
|
||||
{{d-button action=sortByLabel icon=sortIcon class="sort-button"}}
|
||||
{{d-button action=sortByLabel icon=sortIcon class="sort-btn"}}
|
||||
{{/if}}
|
||||
|
||||
<span>{{label.title}}</span>
|
||||
<span class="title">{{label.title}}</span>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<table class="report-table">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
{{#if model.computedLabels}}
|
||||
|
@ -30,7 +30,7 @@
|
|||
</tr>
|
||||
<tr class="admin-report-table-row">
|
||||
{{#each totalsForSample as |total|}}
|
||||
<td class="{{total.type}} {{total.property}}">
|
||||
<td class="admin-report-table-cell {{total.type}} {{total.property}}">
|
||||
{{total.formatedValue}}
|
||||
</td>
|
||||
{{/each}}
|
||||
|
@ -44,8 +44,8 @@
|
|||
</td>
|
||||
</tr>
|
||||
<tr class="admin-report-table-row">
|
||||
<td class="date x">-</td>
|
||||
<td class="number y">{{number model.total}}</td>
|
||||
<td class="admin-report-table-cell date x">—</td>
|
||||
<td class="admin-report-table-cell number y">{{number model.total}}</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
</tbody>
|
||||
|
|
|
@ -1,50 +1,99 @@
|
|||
{{#if isEnabled}}
|
||||
{{#conditional-loading-section isLoading=isLoading}}
|
||||
{{#if showHeader}}
|
||||
<div class="report-header">
|
||||
{{#if showTitle}}
|
||||
<div class="report-title">
|
||||
<h3 class="title">
|
||||
{{#if showAllReportsLink}}
|
||||
{{#link-to "adminReports" class="all-report-link"}}
|
||||
{{i18n "admin.dashboard.all_reports"}}
|
||||
{{/link-to}}
|
||||
<span class="separator">|</span>
|
||||
{{/if}}
|
||||
{{#conditional-loading-section isLoading=isLoading}}
|
||||
{{#if showHeader}}
|
||||
<div class="header">
|
||||
{{#if showTitle}}
|
||||
<ul class="breadcrumb">
|
||||
{{#if showAllReportsLink}}
|
||||
<li class="item all-reports">
|
||||
{{#link-to "adminReports" class="report-url"}}
|
||||
{{i18n "admin.dashboard.all_reports"}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
<li class="item separator">|</li>
|
||||
{{/if}}
|
||||
|
||||
<a href="{{model.reportUrl}}" class="report-link">
|
||||
{{model.title}}
|
||||
</a>
|
||||
</h3>
|
||||
<li class="item report">
|
||||
<a href="{{model.reportUrl}}" class="report-url">
|
||||
{{model.title}}
|
||||
</a>
|
||||
|
||||
{{#if model.description}}
|
||||
<span class="info" data-tooltip="{{model.description}}">
|
||||
{{d-icon "question-circle"}}
|
||||
</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</li>
|
||||
</ul>
|
||||
{{/if}}
|
||||
|
||||
{{#if showTrend}}
|
||||
{{#if model.prev_period}}
|
||||
<div class="trend {{model.trend}}">
|
||||
<span class="trend-value" title="{{model.trendTitle}}">
|
||||
{{#if model.average}}
|
||||
{{number model.currentAverage}}{{#if model.percent}}%{{/if}}
|
||||
{{else}}
|
||||
{{number model.currentTotal noTitle="true"}}{{#if model.percent}}%{{/if}}
|
||||
{{/if}}
|
||||
</span>
|
||||
{{#if shouldDisplayTrend}}
|
||||
<div class="trend {{model.trend}}">
|
||||
<span class="value" title="{{model.trendTitle}}">
|
||||
{{#if model.average}}
|
||||
{{number model.currentAverage}}{{#if model.percent}}%{{/if}}
|
||||
{{else}}
|
||||
{{number model.currentTotal noTitle="true"}}{{#if model.percent}}%{{/if}}
|
||||
{{/if}}
|
||||
</span>
|
||||
|
||||
{{#if model.trendIcon}}
|
||||
{{d-icon model.trendIcon class="trend-icon"}}
|
||||
{{#if model.trendIcon}}
|
||||
{{d-icon model.trendIcon class="icon"}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="body">
|
||||
<div class="main">
|
||||
{{#unless showError}}
|
||||
{{#if hasData}}
|
||||
{{#if currentMode}}
|
||||
{{component modeComponent model=model options=options}}
|
||||
|
||||
{{#if model.relatedReport}}
|
||||
{{admin-report showFilteringUI=false dataSourceName=model.relatedReport.type}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<div class="alert alert-info report-alert no-data">
|
||||
{{d-icon "pie-chart"}}
|
||||
{{#if model.reportUrl}}
|
||||
<a href="{{model.reportUrl}}" class="report-url">
|
||||
<span>
|
||||
{{#if model.title}}
|
||||
{{model.title}} —
|
||||
{{/if}}
|
||||
{{i18n "admin.dashboard.reports.no_data"}}
|
||||
</span>
|
||||
</a>
|
||||
{{else}}
|
||||
<span>{{i18n "admin.dashboard.reports.no_data"}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
{{#if showTimeoutError}}
|
||||
<div class="alert alert-error report-alert timeout">
|
||||
{{d-icon "exclamation-triangle"}}
|
||||
<span>{{i18n "admin.dashboard.timeout_error"}}</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if showExceptionError}}
|
||||
<div class="alert alert-error report-alert exception">
|
||||
{{d-icon "exclamation-triangle"}}
|
||||
<span>{{i18n "admin.dashboard.exception_error"}}</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/unless}}
|
||||
</div>
|
||||
|
||||
{{#if showFilteringUI}}
|
||||
<div class="filters">
|
||||
{{#if showModes}}
|
||||
<ul class="mode-switch">
|
||||
<ul class="modes">
|
||||
{{#each displayedModes as |displayedMode|}}
|
||||
<li class="mode">
|
||||
{{d-button
|
||||
|
@ -56,118 +105,84 @@
|
|||
{{/each}}
|
||||
</ul>
|
||||
{{/if}}
|
||||
|
||||
{{#if showDatesOptions}}
|
||||
<div class="control">
|
||||
<span class="label">
|
||||
{{i18n 'admin.dashboard.reports.start_date'}}
|
||||
</span>
|
||||
|
||||
<div class="input">
|
||||
{{date-picker-past
|
||||
value=startDate
|
||||
defaultDate=startDate}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control">
|
||||
<span class="label">
|
||||
{{i18n 'admin.dashboard.reports.end_date'}}
|
||||
</span>
|
||||
|
||||
<div class="input">
|
||||
{{date-picker-past
|
||||
value=endDate
|
||||
defaultDate=endDate}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if showCategoryOptions}}
|
||||
<div class="control">
|
||||
<div class="input">
|
||||
{{search-advanced-category-chooser
|
||||
filterable=true
|
||||
value=category
|
||||
castInteger=true}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if showGroupOptions}}
|
||||
<div class="control">
|
||||
<div class="input">
|
||||
{{combo-box
|
||||
castInteger=true
|
||||
filterable=true
|
||||
valueAttribute="value"
|
||||
content=groupOptions
|
||||
value=groupId}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if showExport}}
|
||||
<div class="control">
|
||||
<div class="input">
|
||||
{{d-button
|
||||
class="export-csv-btn"
|
||||
action="exportCsv"
|
||||
label="admin.export_csv.button_text"
|
||||
icon="download"}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if showRefresh}}
|
||||
<div class="control">
|
||||
<div class="input">
|
||||
{{d-button
|
||||
class="refresh-report-btn btn-primary"
|
||||
action="refreshReport"
|
||||
label="admin.dashboard.reports.refresh_report"
|
||||
icon="refresh"}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="report-body">
|
||||
{{#unless showError}}
|
||||
{{#if hasData}}
|
||||
{{#if currentMode}}
|
||||
{{component modeComponent model=model options=options}}
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<div class="alert alert-info no-data">
|
||||
{{d-icon "pie-chart"}}
|
||||
<span>{{i18n "admin.dashboard.reports.no_data"}}</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
{{#if showTimeoutError}}
|
||||
<div class="alert alert-error report-error timeout">
|
||||
<span>{{i18n "admin.dashboard.timeout_error"}}</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if showExceptionError}}
|
||||
<div class="alert alert-error report-error exception">
|
||||
{{i18n "admin.dashboard.exception_error"}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/unless}}
|
||||
|
||||
{{#if showFilteringUI}}
|
||||
<div class="report-filters">
|
||||
{{#if showDatesOptions}}
|
||||
<div class="filtering-control">
|
||||
<span class="filtering-label">
|
||||
{{i18n 'admin.dashboard.reports.start_date'}}
|
||||
</span>
|
||||
|
||||
<div class="filtering-input">
|
||||
{{date-picker-past
|
||||
value=startDate
|
||||
defaultDate=startDate}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="filtering-control">
|
||||
<span class="filtering-label">
|
||||
{{i18n 'admin.dashboard.reports.end_date'}}
|
||||
</span>
|
||||
|
||||
<div class="filtering-input">
|
||||
{{date-picker-past
|
||||
value=endDate
|
||||
defaultDate=endDate}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if showCategoryOptions}}
|
||||
<div class="filtering-control">
|
||||
<div class="filtering-input">
|
||||
{{search-advanced-category-chooser
|
||||
filterable=true
|
||||
value=category
|
||||
castInteger=true}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if showGroupOptions}}
|
||||
<div class="filtering-control">
|
||||
<div class="filtering-input">
|
||||
{{combo-box
|
||||
castInteger=true
|
||||
filterable=true
|
||||
valueAttribute="value"
|
||||
content=groupOptions
|
||||
value=groupId}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if showExport}}
|
||||
<div class="filtering-control">
|
||||
<div class="filtering-input">
|
||||
{{d-button
|
||||
class="export-csv-btn"
|
||||
action="exportCsv"
|
||||
label="admin.export_csv.button_text"
|
||||
icon="download"}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if showRefresh}}
|
||||
<div class="filtering-control">
|
||||
<div class="filtering-input">
|
||||
{{d-button
|
||||
class="refresh-report-btn btn-primary"
|
||||
action="refreshReport"
|
||||
label="admin.dashboard.reports.refresh_report"
|
||||
icon="refresh"}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{#if model.relatedReport}}
|
||||
{{admin-report dataSourceName=model.relatedReport.type}}
|
||||
{{/if}}
|
||||
{{/conditional-loading-section}}
|
||||
</div>
|
||||
{{/conditional-loading-section}}
|
||||
{{else}}
|
||||
<div class="alert alert-info">
|
||||
{{{i18n disabledLabel}}}
|
||||
|
|
|
@ -57,23 +57,23 @@
|
|||
<div class="section-columns">
|
||||
<div class="section-column">
|
||||
<div class="admin-report activity-metrics">
|
||||
<div class="report-header">
|
||||
<div class="report-title">
|
||||
<h3 class="title">
|
||||
{{#link-to "adminReports" class="report-link"}}
|
||||
<div class="header">
|
||||
<ul class="breadcrumb">
|
||||
<li class="item report">
|
||||
{{#link-to "adminReports" class="report-url"}}
|
||||
{{i18n "admin.dashboard.activity_metrics"}}
|
||||
{{/link-to}}
|
||||
</h3>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="report-body">
|
||||
<div class="admin-report-counters-list">
|
||||
<div class="counters-list">
|
||||
<div class="counters-header">
|
||||
<div class="header"></div>
|
||||
<div class="header">{{i18n 'admin.dashboard.reports.today'}}</div>
|
||||
<div class="header">{{i18n 'admin.dashboard.reports.yesterday'}}</div>
|
||||
<div class="header">{{i18n 'admin.dashboard.reports.last_7_days'}}</div>
|
||||
<div class="header">{{i18n 'admin.dashboard.reports.last_30_days'}}</div>
|
||||
<div class="counters-cell"></div>
|
||||
<div class="counters-cell">{{i18n 'admin.dashboard.reports.today'}}</div>
|
||||
<div class="counters-cell">{{i18n 'admin.dashboard.reports.yesterday'}}</div>
|
||||
<div class="counters-cell">{{i18n 'admin.dashboard.reports.last_7_days'}}</div>
|
||||
<div class="counters-cell">{{i18n 'admin.dashboard.reports.last_30_days'}}</div>
|
||||
</div>
|
||||
|
||||
{{#each activityMetrics as |metric|}}
|
||||
|
@ -84,10 +84,11 @@
|
|||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#link-to "adminReports"}}
|
||||
{{i18n "admin.dashboard.all_reports"}}
|
||||
{{/link-to}}
|
||||
</div>
|
||||
{{#link-to "adminReports"}}
|
||||
{{i18n "admin.dashboard.all_reports"}}
|
||||
{{/link-to}}
|
||||
|
||||
<div class="user-metrics">
|
||||
{{#conditional-loading-section isLoading=isLoading}}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { escapeExpression } from "discourse/lib/utilities";
|
||||
|
||||
const fadeSpeed = 300;
|
||||
const tooltipID = "#discourse-tooltip";
|
||||
|
||||
export function showTooltip() {
|
||||
const fadeSpeed = 300;
|
||||
const tooltipID = "#discourse-tooltip";
|
||||
const $this = $(this);
|
||||
const $parent = $this.offsetParent();
|
||||
const content = escapeExpression($this.attr("data-tooltip"));
|
||||
|
@ -16,9 +17,7 @@ export function showTooltip() {
|
|||
pos.top -= delta.top;
|
||||
pos.left -= delta.left;
|
||||
|
||||
$(tooltipID)
|
||||
.fadeOut(fadeSpeed)
|
||||
.remove();
|
||||
hideTooltip(tooltipID);
|
||||
|
||||
$(this).after(`
|
||||
<div id="discourse-tooltip" ${retina}>
|
||||
|
@ -67,9 +66,24 @@ export function showTooltip() {
|
|||
return false;
|
||||
}
|
||||
|
||||
export function hideTooltip() {
|
||||
$(tooltipID)
|
||||
.fadeOut(fadeSpeed)
|
||||
.remove();
|
||||
}
|
||||
|
||||
export function registerTooltip(jqueryContext) {
|
||||
if (jqueryContext.length) {
|
||||
jqueryContext.on("click", showTooltip);
|
||||
jqueryContext.off("click").on("click", showTooltip);
|
||||
}
|
||||
}
|
||||
|
||||
export function registerHoverTooltip(jqueryContext) {
|
||||
if (jqueryContext.length) {
|
||||
jqueryContext
|
||||
.off("mouseenter mouseleave click")
|
||||
.on("mouseenter click", showTooltip)
|
||||
.on("mouseleave", hideTooltip);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,3 +92,9 @@ export function unregisterTooltip(jqueryContext) {
|
|||
jqueryContext.off("click");
|
||||
}
|
||||
}
|
||||
|
||||
export function unregisterHoverTooltip(jqueryContext) {
|
||||
if (jqueryContext.length) {
|
||||
jqueryContext.off("mouseenter mouseleave click");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,70 +1,36 @@
|
|||
.admin-report {
|
||||
.report-error,
|
||||
.no-data {
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
align-self: flex-start;
|
||||
text-align: center;
|
||||
padding: 3em;
|
||||
margin-bottom: 1.5em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
+ .table {
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
.report-error {
|
||||
color: $danger;
|
||||
border: 1px solid $danger;
|
||||
}
|
||||
|
||||
.no-data {
|
||||
background: $secondary;
|
||||
border: 1px solid $primary-low;
|
||||
color: $primary-low-mid;
|
||||
|
||||
.d-icon-pie-chart {
|
||||
color: currentColor;
|
||||
margin-bottom: 0.25em;
|
||||
font-size: $font-up-5;
|
||||
display: block;
|
||||
.conditional-loading-section {
|
||||
&.is-loading {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.conditional-loading-section {
|
||||
flex: 1;
|
||||
margin: 0;
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid $primary-low;
|
||||
margin-bottom: 0.5em;
|
||||
padding-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.report-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
.header .breadcrumb {
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
|
||||
.report-title {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.item {
|
||||
display: inline;
|
||||
font-size: $font-up-1;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: $font-up-1;
|
||||
.separator {
|
||||
font-weight: normal;
|
||||
}
|
||||
.all-reports .report-url {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.report-link {
|
||||
color: $primary;
|
||||
}
|
||||
.report {
|
||||
font-weight: 700;
|
||||
|
||||
.separator + .report-link {
|
||||
font-weight: normal;
|
||||
}
|
||||
.report-url {
|
||||
color: $primary;
|
||||
}
|
||||
|
||||
.info {
|
||||
|
@ -77,167 +43,134 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.trend {
|
||||
align-items: center;
|
||||
|
||||
&.trending-down,
|
||||
&.high-trending-down {
|
||||
color: $danger;
|
||||
}
|
||||
|
||||
&.trending-up,
|
||||
&.high-trending-up {
|
||||
color: $success;
|
||||
}
|
||||
|
||||
&.no-change {
|
||||
color: $primary-medium;
|
||||
}
|
||||
|
||||
.trend-value {
|
||||
font-size: $font-up-1;
|
||||
}
|
||||
|
||||
.trend-icon {
|
||||
font-size: $font-up-1;
|
||||
font-weight: 700;
|
||||
}
|
||||
.header .trend {
|
||||
margin-left: auto;
|
||||
&.trending-down,
|
||||
&.high-trending-down {
|
||||
color: $danger;
|
||||
}
|
||||
|
||||
.mode-switch {
|
||||
&.trending-up,
|
||||
&.high-trending-up {
|
||||
color: $success;
|
||||
}
|
||||
|
||||
&.no-change {
|
||||
color: $primary-medium;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: $font-up-1;
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: $font-up-1;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
.body {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.main {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.main .report-alert {
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
padding: 3em;
|
||||
border: 1px solid transparent;
|
||||
|
||||
a {
|
||||
color: $primary-medium;
|
||||
}
|
||||
|
||||
.d-icon {
|
||||
color: currentColor;
|
||||
margin-bottom: 0.25em;
|
||||
font-size: $font-up-5;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&.no-data {
|
||||
background: $secondary;
|
||||
border-color: $primary-low;
|
||||
color: $primary-low-mid;
|
||||
}
|
||||
|
||||
&.timeout,
|
||||
&.exception {
|
||||
border-color: $danger-low;
|
||||
color: $danger;
|
||||
}
|
||||
}
|
||||
|
||||
.filters {
|
||||
display: flex;
|
||||
margin-left: 1em;
|
||||
flex-direction: column;
|
||||
width: 220px;
|
||||
|
||||
.modes {
|
||||
margin: 0 0 1em 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
display: flex;
|
||||
margin: 0;
|
||||
|
||||
.mode {
|
||||
display: inline;
|
||||
display: inline-flex;
|
||||
flex: 1;
|
||||
|
||||
.mode-button.current {
|
||||
.mode-btn.is-current {
|
||||
color: $tertiary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.report-body {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.control {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.admin-report-table,
|
||||
.admin-report-chart {
|
||||
.control .label {
|
||||
font-weight: 700;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.report-filters {
|
||||
margin-left: 1em;
|
||||
min-width: 250px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.control .input,
|
||||
.control .select-kit {
|
||||
width: 100%;
|
||||
|
||||
.filtering-control {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.filtering-label {
|
||||
}
|
||||
.filtering-input {
|
||||
.export-csv-btn {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.date-picker-wrapper,
|
||||
.combo-box,
|
||||
.export-csv-btn,
|
||||
.refresh-report-btn {
|
||||
.refresh-report-btn {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.date-picker-wrapper {
|
||||
width: 100%;
|
||||
.date-picker {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.date-picker-wrapper {
|
||||
.date-picker {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
}
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.report-filters:only-child {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.admin-report.activity-metrics {
|
||||
table {
|
||||
table-layout: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-report.users-by-type {
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
.admin-report.users-by-type,
|
||||
.admin-report.users-by-trust-level {
|
||||
margin-bottom: 1.5em;
|
||||
flex: 1;
|
||||
.report-header {
|
||||
border-bottom: 1px solid $primary-medium;
|
||||
padding-bottom: 0.25em;
|
||||
border-bottom: 1px solid #e9e9e9;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-report.moderators-activity {
|
||||
tbody tr td.username,
|
||||
thead tr th.username {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-report.trending-search {
|
||||
tbody tr td.term,
|
||||
thead tr th.term {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-report.top-traffic-sources {
|
||||
tbody tr td.domain,
|
||||
thead tr th.domain {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-report.post-edits {
|
||||
.report-table {
|
||||
table-layout: auto;
|
||||
|
||||
tbody tr td,
|
||||
thead tr th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
thead tr th.edit_reason,
|
||||
tbody tr td.edit_reason {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.admin-report.flags-status {
|
||||
.admin-report-table {
|
||||
table-layout: auto;
|
||||
|
||||
tbody tr td,
|
||||
thead tr th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
tbody tr td.response_time,
|
||||
thead tr th.response_time {
|
||||
text-align: center;
|
||||
}
|
||||
.rtl .admin-report {
|
||||
.filters {
|
||||
margin-left: 0;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
.trend {
|
||||
margin-left: unset;
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,67 +1,21 @@
|
|||
.admin-report-counters-list {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
border-bottom: 1px solid $primary-low;
|
||||
|
||||
.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 {
|
||||
.admin-report {
|
||||
.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;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
|
||||
.d-icon {
|
||||
color: $primary-low-mid;
|
||||
|
@ -75,13 +29,8 @@
|
|||
}
|
||||
|
||||
@media screen and (max-width: 400px) {
|
||||
&.title {
|
||||
padding: 8px 0 8px 4px;
|
||||
font-size: $font-down-1;
|
||||
|
||||
.d-icon {
|
||||
display: none;
|
||||
}
|
||||
&.title .d-icon {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,27 +48,18 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-data {
|
||||
margin: 0;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
font-size: $font-0;
|
||||
border-bottom: 0;
|
||||
color: $primary-medium;
|
||||
.d-icon {
|
||||
font-size: $font-up-1;
|
||||
margin: 0 0.25em 0 0;
|
||||
color: $primary-low-mid;
|
||||
.rtl .counters-list .counters-header .counters-cell {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.rtl .counters-list {
|
||||
.cell {
|
||||
text-align: left;
|
||||
|
||||
&.title {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
text-align: left;
|
||||
padding: 0.5em;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,74 @@
|
|||
.admin-report-table {
|
||||
@media screen and (max-width: 650px) {
|
||||
table {
|
||||
tbody tr td {
|
||||
font-size: $font-down-1;
|
||||
&.two-columns {
|
||||
.table .admin-report-table-cell:first-child,
|
||||
.table .admin-report-table-header:first-child {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-align: left;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.table .admin-report-table-cell:last-child,
|
||||
.table .admin-report-table-header:last-child {
|
||||
display: inline-block;
|
||||
width: 80%;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.table {
|
||||
margin: 0;
|
||||
border: 1px solid $primary-low;
|
||||
table-layout: fixed;
|
||||
|
||||
tbody {
|
||||
border-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.table .admin-report-table-header {
|
||||
.sort-btn {
|
||||
outline: none;
|
||||
background: none;
|
||||
padding: 3px 8px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&.is-current-sort {
|
||||
.d-icon {
|
||||
color: $tertiary;
|
||||
}
|
||||
|
||||
.sort-btn:hover {
|
||||
color: $primary-medium;
|
||||
background: $primary-low;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.is-current-sort) .sort-btn {
|
||||
background: none;
|
||||
|
||||
&:hover {
|
||||
color: $primary-medium;
|
||||
background: $primary-low;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.admin-report-table-cell {
|
||||
&.user .username {
|
||||
margin-left: 0.25em;
|
||||
}
|
||||
}
|
||||
|
||||
.total-row {
|
||||
background: $primary-very-low;
|
||||
|
||||
td {
|
||||
font-weight: 700;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,98 +80,114 @@
|
|||
button {
|
||||
margin-left: 0.5em;
|
||||
|
||||
&.current {
|
||||
&.is-current {
|
||||
color: $tertiary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.two-columns {
|
||||
.report-table tbody tr td:first-child,
|
||||
.report-table thead tr th:first-child {
|
||||
text-align: left;
|
||||
.admin-report.top-referred-topics {
|
||||
.admin-report-table-header.topic_title {
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-report.trending-search {
|
||||
.admin-report-table-header.ctr,
|
||||
.admin-report-table-header.unique_searches,
|
||||
.admin-report-table-cell.ctr,
|
||||
.admin-report-table-cell.unique_searches {
|
||||
text-align: center;
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.admin-report-table-cell.term {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-report.moderators-activity {
|
||||
.admin-report-table-header.seconds,
|
||||
.admin-report-table-header.number,
|
||||
.admin-report-table-cell.seconds,
|
||||
.admin-report-table-cell.number {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.admin-report-table-header.user {
|
||||
width: 20%;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-report.post-edits {
|
||||
.admin-report-table-header.user {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.admin-report-table-cell.post,
|
||||
.admin-report-table-cell.edit_reason {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-report.flags-status {
|
||||
.admin-report-table-header.response_time,
|
||||
.admin-report-table-cell.response_time {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.rtl {
|
||||
.admin-report-table {
|
||||
&.two-columns {
|
||||
.table .admin-report-table-cell:first-child,
|
||||
.table .admin-report-table-header:first-child {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.table .admin-report-table-cell:last-child,
|
||||
.table .admin-report-table-header:last-child {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.report-table {
|
||||
table-layout: auto;
|
||||
.total-row {
|
||||
td {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.report-table {
|
||||
table-layout: fixed;
|
||||
border: 1px solid $primary-low;
|
||||
margin-top: 0;
|
||||
|
||||
tbody {
|
||||
border: none;
|
||||
|
||||
.total-row {
|
||||
td {
|
||||
font-weight: 700;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
tr {
|
||||
td {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
padding: 8px;
|
||||
|
||||
&.user {
|
||||
text-align: left;
|
||||
|
||||
.username {
|
||||
margin-left: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.admin-report-table-cell {
|
||||
&.user .username {
|
||||
margin-left: 0;
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
}
|
||||
|
||||
thead {
|
||||
border: 1px solid $primary-low;
|
||||
.admin-report.trending-search {
|
||||
.admin-report-table-header.term,
|
||||
.admin-report-table-cell.term {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-report-table-header {
|
||||
.sort-button {
|
||||
outline: none;
|
||||
background: none;
|
||||
padding: 3px 7px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.pagination {
|
||||
button {
|
||||
margin-left: 0;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-current-sort {
|
||||
.d-icon {
|
||||
color: $tertiary;
|
||||
}
|
||||
|
||||
.sort-button:hover {
|
||||
color: $primary-medium;
|
||||
background: $primary-low;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.is-current-sort) .sort-button {
|
||||
background: none;
|
||||
|
||||
&:hover {
|
||||
color: $primary-medium;
|
||||
background: $primary-low;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tr {
|
||||
th {
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
.admin-report.moderators-activity {
|
||||
.admin-report-table-header.user,
|
||||
.admin-report-table-cell.user {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,11 +62,11 @@
|
|||
max-width: 100%;
|
||||
|
||||
&:last-child {
|
||||
margin-left: 1em;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
margin-right: 1em;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
@include breakpoint(medium) {
|
||||
|
@ -119,22 +119,25 @@
|
|||
}
|
||||
}
|
||||
|
||||
.charts {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
.admin-report .header {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.chart {
|
||||
max-width: calc(100% * 1 / 3.2);
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
flex-basis: 100%;
|
||||
display: flex;
|
||||
.charts {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(12, 1fr);
|
||||
grid-column-gap: 1em;
|
||||
grid-row-gap: 1em;
|
||||
|
||||
.admin-report {
|
||||
grid-column: span 4;
|
||||
}
|
||||
|
||||
@include breakpoint(medium) {
|
||||
.chart {
|
||||
max-width: 100%;
|
||||
.admin-report {
|
||||
grid-column: span 12;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,6 +212,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.top-referred-topics {
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
.top-referred-topics,
|
||||
.trending-search {
|
||||
th:first-of-type {
|
||||
|
@ -216,12 +223,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.top-referred-topics {
|
||||
.dashboard-table table {
|
||||
table-layout: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.section {
|
||||
.period-chooser .period-chooser-header {
|
||||
.selected-name,
|
||||
|
@ -248,27 +249,82 @@
|
|||
}
|
||||
}
|
||||
|
||||
.admin-report-table {
|
||||
&.is-disabled {
|
||||
background: $primary-low;
|
||||
padding: 1em;
|
||||
.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;
|
||||
font-weight: 700;
|
||||
text-align: right;
|
||||
align-items: center;
|
||||
padding: 0.65em 0.25em;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 650px) {
|
||||
table {
|
||||
tbody tr td {
|
||||
font-size: $font-down-1;
|
||||
}
|
||||
.admin-report .main {
|
||||
border: 1px solid $primary-low;
|
||||
|
||||
&:hover {
|
||||
background-color: $primary-very-low;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-loading {
|
||||
height: 150px;
|
||||
.admin-report:not(:last-child) {
|
||||
.main {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.conditional-loading-section.is-loading {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-report .conditional-loading-section.is-loading {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 0.5em 0.25em;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
border: 1px solid $primary-low;
|
||||
|
||||
.title {
|
||||
font-size: $font-0;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
margin: 0;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-report .main .report-alert {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 0.5em 0.25em;
|
||||
align-items: center;
|
||||
border: 0;
|
||||
|
||||
&:hover {
|
||||
background-color: $primary-very-low;
|
||||
}
|
||||
|
||||
.d-icon {
|
||||
font-size: $font-up-1;
|
||||
margin: 0 0.25em 0 0;
|
||||
color: $primary-low-mid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.activity-metrics {
|
||||
margin-bottom: 0.25em;
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
.user-metrics {
|
||||
|
@ -368,21 +424,32 @@
|
|||
}
|
||||
}
|
||||
|
||||
.community-health.section {
|
||||
margin-bottom: 1em;
|
||||
.users-by-trust-level,
|
||||
.users-by-type {
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
.dashboard-next.moderation {
|
||||
.community-health.section {
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
.dashboard-next-moderation {
|
||||
.admin-dashboard-moderation-top {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(12, 1fr);
|
||||
grid-column-gap: 1em;
|
||||
grid-row-gap: 1em;
|
||||
}
|
||||
|
||||
.section-body {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.main-section {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(12, 1fr);
|
||||
grid-column-gap: 1em;
|
||||
grid-row-gap: 1em;
|
||||
|
||||
> * {
|
||||
grid-column: span 12;
|
||||
|
@ -392,6 +459,7 @@
|
|||
display: grid;
|
||||
grid-template-columns: repeat(12, 1fr);
|
||||
grid-column-gap: 1em;
|
||||
grid-row-gap: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,9 +22,11 @@
|
|||
@import "mobile/ring";
|
||||
@import "mobile/group";
|
||||
@import "mobile/groups";
|
||||
@import "mobile/dashboard_next";
|
||||
@import "mobile/admin_reports";
|
||||
@import "mobile/admin_report";
|
||||
@import "mobile/admin_report_table";
|
||||
@import "mobile/admin_report_counters";
|
||||
|
||||
// Import all component-specific files
|
||||
@import "mobile/components/*";
|
||||
|
|
|
@ -9,27 +9,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
.admin-report.top-referred-topics {
|
||||
.admin-report-table {
|
||||
.report-table {
|
||||
table-layout: fixed;
|
||||
|
||||
thead tr th.topic_title,
|
||||
tbody tr td.topic_title {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.admin-report.trending-search {
|
||||
.admin-report-table {
|
||||
.report-table {
|
||||
table-layout: fixed;
|
||||
|
||||
thead tr th.term,
|
||||
tbody tr td.term {
|
||||
width: 50%;
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
.counters-list {
|
||||
.counters-header .counters-cell {
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
|
@ -1,14 +1,28 @@
|
|||
.admin-report-table {
|
||||
.report-table {
|
||||
table-layout: fixed;
|
||||
.table {
|
||||
font-size: $font-down-1;
|
||||
}
|
||||
|
||||
thead tr th {
|
||||
font-weight: normal;
|
||||
font-size: $font-down-2;
|
||||
white-space: unset;
|
||||
.sort-button {
|
||||
display: none;
|
||||
}
|
||||
.table .admin-report-table-header {
|
||||
font-weight: 500;
|
||||
border-right: 1px solid $primary-low;
|
||||
padding: auto;
|
||||
|
||||
.title {
|
||||
writing-mode: vertical-rl;
|
||||
text-orientation: mixed;
|
||||
text-align: right;
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.sort-btn {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.table tbody tr td {
|
||||
&.user .username {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
.admin-reports {
|
||||
.admin-report {
|
||||
.report-body {
|
||||
.body {
|
||||
flex-direction: column;
|
||||
|
||||
.report-filters {
|
||||
.filters {
|
||||
order: 0;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.alert {
|
||||
.main {
|
||||
order: 2;
|
||||
}
|
||||
|
||||
.report-alert {
|
||||
margin: 0;
|
||||
order: 1;
|
||||
flex: 1;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.admin-report-table,
|
||||
.admin-report-chart {
|
||||
order: 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
.dashboard-next {
|
||||
.activity-metrics .counters-list {
|
||||
font-size: $font-down-1;
|
||||
}
|
||||
}
|
|
@ -23,8 +23,8 @@ class Admin::ReportsController < Admin::AdminController
|
|||
|
||||
raise Discourse::NotFound unless report_type =~ /^[a-z0-9\_]+$/
|
||||
|
||||
start_date = (params[:start_date].present? ? params[:start_date].to_date : 30.days.ago).beginning_of_day
|
||||
end_date = (params[:end_date].present? ? params[:end_date].to_date : start_date + 30.days).end_of_day
|
||||
start_date = (params[:start_date].present? ? Time.parse(params[:start_date]).to_date : 1.days.ago).beginning_of_day
|
||||
end_date = (params[:end_date].present? ? Time.parse(params[:end_date]).to_date : start_date + 30.days).end_of_day
|
||||
|
||||
if params.has_key?(:category_id) && params[:category_id].to_i > 0
|
||||
category_id = params[:category_id].to_i
|
||||
|
|
|
@ -18,8 +18,8 @@ class Report
|
|||
|
||||
def initialize(type)
|
||||
@type = type
|
||||
@start_date ||= Report.default_days.days.ago.beginning_of_day
|
||||
@end_date ||= Time.now.end_of_day
|
||||
@start_date ||= Report.default_days.days.ago.utc.beginning_of_day
|
||||
@end_date ||= Time.now.utc.end_of_day
|
||||
@prev_end_date = @start_date
|
||||
@average = false
|
||||
@percent = false
|
||||
|
|
|
@ -10,12 +10,10 @@ componentTest("default", {
|
|||
async test(assert) {
|
||||
assert.ok(exists(".admin-report.signups"));
|
||||
|
||||
assert.ok(
|
||||
exists(".admin-report.table.signups", "it defaults to table mode")
|
||||
);
|
||||
assert.ok(exists(".admin-report.signups", "it defaults to table mode"));
|
||||
|
||||
assert.equal(
|
||||
find(".report-header .title")
|
||||
find(".header .item.report")
|
||||
.text()
|
||||
.trim(),
|
||||
"Signups",
|
||||
|
@ -23,13 +21,13 @@ componentTest("default", {
|
|||
);
|
||||
|
||||
assert.equal(
|
||||
find(".report-header .info").attr("data-tooltip"),
|
||||
find(".header .info").attr("data-tooltip"),
|
||||
"New account registrations for this period",
|
||||
"it has a description"
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find(".report-body .report-table thead tr th:first-child")
|
||||
find(".admin-report-table thead tr th:first-child .title")
|
||||
.text()
|
||||
.trim(),
|
||||
"Day",
|
||||
|
@ -37,7 +35,7 @@ componentTest("default", {
|
|||
);
|
||||
|
||||
assert.equal(
|
||||
find(".report-body .report-table thead tr th:nth-child(2)")
|
||||
find(".admin-report-table thead tr th:nth-child(2) .title")
|
||||
.text()
|
||||
.trim(),
|
||||
"Count",
|
||||
|
@ -45,7 +43,7 @@ componentTest("default", {
|
|||
);
|
||||
|
||||
assert.equal(
|
||||
find(".report-body .report-table tbody tr:nth-child(1) td:nth-child(1)")
|
||||
find(".admin-report-table tbody tr:nth-child(1) td:nth-child(1)")
|
||||
.text()
|
||||
.trim(),
|
||||
"June 16, 2018",
|
||||
|
@ -53,7 +51,7 @@ componentTest("default", {
|
|||
);
|
||||
|
||||
assert.equal(
|
||||
find(".report-body .report-table tbody tr:nth-child(1) td:nth-child(2)")
|
||||
find(".admin-report-table tbody tr:nth-child(1) td:nth-child(2)")
|
||||
.text()
|
||||
.trim(),
|
||||
"12",
|
||||
|
@ -62,9 +60,10 @@ componentTest("default", {
|
|||
|
||||
assert.ok(exists(".total-row"), "it has totals");
|
||||
|
||||
await click(".admin-report-table-header.y .sort-button");
|
||||
await click(".admin-report-table-header.y .sort-btn");
|
||||
|
||||
assert.equal(
|
||||
find(".report-body .report-table tbody tr:nth-child(1) td:nth-child(2)")
|
||||
find(".admin-report-table tbody tr:nth-child(1) td:nth-child(2)")
|
||||
.text()
|
||||
.trim(),
|
||||
"7",
|
||||
|
@ -98,13 +97,13 @@ componentTest("options", {
|
|||
});
|
||||
|
||||
componentTest("switch modes", {
|
||||
template: "{{admin-report dataSourceName='signups'}}",
|
||||
template: "{{admin-report dataSourceName='signups' showFilteringUI=true}}",
|
||||
|
||||
async test(assert) {
|
||||
await click(".mode-button.chart");
|
||||
await click(".mode-btn.chart");
|
||||
|
||||
assert.notOk(exists(".admin-report.table.signups"), "it removes the table");
|
||||
assert.ok(exists(".admin-report.chart.signups"), "it shows the chart");
|
||||
assert.notOk(exists(".admin-report-table"), "it removes the table");
|
||||
assert.ok(exists(".admin-report-chart"), "it shows the chart");
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue