Skip to content

Commit

Permalink
handle pluralization for vingle values
Browse files Browse the repository at this point in the history
  • Loading branch information
ZakharA committed Oct 20, 2024
1 parent 13aec54 commit 94106df
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 26 deletions.
58 changes: 38 additions & 20 deletions src/plugins/field_formats/common/constants/duration_formats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,85 +79,103 @@ const inputFormats = [
},
];
const DEFAULT_OUTPUT_FORMAT = {
text: i18n.translate('fieldFormats.duration.outputFormats.humanize.approximate', {
defaultMessage: 'Human-readable (approximate)',
text: (value: string) =>
i18n.translate('fieldFormats.duration.outputFormats.humanize.approximate', {
defaultMessage: 'Human-readable (approximate)',
}),
method: 'humanize',
};
const outputFormats = [
{ ...DEFAULT_OUTPUT_FORMAT },
{
text: i18n.translate('fieldFormats.duration.outputFormats.humanize.precise', {
defaultMessage: 'Human-readable (precise)',
text: (value: string) =>
i18n.translate('fieldFormats.duration.outputFormats.humanize.precise', {
defaultMessage: 'Human-readable (precise)',
}),
method: 'humanizePrecise',
},
{
text: i18n.translate('fieldFormats.duration.outputFormats.asMilliseconds', {
defaultMessage: 'Milliseconds',
text: (value: string) =>
i18n.translate('fieldFormats.duration.outputFormats.asMilliseconds', {
defaultMessage: '{value, plural, one {Millisecond} other {Milliseconds}}',
values: { value },
}),
shortText: i18n.translate('fieldFormats.duration.outputFormats.asMilliseconds.short', {
defaultMessage: 'ms',
}),
method: 'asMilliseconds',
},
{
text: i18n.translate('fieldFormats.duration.outputFormats.asSeconds', {
defaultMessage: 'Seconds',
text: (value: string) =>
i18n.translate('fieldFormats.duration.outputFormats.asSeconds', {
defaultMessage: '{value, plural, one {Second} other {Seconds}}',
values: { value },
}),
shortText: i18n.translate('fieldFormats.duration.outputFormats.asSeconds.short', {
defaultMessage: 's',
}),
method: 'asSeconds',
},
{
text: i18n.translate('fieldFormats.duration.outputFormats.asMinutes', {
defaultMessage: 'Minutes',
text: (value: string) =>
i18n.translate('fieldFormats.duration.outputFormats.asMinutes', {
defaultMessage: '{value, plural, one {minute} other {minutes}}',
values: { value },
}),
shortText: i18n.translate('fieldFormats.duration.outputFormats.asMinutes.short', {
defaultMessage: 'min',
}),
method: 'asMinutes',
},
{
text: i18n.translate('fieldFormats.duration.outputFormats.asHours', {
defaultMessage: 'Hours',
text: (value: string) =>
i18n.translate('fieldFormats.duration.outputFormats.asHours', {
defaultMessage: '{value, plural, one {Hour} other {Hours}}',
values: { value },
}),
shortText: i18n.translate('fieldFormats.duration.outputFormats.asHours.short', {
defaultMessage: 'h',
}),
method: 'asHours',
},
{
text: i18n.translate('fieldFormats.duration.outputFormats.asDays', {
defaultMessage: 'Days',
text: (value: string) =>
i18n.translate('fieldFormats.duration.outputFormats.asDays', {
defaultMessage: '{value, plural, one {Day} other {Days}}',
values: { value },
}),
shortText: i18n.translate('fieldFormats.duration.outputFormats.asDays.short', {
defaultMessage: 'd',
}),
method: 'asDays',
},
{
text: i18n.translate('fieldFormats.duration.outputFormats.asWeeks', {
defaultMessage: 'Weeks',
text: (value: string) =>
i18n.translate('fieldFormats.duration.outputFormats.asWeeks', {
defaultMessage: '{value, plural, one {Week} other {Weeks}}',
values: { value },
}),
shortText: i18n.translate('fieldFormats.duration.outputFormats.asWeeks.short', {
defaultMessage: 'w',
}),
method: 'asWeeks',
},
{
text: i18n.translate('fieldFormats.duration.outputFormats.asMonths', {
defaultMessage: 'Months',
text: (value: string) =>
i18n.translate('fieldFormats.duration.outputFormats.asMonths', {
defaultMessage: '{value, plural, one {Month} other {Months}}',
values: { value },
}),
shortText: i18n.translate('fieldFormats.duration.outputFormats.asMonths.short', {
defaultMessage: 'mon',
}),
method: 'asMonths',
},
{
text: i18n.translate('fieldFormats.duration.outputFormats.asYears', {
defaultMessage: 'Years',
text: (value: string) =>
i18n.translate('fieldFormats.duration.outputFormats.asYears', {
defaultMessage: '{value, plural, one {Year} other {Years}}',
values: { value },
}),
shortText: i18n.translate('fieldFormats.duration.outputFormats.asYears.short', {
defaultMessage: 'y',
Expand Down
144 changes: 142 additions & 2 deletions src/plugins/field_formats/common/converters/duration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,99 @@ describe('Duration Format', () => {
],
});

testCase({
inputFormat: 'minutes',
outputFormat: 'asHours',
outputPrecision: undefined,
showSuffix: true,
fixtures: [
{
input: -60,
output: '-1.00 hour',
},
{
input: 60,
output: '1.00 hour',
},
{
input: 125,
output: '2.08 hours',
},
],
});

testCase({
inputFormat: 'minutes',
outputFormat: 'asDays',
outputPrecision: undefined,
showSuffix: true,
fixtures: [
{
input: -1440,
output: '-1.00 day',
},
{
input: 1440,
output: '1.00 day',
},
{
input: 2880,
output: '2.00 days',
},
],
});

testCase({
inputFormat: 'hours',
outputFormat: 'asWeeks',
outputPrecision: undefined,
showSuffix: true,
fixtures: [
{
input: 168,
output: '1.00 week',
},
{
input: 336,
output: '2.00 weeks',
},
],
});

testCase({
inputFormat: 'hours',
outputFormat: 'asMonths',
outputPrecision: undefined,
showSuffix: true,
fixtures: [
{
input: 730.56,
output: '1.00 month',
},
{
input: 1461.11,
output: '2.00 months',
},
],
});

testCase({
inputFormat: 'hours',
outputFormat: 'asYears',
outputPrecision: undefined,
showSuffix: true,
fixtures: [
{
input: 8760,
output: '1.00 year',
},
{
input: 17520,
output: '2.00 years',
},
],
});

testCase({
inputFormat: 'seconds',
outputFormat: 'asSeconds',
Expand Down Expand Up @@ -137,13 +230,52 @@ describe('Duration Format', () => {
input: -60,
output: '-60 seconds',
},
{
input: 1,
output: '1 second',
},
{
input: -32.333,
output: '-32 seconds',
},
],
});

testCase({
inputFormat: 'nanoseconds',
outputFormat: 'asMilliseconds',
outputPrecision: 0,
showSuffix: true,
fixtures: [
{
input: 1000000,
output: '1 millisecond',
},
{
input: 2000000,
output: '2 milliseconds',
},
],
});

testCase({
inputFormat: 'seconds',
outputFormat: 'asMinutes',
outputPrecision: 2,
showSuffix: true,
useShortSuffix: false,
fixtures: [
{
input: 60,
output: '1.00 minute',
},
{
input: 120,
output: '2.00 minutes',
},
],
});

testCase({
inputFormat: 'nanoseconds',
outputFormat: 'humanizePrecise',
Expand Down Expand Up @@ -253,7 +385,7 @@ describe('Duration Format', () => {
},
{
input: 1,
output: '1.00 seconds',
output: '1.00 second',
},
{
input: 12,
Expand All @@ -275,6 +407,14 @@ describe('Duration Format', () => {
input: 3857,
output: '1.07 hours',
},
{
input: 3600,
output: '1.00 hour',
},
{
input: 86400,
output: '1.00 day',
},
{
input: 123292,
output: '1.43 days',
Expand Down Expand Up @@ -422,7 +562,7 @@ describe('Duration Format', () => {
},
{
input: 604800,
output: '1.00 weeks',
output: '1.00 week',
},
// 1 week and 3 and a half days
{
Expand Down
13 changes: 9 additions & 4 deletions src/plugins/field_formats/common/converters/duration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export class DurationFormat extends FieldFormat {
const precise = human || humanPrecise ? formatted : Number(formatted).toFixed(outputPrecision);
const type = DURATION_OUTPUT_FORMATS.find(({ method }) => method === outputFormat);

const unitText = useShortSuffix ? type?.shortText : type?.text.toLowerCase();
const unitText = useShortSuffix ? type?.shortText : type?.text(precise).toLowerCase();

const suffix = showSuffix && unitText && !human ? `${includeSpace}${unitText}` : '';

Expand Down Expand Up @@ -131,17 +131,22 @@ function formatDurationHumanPrecise(
if (!duration || !duration.isValid()) return;
const valueInSeconds = duration.as('seconds');

const getUnitText = (method: string) => {
const getUnitText = (method: string, unitValue: string) => {
const type = DURATION_OUTPUT_FORMATS.find(({ method: methodT }) => method === methodT);
return useShortSuffix ? type?.shortText : type?.text.toLowerCase();
return useShortSuffix ? type?.shortText : type?.text(unitValue).toLowerCase();
};

for (const unit of units) {
const unitValue = valueInSeconds / unit.seconds;
if (unitValue >= 1 || unit === units[units.length - 1]) {
// return a value if it's the first iteration where the value > 1, or the last iteration
const prefix = negativeValue ? '-' : '';
return prefix + unitValue.toFixed(outputPrecision) + includeSpace + getUnitText(unit.method);
return (
prefix +
unitValue.toFixed(outputPrecision) +
includeSpace +
getUnitText(unit.method, unitValue.toFixed(outputPrecision))
);
}
}
}

0 comments on commit 94106df

Please sign in to comment.