FIX: Cast all numerical values in reports (#8087)
* FIX: Cast all numerical values in reports The backend can return some numerical values in report as strings. That results in unexpected order of values when sorting report tables. * Create `toNumber()` helper The `typeof` and `parseFloat` seem to be the fastest path: https://jsperf.com/number-vs-typeof-vs-parsefloat#results
This commit is contained in:
parent
73172f00d3
commit
1dcdcb5c31
|
@ -1,7 +1,11 @@
|
||||||
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 { fillMissingDates, formatUsername } from "discourse/lib/utilities";
|
import {
|
||||||
|
fillMissingDates,
|
||||||
|
formatUsername,
|
||||||
|
toNumber
|
||||||
|
} 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";
|
||||||
|
@ -374,14 +378,14 @@ const Report = Discourse.Model.extend({
|
||||||
|
|
||||||
_secondsLabel(value) {
|
_secondsLabel(value) {
|
||||||
return {
|
return {
|
||||||
value,
|
value: toNumber(value),
|
||||||
formatedValue: durationTiny(value)
|
formatedValue: durationTiny(value)
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
_percentLabel(value) {
|
_percentLabel(value) {
|
||||||
return {
|
return {
|
||||||
value,
|
value: toNumber(value),
|
||||||
formatedValue: value ? `${value}%` : "—"
|
formatedValue: value ? `${value}%` : "—"
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -394,14 +398,14 @@ const Report = Discourse.Model.extend({
|
||||||
const formatedValue = () => (formatNumbers ? number(value) : value);
|
const formatedValue = () => (formatNumbers ? number(value) : value);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
value,
|
value: toNumber(value),
|
||||||
formatedValue: value ? formatedValue() : "—"
|
formatedValue: value ? formatedValue() : "—"
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
_bytesLabel(value) {
|
_bytesLabel(value) {
|
||||||
return {
|
return {
|
||||||
value,
|
value: toNumber(value),
|
||||||
formatedValue: I18n.toHumanSize(value)
|
formatedValue: I18n.toHumanSize(value)
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
|
@ -599,8 +599,12 @@ export function clipboardData(e, canUpload) {
|
||||||
return { clipboard, types, canUpload, canPasteHtml };
|
return { clipboard, types, canUpload, canPasteHtml };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function toNumber(input) {
|
||||||
|
return typeof input === "number" ? input : parseFloat(input);
|
||||||
|
}
|
||||||
|
|
||||||
export function isNumeric(input) {
|
export function isNumeric(input) {
|
||||||
return !isNaN(parseFloat(input)) && isFinite(input);
|
return !isNaN(toNumber(input)) && isFinite(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fillMissingDates(data, startDate, endDate) {
|
export function fillMissingDates(data, startDate, endDate) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ let signups = {
|
||||||
yaxis: "Number of signups",
|
yaxis: "Number of signups",
|
||||||
description: "New account registrations for this period",
|
description: "New account registrations for this period",
|
||||||
data: [
|
data: [
|
||||||
{ x: "2018-06-16", y: 12 },
|
{ x: "2018-06-16", y: "12" },
|
||||||
{ x: "2018-06-17", y: 16 },
|
{ x: "2018-06-17", y: 16 },
|
||||||
{ x: "2018-06-18", y: 42 },
|
{ x: "2018-06-18", y: 42 },
|
||||||
{ x: "2018-06-19", y: 38 },
|
{ x: "2018-06-19", y: 38 },
|
||||||
|
@ -18,7 +18,7 @@ let signups = {
|
||||||
{ x: "2018-06-24", y: 17 },
|
{ x: "2018-06-24", y: 17 },
|
||||||
{ x: "2018-06-25", y: 27 },
|
{ x: "2018-06-25", y: 27 },
|
||||||
{ x: "2018-06-26", y: 32 },
|
{ x: "2018-06-26", y: 32 },
|
||||||
{ x: "2018-06-27", y: 7 }
|
{ x: "2018-06-27", y: "7" }
|
||||||
],
|
],
|
||||||
start_date: "2018-06-16T00:00:00Z",
|
start_date: "2018-06-16T00:00:00Z",
|
||||||
end_date: "2018-07-16T23:59:59Z",
|
end_date: "2018-07-16T23:59:59Z",
|
||||||
|
|
|
@ -398,7 +398,7 @@ QUnit.test("computed labels", assert => {
|
||||||
username: "joffrey",
|
username: "joffrey",
|
||||||
user_id: 1,
|
user_id: 1,
|
||||||
user_avatar: "/",
|
user_avatar: "/",
|
||||||
flag_count: 1876,
|
flag_count: "1876",
|
||||||
time_read: 287362,
|
time_read: 287362,
|
||||||
note: "This is a long note",
|
note: "This is a long note",
|
||||||
topic_id: 2,
|
topic_id: 2,
|
||||||
|
@ -470,7 +470,7 @@ QUnit.test("computed labels", assert => {
|
||||||
assert.equal(flagCountLabel.type, "number");
|
assert.equal(flagCountLabel.type, "number");
|
||||||
let computedFlagCountLabel = flagCountLabel.compute(row);
|
let computedFlagCountLabel = flagCountLabel.compute(row);
|
||||||
assert.equal(computedFlagCountLabel.formatedValue, "1.9k");
|
assert.equal(computedFlagCountLabel.formatedValue, "1.9k");
|
||||||
assert.equal(computedFlagCountLabel.value, 1876);
|
assert.strictEqual(computedFlagCountLabel.value, 1876);
|
||||||
computedFlagCountLabel = flagCountLabel.compute(row, {
|
computedFlagCountLabel = flagCountLabel.compute(row, {
|
||||||
formatNumbers: false
|
formatNumbers: false
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue