Skip to content
Snippets Groups Projects
Commit 80a9e61f authored by Michael Shen's avatar Michael Shen
Browse files

translation

parent d1192171
No related branches found
No related tags found
No related merge requests found
......@@ -11,7 +11,7 @@ import Icon from "metabase/components/Icon";
export default class Calendar extends Component {
constructor(props) {
super(props);
moment.locale(t `moment_locale`);
this.state = {
current: moment(props.initial || undefined),
};
......
......@@ -3,258 +3,259 @@ import inflection from "inflection";
import { formatDateTimeWithUnit } from "metabase/lib/formatting";
import { parseTimestamp } from "metabase/lib/time";
import { t } from "c-3po";
export const DATETIME_UNITS = [
// "default",
"minute",
"hour",
"day",
"week",
"month",
"quarter",
"year",
// "minute-of-hour",
"hour-of-day",
"day-of-week",
"day-of-month",
// "day-of-year",
"week-of-year",
"month-of-year",
"quarter-of-year",
// "default",
t `minute`,
t `hour`,
t `day`,
t `week`,
t `month`,
t `quarter`,
t `year`,
// t `minute-of-hour",
t `hour-of-day`,
t `day-of-week`,
t `day-of-month`,
// t `day-of-year",
t `week-of-year`,
t `month-of-year`,
t `quarter-of-year`,
];
export function computeFilterTimeRange(filter) {
let expandedFilter;
if (filter[0] === "time-interval") {
expandedFilter = expandTimeIntervalFilter(filter);
} else {
expandedFilter = filter;
}
let expandedFilter;
if (filter[0] === "time-interval") {
expandedFilter = expandTimeIntervalFilter(filter);
} else {
expandedFilter = filter;
}
let [operator, field, ...values] = expandedFilter;
let bucketing = parseFieldBucketing(field, "day");
let [operator, field, ...values] = expandedFilter;
let bucketing = parseFieldBucketing(field, "day");
let start, end;
if (operator === "=" && values[0]) {
let point = absolute(values[0]);
start = point.clone().startOf(bucketing);
end = point.clone().endOf(bucketing);
} else if (operator === ">" && values[0]) {
start = absolute(values[0]).endOf(bucketing);
end = max();
} else if (operator === "<" && values[0]) {
start = min();
end = absolute(values[0]).startOf(bucketing);
} else if (operator === "between" && values[0] && values[1]) {
start = absolute(values[0]).startOf(bucketing);
end = absolute(values[1]).endOf(bucketing);
}
let start, end;
if (operator === "=" && values[0]) {
let point = absolute(values[0]);
start = point.clone().startOf(bucketing);
end = point.clone().endOf(bucketing);
} else if (operator === ">" && values[0]) {
start = absolute(values[0]).endOf(bucketing);
end = max();
} else if (operator === "<" && values[0]) {
start = min();
end = absolute(values[0]).startOf(bucketing);
} else if (operator === "between" && values[0] && values[1]) {
start = absolute(values[0]).startOf(bucketing);
end = absolute(values[1]).endOf(bucketing);
}
return [start, end];
return [start, end];
}
export function expandTimeIntervalFilter(filter) {
let [operator, field, n, unit] = filter;
let [operator, field, n, unit] = filter;
if (operator !== "time-interval") {
throw new Error("translateTimeInterval expects operator 'time-interval'");
}
if (operator !== "time-interval") {
throw new Error("translateTimeInterval expects operator 'time-interval'");
}
if (n === "current") {
n = 0;
} else if (n === "last") {
n = -1;
} else if (n === "next") {
n = 1;
}
if (n === "current") {
n = 0;
} else if (n === "last") {
n = -1;
} else if (n === "next") {
n = 1;
}
field = ["datetime-field", field, "as", unit];
field = ["datetime-field", field, "as", unit];
if (n < -1) {
return [
"between",
field,
["relative-datetime", n - 1, unit],
["relative-datetime", -1, unit],
];
} else if (n > 1) {
return [
"between",
field,
["relative-datetime", 1, unit],
["relative-datetime", n, unit],
];
} else if (n === 0) {
return ["=", field, ["relative-datetime", "current"]];
} else {
return ["=", field, ["relative-datetime", n, unit]];
}
if (n < -1) {
return [
"between",
field, ["relative-datetime", n - 1, unit],
["relative-datetime", -1, unit],
];
} else if (n > 1) {
return [
"between",
field, ["relative-datetime", 1, unit],
["relative-datetime", n, unit],
];
} else if (n === 0) {
return ["=", field, ["relative-datetime", "current"]];
} else {
return ["=", field, ["relative-datetime", n, unit]];
}
}
export function generateTimeFilterValuesDescriptions(filter) {
let [operator, field, ...values] = filter;
let bucketing = parseFieldBucketing(field);
let [operator, field, ...values] = filter;
let bucketing = parseFieldBucketing(field);
if (operator === "time-interval") {
let [n, unit] = values;
return generateTimeIntervalDescription(n, unit);
} else {
return values.map(value => generateTimeValueDescription(value, bucketing));
}
if (operator === "time-interval") {
let [n, unit] = values;
return generateTimeIntervalDescription(n, unit);
} else {
return values.map(value => generateTimeValueDescription(value, bucketing));
}
}
export function generateTimeIntervalDescription(n, unit) {
if (unit === "day") {
switch (n) {
case "current":
case 0:
return ["Today"];
case "next":
case 1:
return ["Tomorrow"];
case "last":
case -1:
return ["Yesterday"];
if (unit === "day") {
switch (n) {
case "current":
case 0:
return [t `Today`];
case "next":
case 1:
return [t `Tomorrow`];
case "last":
case -1:
return [t `Yesterday`];
}
}
}
if (!unit && n === 0) {
return "Today";
} // ['relative-datetime', 'current'] is a legal MBQL form but has no unit
if (!unit && n === 0) {
return t `Today`;
} // ['relative-datetime', 'current'] is a legal MBQL form but has no unit
unit = inflection.capitalize(unit);
if (typeof n === "string") {
if (n === "current") {
n = "this";
}
return [inflection.capitalize(n) + " " + unit];
} else {
if (n < 0) {
return ["Past " + -n + " " + inflection.inflect(unit, -n)];
} else if (n > 0) {
return ["Next " + n + " " + inflection.inflect(unit, n)];
unit = inflection.capitalize(unit);
if (typeof n === "string") {
if (n === "current") {
n = "this";
}
return [inflection.capitalize(n) + " " + unit];
} else {
return ["This " + unit];
if (n < 0) {
return [t `Past ` + -n + " " + inflection.inflect(unit, -n)];
} else if (n > 0) {
return [t `Next ` + n + " " + inflection.inflect(unit, n)];
} else {
return [t `This ` + unit];
}
}
}
}
export function generateTimeValueDescription(value, bucketing) {
if (typeof value === "string") {
const m = parseTimestamp(value, bucketing);
if (bucketing) {
return formatDateTimeWithUnit(value, bucketing);
} else if (m.hours() || m.minutes()) {
return m.format("MMMM D, YYYY hh:mm a");
} else {
return m.format("MMMM D, YYYY");
}
} else if (Array.isArray(value) && value[0] === "relative-datetime") {
let n = value[1];
let unit = value[2];
if (typeof value === "string") {
const m = parseTimestamp(value, bucketing);
if (bucketing) {
return formatDateTimeWithUnit(value, bucketing);
} else if (m.hours() || m.minutes()) {
return m.locale(t `moment_locale`).format("MMMM D, YYYY hh:mm a");
} else {
return m.locale(t `moment_locale`).format("MMMM D, YYYY");
}
} else if (Array.isArray(value) && value[0] === "relative-datetime") {
let n = value[1];
let unit = value[2];
if (n === "current") {
n = 0;
unit = bucketing;
}
if (n === "current") {
n = 0;
unit = bucketing;
}
if (bucketing === unit) {
return generateTimeIntervalDescription(n, unit);
if (bucketing === unit) {
return generateTimeIntervalDescription(n, unit);
} else {
// FIXME: what to do if the bucketing and unit don't match?
if (n === 0) {
return t `Now`;
} else {
return (
Math.abs(n) +
" " +
inflection.inflect(unit, Math.abs(n)) +
(n < 0 ? t ` ago` : t ` from now`)
);
}
}
} else {
// FIXME: what to do if the bucketing and unit don't match?
if (n === 0) {
return "Now";
} else {
return (
Math.abs(n) +
" " +
inflection.inflect(unit, Math.abs(n)) +
(n < 0 ? " ago" : " from now")
);
}
console.warn("Unknown datetime format", value);
return t `[Unknown]`;
}
} else {
console.warn("Unknown datetime format", value);
return "[Unknown]";
}
}
export function formatBucketing(bucketing = "") {
let words = bucketing.split("-");
words[0] = inflection.capitalize(words[0]);
return words.join(" ");
let words = bucketing.split("-");
words[0] = inflection.capitalize(words[0]);
return words.join(" ");
}
export function absolute(date) {
if (typeof date === "string") {
return moment(date);
} else if (Array.isArray(date) && date[0] === "relative-datetime") {
return moment().add(date[1], date[2]);
} else {
console.warn("Unknown datetime format", date);
}
if (typeof date === "string") {
return moment(date);
} else if (Array.isArray(date) && date[0] === "relative-datetime") {
return moment().add(date[1], date[2]);
} else {
console.warn("Unknown datetime format", date);
}
}
export function parseFieldBucketing(field, defaultUnit = null) {
if (Array.isArray(field)) {
if (field[0] === "datetime-field") {
if (field.length === 4) {
// Deprecated legacy format [datetime-field field "as" unit], see DatetimeFieldDimension for more info
return field[3];
} else {
// Current format [datetime-field field unit]
return field[2];
}
}
if (field[0] === "fk->" || field[0] === "field-id") {
return defaultUnit;
}
if (field[0] === "field-literal") {
return defaultUnit;
} else {
console.warn("Unknown field format", field);
if (Array.isArray(field)) {
if (field[0] === "datetime-field") {
if (field.length === 4) {
// Deprecated legacy format [datetime-field field "as" unit], see DatetimeFieldDimension for more info
return field[3];
} else {
// Current format [datetime-field field unit]
return field[2];
}
}
if (field[0] === "fk->" || field[0] === "field-id") {
return defaultUnit;
}
if (field[0] === "field-literal") {
return defaultUnit;
} else {
console.warn("Unknown field format", field);
}
}
}
return defaultUnit;
return defaultUnit;
}
// returns field with "datetime-field" removed
export function parseFieldTarget(field) {
if (field[0] === "datetime-field") {
return field[1];
} else {
return field;
}
if (field[0] === "datetime-field") {
return field[1];
} else {
return field;
}
}
export function parseFieldTargetId(field) {
if (Number.isInteger(field)) {
return field;
}
if (Array.isArray(field)) {
if (field[0] === "field-id") {
return field[1];
}
if (field[0] === "fk->") {
return field[1];
}
if (field[0] === "datetime-field") {
return parseFieldTargetId(field[1]);
if (Number.isInteger(field)) {
return field;
}
if (field[0] === "field-literal") {
return field;
if (Array.isArray(field)) {
if (field[0] === "field-id") {
return field[1];
}
if (field[0] === "fk->") {
return field[1];
}
if (field[0] === "datetime-field") {
return parseFieldTargetId(field[1]);
}
if (field[0] === "field-literal") {
return field;
}
}
}
console.warn("Unknown field format", field);
return field;
console.warn("Unknown field format", field);
return field;
}
// 271821 BC and 275760 AD and should be far enough in the past/future
function max() {
return moment(new Date(864000000000000));
return moment(new Date(864000000000000));
}
function min() {
return moment(new Date(-864000000000000));
}
return moment(new Date(-864000000000000));
}
\ No newline at end of file
......@@ -58,7 +58,7 @@ export default class CategoryWidget extends Component {
static format(values, fieldValues) {
if (Array.isArray(values) && values.length > 1) {
return `${values.length} selections`;
return `${values.length}` + t `selections`;
} else {
return getHumanReadableValue(values, fieldValues);
}
......
......@@ -54,7 +54,7 @@ export default class ParameterFieldWidget extends Component<*, Props, State> {
static format(value, field) {
value = normalizeValue(value);
if (value.length > 1) {
return `${value.length} selections`;
return `${value.length}` + t`selections`;
} else {
return <RemappedValue value={value[0]} column={field} />;
}
......
......@@ -75,7 +75,7 @@ export const OperatorFilter = ({
let formattedValues;
// $FlowFixMe: not understanding maxDisplayValues is provided by defaultProps
if (operator && operator.multi && values.length > maxDisplayValues) {
formattedValues = [values.length + " selections"];
formattedValues = [values.length + t`selections`];
} else if (dimension.field().isDate() && !dimension.field().isTime()) {
formattedValues = generateTimeFilterValuesDescriptions(filter);
} else {
......
......@@ -144,7 +144,7 @@ export default class SpecificDatePicker extends Component {
onClick={() => this.onChange(date, 12, 30)}
>
<Icon className="mr1" name="clock" />
Add a time
{t`Add a time`}
</div>
) : (
<HoursMinutesInput
......
{
:locales #{"en" "fr" "es" "nb" "pt" }
:locales #{"en" "fr" "es" "nb" "pt" "zh"}
:packages ["metabase"]
:bundle "metabase.Messages"
}
......@@ -235,19 +235,19 @@
(case unit
:day (date->interval-name parsed-timestamp
(t/date-midnight (year) (month) (day))
(t/days 1) "Today" "Yesterday")
(t/days 1) (tru "Today") (tru "Yesterday"))
:week (date->interval-name parsed-timestamp
(start-of-this-week)
(t/weeks 1) "This week" "Last week")
(t/weeks 1) (tru "This week") (tru "Last week"))
:month (date->interval-name parsed-timestamp
(t/date-midnight (year) (month))
(t/months 1) "This month" "Last month")
(t/months 1) (tru "This month") (tru "Last month"))
:quarter (date->interval-name parsed-timestamp
(start-of-this-quarter)
(t/months 3) "This quarter" "Last quarter")
(t/months 3) (tru "This quarter") (tru "Last quarter"))
:year (date->interval-name (t/date-midnight parsed-timestamp)
(t/date-midnight (year))
(t/years 1) "This year" "Last year")
(t/years 1) (tru "This year") (tru "Last year"))
nil)))
(defn- format-timestamp-pair
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment