mirror of
https://github.com/discourse/discourse.git
synced 2025-05-25 00:32:52 +08:00
FIX: improves number/percent support in reports
This commit is contained in:
@ -0,0 +1,18 @@
|
|||||||
|
import computed from "ember-addons/ember-computed-decorators";
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
tagName: "td",
|
||||||
|
classNames: ["admin-report-table-cell"],
|
||||||
|
classNameBindings: ["type", "property"],
|
||||||
|
options: null,
|
||||||
|
|
||||||
|
@computed("label", "data", "options")
|
||||||
|
computedLabel(label, data, options) {
|
||||||
|
return label.compute(data, options || {});
|
||||||
|
},
|
||||||
|
|
||||||
|
type: Ember.computed.alias("label.type"),
|
||||||
|
property: Ember.computed.alias("label.mainProperty"),
|
||||||
|
formatedValue: Ember.computed.alias("computedLabel.formatedValue"),
|
||||||
|
value: Ember.computed.alias("computedLabel.value")
|
||||||
|
});
|
@ -3,7 +3,7 @@ import computed from "ember-addons/ember-computed-decorators";
|
|||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
tagName: "th",
|
tagName: "th",
|
||||||
classNames: ["admin-report-table-header"],
|
classNames: ["admin-report-table-header"],
|
||||||
classNameBindings: ["label.mainProperty", "isCurrentSort"],
|
classNameBindings: ["label.mainProperty", "label.type", "isCurrentSort"],
|
||||||
attributeBindings: ["label.title:title"],
|
attributeBindings: ["label.title:title"],
|
||||||
|
|
||||||
@computed("currentSortLabel.sortProperty", "label.sortProperty")
|
@computed("currentSortLabel.sortProperty", "label.sortProperty")
|
||||||
|
@ -1,13 +1,5 @@
|
|||||||
import computed from "ember-addons/ember-computed-decorators";
|
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
tagName: "tr",
|
tagName: "tr",
|
||||||
classNames: ["admin-report-table-row"],
|
classNames: ["admin-report-table-row"],
|
||||||
|
options: null
|
||||||
@computed("data", "labels")
|
|
||||||
cells(row, labels) {
|
|
||||||
return labels.map(label => {
|
|
||||||
return label.compute(row);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import computed from "ember-addons/ember-computed-decorators";
|
import computed from "ember-addons/ember-computed-decorators";
|
||||||
import { registerTooltip, unregisterTooltip } from "discourse/lib/tooltip";
|
import { registerTooltip, unregisterTooltip } from "discourse/lib/tooltip";
|
||||||
import { isNumeric } from "discourse/lib/utilities";
|
|
||||||
|
|
||||||
const PAGES_LIMIT = 8;
|
const PAGES_LIMIT = 8;
|
||||||
|
|
||||||
@ -67,14 +66,16 @@ export default Ember.Component.extend({
|
|||||||
const computedLabel = label.compute(row);
|
const computedLabel = label.compute(row);
|
||||||
const value = computedLabel.value;
|
const value = computedLabel.value;
|
||||||
|
|
||||||
if (!computedLabel.countable || !value || !isNumeric(value)) {
|
if (!["seconds", "number", "percent"].includes(label.type)) {
|
||||||
return undefined;
|
return;
|
||||||
} else {
|
} else {
|
||||||
return sum + value;
|
return sum + Math.round(value || 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
totalsRow[label.mainProperty] = rows.reduce(reducer, 0);
|
const total = rows.reduce(reducer, 0);
|
||||||
|
totalsRow[label.mainProperty] =
|
||||||
|
label.type === "percent" ? Math.round(total / rows.length) : total;
|
||||||
});
|
});
|
||||||
|
|
||||||
return totalsRow;
|
return totalsRow;
|
||||||
|
@ -9,7 +9,8 @@ import { registerTooltip, unregisterTooltip } from "discourse/lib/tooltip";
|
|||||||
const TABLE_OPTIONS = {
|
const TABLE_OPTIONS = {
|
||||||
perPage: 8,
|
perPage: 8,
|
||||||
total: true,
|
total: true,
|
||||||
limit: 20
|
limit: 20,
|
||||||
|
formatNumbers: true
|
||||||
};
|
};
|
||||||
|
|
||||||
const CHART_OPTIONS = {};
|
const CHART_OPTIONS = {};
|
||||||
@ -347,12 +348,12 @@ export default Ember.Component.extend({
|
|||||||
if (mode === "table") {
|
if (mode === "table") {
|
||||||
const tableOptions = JSON.parse(JSON.stringify(TABLE_OPTIONS));
|
const tableOptions = JSON.parse(JSON.stringify(TABLE_OPTIONS));
|
||||||
return Ember.Object.create(
|
return Ember.Object.create(
|
||||||
_.assign(tableOptions, this.get("reportOptions.table") || {})
|
Object.assign(tableOptions, this.get("reportOptions.table") || {})
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const chartOptions = JSON.parse(JSON.stringify(CHART_OPTIONS));
|
const chartOptions = JSON.parse(JSON.stringify(CHART_OPTIONS));
|
||||||
return Ember.Object.create(
|
return Ember.Object.create(
|
||||||
_.assign(chartOptions, this.get("reportOptions.chart") || {})
|
Object.assign(chartOptions, this.get("reportOptions.chart") || {})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -5,7 +5,7 @@ export default Ember.Controller.extend({
|
|||||||
|
|
||||||
@computed("model.type")
|
@computed("model.type")
|
||||||
reportOptions(type) {
|
reportOptions(type) {
|
||||||
let options = { table: { perPage: 50, limit: 50 } };
|
let options = { table: { perPage: 50, limit: 50, formatNumbers: false } };
|
||||||
|
|
||||||
if (type === "top_referred_topics") {
|
if (type === "top_referred_topics") {
|
||||||
options.table.limit = 10;
|
options.table.limit = 10;
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
import { escapeExpression } from "discourse/lib/utilities";
|
import { escapeExpression } from "discourse/lib/utilities";
|
||||||
import { ajax } from "discourse/lib/ajax";
|
import { ajax } from "discourse/lib/ajax";
|
||||||
import round from "discourse/lib/round";
|
import round from "discourse/lib/round";
|
||||||
import {
|
import { fillMissingDates, formatUsername } from "discourse/lib/utilities";
|
||||||
fillMissingDates,
|
|
||||||
isNumeric,
|
|
||||||
formatUsername
|
|
||||||
} from "discourse/lib/utilities";
|
|
||||||
import computed from "ember-addons/ember-computed-decorators";
|
import computed from "ember-addons/ember-computed-decorators";
|
||||||
import { number, durationTiny } from "discourse/lib/formatter";
|
import { number, durationTiny } from "discourse/lib/formatter";
|
||||||
import { renderAvatar } from "discourse/helpers/user-avatar";
|
import { renderAvatar } from "discourse/helpers/user-avatar";
|
||||||
@ -252,7 +248,7 @@ const Report = Discourse.Model.extend({
|
|||||||
@computed("labels")
|
@computed("labels")
|
||||||
computedLabels(labels) {
|
computedLabels(labels) {
|
||||||
return labels.map(label => {
|
return labels.map(label => {
|
||||||
const type = label.type;
|
const type = label.type || "string";
|
||||||
|
|
||||||
let mainProperty;
|
let mainProperty;
|
||||||
if (label.property) mainProperty = label.property;
|
if (label.property) mainProperty = label.property;
|
||||||
@ -266,51 +262,41 @@ const Report = Discourse.Model.extend({
|
|||||||
title: label.title,
|
title: label.title,
|
||||||
sortProperty: label.sort_property || mainProperty,
|
sortProperty: label.sort_property || mainProperty,
|
||||||
mainProperty,
|
mainProperty,
|
||||||
compute: row => {
|
type,
|
||||||
|
compute: (row, opts = {}) => {
|
||||||
const value = row[mainProperty];
|
const value = row[mainProperty];
|
||||||
|
|
||||||
if (type === "user") return this._userLabel(label.properties, row);
|
if (type === "user") return this._userLabel(label.properties, row);
|
||||||
if (type === "post") return this._postLabel(label.properties, row);
|
if (type === "post") return this._postLabel(label.properties, row);
|
||||||
if (type === "topic") return this._topicLabel(label.properties, row);
|
if (type === "topic") return this._topicLabel(label.properties, row);
|
||||||
if (type === "seconds")
|
if (type === "seconds") return this._secondsLabel(value);
|
||||||
return this._secondsLabel(mainProperty, value);
|
|
||||||
if (type === "link") return this._linkLabel(label.properties, row);
|
if (type === "link") return this._linkLabel(label.properties, row);
|
||||||
if (type === "percent")
|
if (type === "percent") return this._percentLabel(value);
|
||||||
return this._percentLabel(mainProperty, value);
|
if (type === "number") {
|
||||||
if (type === "number" || isNumeric(value)) {
|
return this._numberLabel(value, opts);
|
||||||
return this._numberLabel(mainProperty, value);
|
|
||||||
}
|
}
|
||||||
if (type === "date") {
|
if (type === "date") {
|
||||||
const date = moment(value, "YYYY-MM-DD");
|
const date = moment(value, "YYYY-MM-DD");
|
||||||
if (date.isValid())
|
if (date.isValid()) return this._dateLabel(value, date);
|
||||||
return this._dateLabel(mainProperty, value, date);
|
|
||||||
}
|
}
|
||||||
if (type === "text") return this._textLabel(mainProperty, value);
|
if (type === "text") return this._textLabel(value);
|
||||||
if (!value) return this._undefinedLabel();
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
property: mainProperty,
|
|
||||||
value,
|
value,
|
||||||
type: type || "string",
|
type,
|
||||||
formatedValue: escapeExpression(value)
|
property: mainProperty,
|
||||||
|
formatedValue: value ? escapeExpression(value) : "-"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_undefinedLabel() {
|
|
||||||
return {
|
|
||||||
value: null,
|
|
||||||
formatedValue: "-",
|
|
||||||
type: "undefined"
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
_userLabel(properties, row) {
|
_userLabel(properties, row) {
|
||||||
const username = row[properties.username];
|
const username = row[properties.username];
|
||||||
|
|
||||||
if (!username) return this._undefinedLabel();
|
const formatedValue = () => {
|
||||||
|
const userId = row[properties.id];
|
||||||
|
|
||||||
const user = Ember.Object.create({
|
const user = Ember.Object.create({
|
||||||
username,
|
username,
|
||||||
@ -318,18 +304,21 @@ const Report = Discourse.Model.extend({
|
|||||||
avatar_template: row[properties.avatar]
|
avatar_template: row[properties.avatar]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const href = `/admin/users/${userId}/${username}`;
|
||||||
|
|
||||||
const avatarImg = renderAvatar(user, {
|
const avatarImg = renderAvatar(user, {
|
||||||
imageSize: "tiny",
|
imageSize: "tiny",
|
||||||
ignoreTitle: true
|
ignoreTitle: true
|
||||||
});
|
});
|
||||||
|
|
||||||
const href = `/admin/users/${row[properties.id]}/${username}`;
|
return `<a href='${href}'>${avatarImg}<span class='username'>${
|
||||||
|
user.name
|
||||||
|
}</span></a>`;
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: "user",
|
|
||||||
property: properties.username,
|
|
||||||
value: username,
|
value: username,
|
||||||
formatedValue: `<a href='${href}'>${avatarImg}<span class='username'>${username}</span></a>`
|
formatedValue: username ? formatedValue(username) : "-"
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -339,8 +328,6 @@ const Report = Discourse.Model.extend({
|
|||||||
const href = `/t/-/${topicId}`;
|
const href = `/t/-/${topicId}`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: "topic",
|
|
||||||
property: properties.title,
|
|
||||||
value: topicTitle,
|
value: topicTitle,
|
||||||
formatedValue: `<a href='${href}'>${topicTitle}</a>`
|
formatedValue: `<a href='${href}'>${topicTitle}</a>`
|
||||||
};
|
};
|
||||||
@ -353,72 +340,67 @@ const Report = Discourse.Model.extend({
|
|||||||
const href = `/t/-/${topicId}/${postNumber}`;
|
const href = `/t/-/${topicId}/${postNumber}`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: "post",
|
|
||||||
property: properties.title,
|
property: properties.title,
|
||||||
value: postTitle,
|
value: postTitle,
|
||||||
formatedValue: `<a href='${href}'>${postTitle}</a>`
|
formatedValue: `<a href='${href}'>${postTitle}</a>`
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
_secondsLabel(property, value) {
|
_secondsLabel(value) {
|
||||||
return {
|
return {
|
||||||
value,
|
value,
|
||||||
property,
|
|
||||||
countable: true,
|
|
||||||
type: "seconds",
|
|
||||||
formatedValue: durationTiny(value)
|
formatedValue: durationTiny(value)
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
_percentLabel(property, value) {
|
_percentLabel(value) {
|
||||||
return {
|
return {
|
||||||
type: "percent",
|
|
||||||
property,
|
|
||||||
value,
|
value,
|
||||||
formatedValue: `${value}%`
|
formatedValue: value ? `${value}%` : "-"
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
_numberLabel(property, value) {
|
_numberLabel(value, options = {}) {
|
||||||
|
const formatNumbers = Ember.isEmpty(options.formatNumbers)
|
||||||
|
? true
|
||||||
|
: options.formatNumbers;
|
||||||
|
|
||||||
|
const formatedValue = () => (formatNumbers ? number(value) : value);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: "number",
|
|
||||||
countable: true,
|
|
||||||
property,
|
|
||||||
value,
|
value,
|
||||||
formatedValue: number(value)
|
formatedValue: value ? formatedValue() : "-"
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
_dateLabel(property, value, date) {
|
_dateLabel(value, date) {
|
||||||
return {
|
return {
|
||||||
type: "date",
|
|
||||||
property,
|
|
||||||
value,
|
value,
|
||||||
formatedValue: date.format("LL")
|
formatedValue: value ? date.format("LL") : "-"
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
_textLabel(property, value) {
|
_textLabel(value) {
|
||||||
const escaped = escapeExpression(value);
|
const escaped = escapeExpression(value);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: "text",
|
|
||||||
property,
|
|
||||||
value,
|
value,
|
||||||
formatedValue: escaped
|
formatedValue: value ? escaped : "-"
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
_linkLabel(properties, row) {
|
_linkLabel(properties, row) {
|
||||||
const property = properties[0];
|
const property = properties[0];
|
||||||
const value = row[property];
|
const value = row[property];
|
||||||
|
const formatedValue = (href, anchor) => {
|
||||||
|
return `<a href="${escapeExpression(href)}">${escapeExpression(
|
||||||
|
anchor
|
||||||
|
)}</a>`;
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: "link",
|
|
||||||
property,
|
|
||||||
value,
|
value,
|
||||||
formatedValue: `<a href="${escapeExpression(
|
formatedValue: value ? formatedValue(value, row[properties[1]]) : "-"
|
||||||
row[properties[1]]
|
|
||||||
)}">${escapeExpression(value)}</a>`
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
{{{formatedValue}}}
|
@ -1,5 +1,3 @@
|
|||||||
{{#each cells as |cell|}}
|
{{#each labels as |label|}}
|
||||||
<td class="{{cell.type}} {{cell.property}}" title="{{cell.tooltip}}">
|
{{admin-report-table-cell label=label data=data options=options}}
|
||||||
{{{cell.formatedValue}}}
|
|
||||||
</td>
|
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{{#each paginatedData as |data|}}
|
{{#each paginatedData as |data|}}
|
||||||
{{admin-report-table-row data=data labels=model.computedLabels}}
|
{{admin-report-table-row data=data labels=model.computedLabels options=options}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
{{#if showTotalForSample}}
|
{{#if showTotalForSample}}
|
||||||
@ -30,7 +30,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr class="admin-report-table-row">
|
<tr class="admin-report-table-row">
|
||||||
{{#each totalsForSample as |total|}}
|
{{#each totalsForSample as |total|}}
|
||||||
<td class="admin-report-table-row {{total.type}} {{total.property}}">
|
<td class="{{total.type}} {{total.property}}">
|
||||||
{{total.formatedValue}}
|
{{total.formatedValue}}
|
||||||
</td>
|
</td>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
@ -296,6 +296,19 @@ class Report
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.report_dau_by_mau(report)
|
def self.report_dau_by_mau(report)
|
||||||
|
report.labels = [
|
||||||
|
{
|
||||||
|
type: :date,
|
||||||
|
property: :x,
|
||||||
|
title: I18n.t("reports.default.labels.day")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: :percent,
|
||||||
|
property: :y,
|
||||||
|
title: I18n.t("reports.default.labels.percent")
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
report.average = true
|
report.average = true
|
||||||
report.percent = true
|
report.percent = true
|
||||||
|
|
||||||
@ -441,6 +454,7 @@ class Report
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: :y,
|
property: :y,
|
||||||
|
type: :number,
|
||||||
title: I18n.t("reports.default.labels.count")
|
title: I18n.t("reports.default.labels.count")
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -537,6 +551,7 @@ class Report
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: :count,
|
property: :count,
|
||||||
|
type: :number,
|
||||||
title: I18n.t("reports.web_crawlers.labels.page_views")
|
title: I18n.t("reports.web_crawlers.labels.page_views")
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -562,6 +577,7 @@ class Report
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: :y,
|
property: :y,
|
||||||
|
type: :number,
|
||||||
title: I18n.t("reports.default.labels.count")
|
title: I18n.t("reports.default.labels.count")
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -596,6 +612,7 @@ class Report
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: :num_clicks,
|
property: :num_clicks,
|
||||||
|
type: :number,
|
||||||
title: I18n.t("reports.top_referred_topics.labels.num_clicks")
|
title: I18n.t("reports.top_referred_topics.labels.num_clicks")
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -616,10 +633,12 @@ class Report
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: :num_clicks,
|
property: :num_clicks,
|
||||||
|
type: :number,
|
||||||
title: I18n.t("reports.top_traffic_sources.labels.num_clicks")
|
title: I18n.t("reports.top_traffic_sources.labels.num_clicks")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: :num_topics,
|
property: :num_topics,
|
||||||
|
type: :number,
|
||||||
title: I18n.t("reports.top_traffic_sources.labels.num_topics")
|
title: I18n.t("reports.top_traffic_sources.labels.num_topics")
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -638,6 +657,7 @@ class Report
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: :unique_searches,
|
property: :unique_searches,
|
||||||
|
type: :number,
|
||||||
title: I18n.t("reports.trending_search.labels.searches")
|
title: I18n.t("reports.trending_search.labels.searches")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -696,6 +716,7 @@ class Report
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: :flag_count,
|
property: :flag_count,
|
||||||
|
type: :number,
|
||||||
title: I18n.t("reports.moderators_activity.labels.flag_count")
|
title: I18n.t("reports.moderators_activity.labels.flag_count")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -705,18 +726,22 @@ class Report
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: :topic_count,
|
property: :topic_count,
|
||||||
|
type: :number,
|
||||||
title: I18n.t("reports.moderators_activity.labels.topic_count")
|
title: I18n.t("reports.moderators_activity.labels.topic_count")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: :pm_count,
|
property: :pm_count,
|
||||||
|
type: :number,
|
||||||
title: I18n.t("reports.moderators_activity.labels.pm_count")
|
title: I18n.t("reports.moderators_activity.labels.pm_count")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: :post_count,
|
property: :post_count,
|
||||||
|
type: :number,
|
||||||
title: I18n.t("reports.moderators_activity.labels.post_count")
|
title: I18n.t("reports.moderators_activity.labels.post_count")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: :revision_count,
|
property: :revision_count,
|
||||||
|
type: :number,
|
||||||
title: I18n.t("reports.moderators_activity.labels.revision_count")
|
title: I18n.t("reports.moderators_activity.labels.revision_count")
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -850,6 +850,7 @@ en:
|
|||||||
default:
|
default:
|
||||||
labels:
|
labels:
|
||||||
count: Count
|
count: Count
|
||||||
|
percent: Percent
|
||||||
day: Day
|
day: Day
|
||||||
post_edits:
|
post_edits:
|
||||||
title: "Post edits"
|
title: "Post edits"
|
||||||
|
@ -418,7 +418,7 @@ QUnit.test("computed labels", assert => {
|
|||||||
},
|
},
|
||||||
title: "Moderator"
|
title: "Moderator"
|
||||||
},
|
},
|
||||||
{ property: "flag_count", title: "Flag count" },
|
{ type: "number", property: "flag_count", title: "Flag count" },
|
||||||
{ type: "seconds", property: "time_read", title: "Time read" },
|
{ type: "seconds", property: "time_read", title: "Time read" },
|
||||||
{ type: "text", property: "note", title: "Note" },
|
{ type: "text", property: "note", title: "Note" },
|
||||||
{
|
{
|
||||||
@ -453,62 +453,66 @@ QUnit.test("computed labels", assert => {
|
|||||||
assert.equal(usernameLabel.mainProperty, "username");
|
assert.equal(usernameLabel.mainProperty, "username");
|
||||||
assert.equal(usernameLabel.sortProperty, "username");
|
assert.equal(usernameLabel.sortProperty, "username");
|
||||||
assert.equal(usernameLabel.title, "Moderator");
|
assert.equal(usernameLabel.title, "Moderator");
|
||||||
|
assert.equal(usernameLabel.type, "user");
|
||||||
const computedUsernameLabel = usernameLabel.compute(row);
|
const computedUsernameLabel = usernameLabel.compute(row);
|
||||||
assert.equal(
|
assert.equal(
|
||||||
computedUsernameLabel.formatedValue,
|
computedUsernameLabel.formatedValue,
|
||||||
"<a href='/admin/users/1/joffrey'><img alt='' width='20' height='20' src='/' class='avatar' title='joffrey'><span class='username'>joffrey</span></a>"
|
"<a href='/admin/users/1/joffrey'><img alt='' width='20' height='20' src='/' class='avatar' title='joffrey'><span class='username'>joffrey</span></a>"
|
||||||
);
|
);
|
||||||
assert.equal(computedUsernameLabel.type, "user");
|
|
||||||
assert.equal(computedUsernameLabel.value, "joffrey");
|
assert.equal(computedUsernameLabel.value, "joffrey");
|
||||||
|
|
||||||
const flagCountLabel = computedLabels[1];
|
const flagCountLabel = computedLabels[1];
|
||||||
assert.equal(flagCountLabel.mainProperty, "flag_count");
|
assert.equal(flagCountLabel.mainProperty, "flag_count");
|
||||||
assert.equal(flagCountLabel.sortProperty, "flag_count");
|
assert.equal(flagCountLabel.sortProperty, "flag_count");
|
||||||
assert.equal(flagCountLabel.title, "Flag count");
|
assert.equal(flagCountLabel.title, "Flag count");
|
||||||
const computedFlagCountLabel = flagCountLabel.compute(row);
|
assert.equal(flagCountLabel.type, "number");
|
||||||
|
let computedFlagCountLabel = flagCountLabel.compute(row);
|
||||||
assert.equal(computedFlagCountLabel.formatedValue, "1.9k");
|
assert.equal(computedFlagCountLabel.formatedValue, "1.9k");
|
||||||
assert.equal(computedFlagCountLabel.type, "number");
|
|
||||||
assert.equal(computedFlagCountLabel.value, 1876);
|
assert.equal(computedFlagCountLabel.value, 1876);
|
||||||
|
computedFlagCountLabel = flagCountLabel.compute(row, {
|
||||||
|
formatNumbers: false
|
||||||
|
});
|
||||||
|
assert.equal(computedFlagCountLabel.formatedValue, 1876);
|
||||||
|
|
||||||
const timeReadLabel = computedLabels[2];
|
const timeReadLabel = computedLabels[2];
|
||||||
assert.equal(timeReadLabel.mainProperty, "time_read");
|
assert.equal(timeReadLabel.mainProperty, "time_read");
|
||||||
assert.equal(timeReadLabel.sortProperty, "time_read");
|
assert.equal(timeReadLabel.sortProperty, "time_read");
|
||||||
assert.equal(timeReadLabel.title, "Time read");
|
assert.equal(timeReadLabel.title, "Time read");
|
||||||
|
assert.equal(timeReadLabel.type, "seconds");
|
||||||
const computedTimeReadLabel = timeReadLabel.compute(row);
|
const computedTimeReadLabel = timeReadLabel.compute(row);
|
||||||
assert.equal(computedTimeReadLabel.formatedValue, "3d");
|
assert.equal(computedTimeReadLabel.formatedValue, "3d");
|
||||||
assert.equal(computedTimeReadLabel.type, "seconds");
|
|
||||||
assert.equal(computedTimeReadLabel.value, 287362);
|
assert.equal(computedTimeReadLabel.value, 287362);
|
||||||
|
|
||||||
const noteLabel = computedLabels[3];
|
const noteLabel = computedLabels[3];
|
||||||
assert.equal(noteLabel.mainProperty, "note");
|
assert.equal(noteLabel.mainProperty, "note");
|
||||||
assert.equal(noteLabel.sortProperty, "note");
|
assert.equal(noteLabel.sortProperty, "note");
|
||||||
assert.equal(noteLabel.title, "Note");
|
assert.equal(noteLabel.title, "Note");
|
||||||
|
assert.equal(noteLabel.type, "text");
|
||||||
const computedNoteLabel = noteLabel.compute(row);
|
const computedNoteLabel = noteLabel.compute(row);
|
||||||
assert.equal(computedNoteLabel.formatedValue, "This is a long note");
|
assert.equal(computedNoteLabel.formatedValue, "This is a long note");
|
||||||
assert.equal(computedNoteLabel.type, "text");
|
|
||||||
assert.equal(computedNoteLabel.value, "This is a long note");
|
assert.equal(computedNoteLabel.value, "This is a long note");
|
||||||
|
|
||||||
const topicLabel = computedLabels[4];
|
const topicLabel = computedLabels[4];
|
||||||
assert.equal(topicLabel.mainProperty, "topic_title");
|
assert.equal(topicLabel.mainProperty, "topic_title");
|
||||||
assert.equal(topicLabel.sortProperty, "topic_title");
|
assert.equal(topicLabel.sortProperty, "topic_title");
|
||||||
assert.equal(topicLabel.title, "Topic");
|
assert.equal(topicLabel.title, "Topic");
|
||||||
|
assert.equal(topicLabel.type, "topic");
|
||||||
const computedTopicLabel = topicLabel.compute(row);
|
const computedTopicLabel = topicLabel.compute(row);
|
||||||
assert.equal(
|
assert.equal(
|
||||||
computedTopicLabel.formatedValue,
|
computedTopicLabel.formatedValue,
|
||||||
"<a href='/t/-/2'>Test topic</a>"
|
"<a href='/t/-/2'>Test topic</a>"
|
||||||
);
|
);
|
||||||
assert.equal(computedTopicLabel.type, "topic");
|
|
||||||
assert.equal(computedTopicLabel.value, "Test topic");
|
assert.equal(computedTopicLabel.value, "Test topic");
|
||||||
|
|
||||||
const postLabel = computedLabels[5];
|
const postLabel = computedLabels[5];
|
||||||
assert.equal(postLabel.mainProperty, "post_raw");
|
assert.equal(postLabel.mainProperty, "post_raw");
|
||||||
assert.equal(postLabel.sortProperty, "post_raw");
|
assert.equal(postLabel.sortProperty, "post_raw");
|
||||||
assert.equal(postLabel.title, "Post");
|
assert.equal(postLabel.title, "Post");
|
||||||
|
assert.equal(postLabel.type, "post");
|
||||||
const computedPostLabel = postLabel.compute(row);
|
const computedPostLabel = postLabel.compute(row);
|
||||||
assert.equal(
|
assert.equal(
|
||||||
computedPostLabel.formatedValue,
|
computedPostLabel.formatedValue,
|
||||||
"<a href='/t/-/2/3'>This is the beginning of</a>"
|
"<a href='/t/-/2/3'>This is the beginning of</a>"
|
||||||
);
|
);
|
||||||
assert.equal(computedPostLabel.type, "post");
|
|
||||||
assert.equal(computedPostLabel.value, "This is the beginning of");
|
assert.equal(computedPostLabel.value, "This is the beginning of");
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user