Skip to content

Commit 38c8093

Browse files
authored
Merge pull request #2852 from Brain-up/feat/localize-plots-weekdays-months
Use correct localization for plots (weekdays and months)
2 parents a7e9718 + 77fd116 commit 38c8093

7 files changed

Lines changed: 172 additions & 5 deletions

File tree

frontend/app/components/login-form/index.gts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Router from '@ember/routing/router-service';
77
import Session from 'ember-simple-auth/services/session';
88
import IntlService from 'ember-intl/services/intl';
99
import NetworkService from 'brn/services/network';
10+
import type TasksManagerService from 'brn/services/tasks-manager';
1011
import { LinkTo } from '@ember/routing';
1112
import { on } from '@ember/modifier';
1213
import { t } from 'ember-intl';
@@ -27,6 +28,7 @@ export default class LoginFormComponent extends Component {
2728
@service('router') router!: Router;
2829
@service('network') network!: NetworkService;
2930
@service('intl') intl!: IntlService;
31+
@service('tasks-manager') tasksManager!: TasksManagerService;
3032

3133
@tracked login: string | undefined = undefined;
3234
@tracked password: string | undefined = undefined;
@@ -75,7 +77,10 @@ export default class LoginFormComponent extends Component {
7577
password,
7678
);
7779
await timeout(500);
78-
await this.network.loadCurrentUser();
80+
await Promise.all([
81+
this.network.loadCurrentUser(),
82+
this.tasksManager.loadTodayCompletedExercises(),
83+
]);
7984
} catch (error) {
8085
let key = '';
8186
if (error.responseJSON) {

frontend/app/components/statistics/index.gts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { UserYearlyStatistics as UserYearlyStatisticsModel } from 'brn/sche
44
import NetworkService from 'brn/services/network';
55
// eslint-disable-next-line @typescript-eslint/no-unused-vars
66
import { service } from '@ember/service';
7+
import type IntlService from 'ember-intl/services/intl';
78
import { DateTime } from 'luxon';
89
// eslint-disable-next-line @typescript-eslint/no-unused-vars
910
import { tracked } from '@glimmer/tracking';
@@ -30,6 +31,7 @@ interface StatisticsSignature {
3031
export default class StatisticsComponent extends Component<StatisticsSignature> {
3132
@service('network') network!: NetworkService;
3233
@service('store') store!: Store;
34+
@service('intl') intl!: IntlService;
3335

3436
@tracked selectedMonth: DateTime =
3537
this.args.initialSelectedMonth || DateTime.now();
@@ -42,7 +44,7 @@ export default class StatisticsComponent extends Component<StatisticsSignature>
4244
@tracked isLoadingMonthlyDetail = false;
4345

4446
get monthLabel(): string {
45-
return this.selectedMonth.toFormat('LLLL yyyy');
47+
return this.selectedMonth.reconfigure({ locale: this.intl.primaryLocale }).toFormat('LLLL yyyy');
4648
}
4749

4850
getWeekTimeTrackData = dropTask(async () => {

frontend/app/components/statistics/month-time-track-item/index.gts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import './index.css';
22
import type { TOC } from '@ember/component/template-only';
3+
import type { DateTime } from 'luxon';
34
import { t } from 'ember-intl';
5+
import localeMonth from 'brn/helpers/locale-month';
46

57
interface MonthTimeTrackData {
68
progress: string;
79
time: string;
810
days: number;
911
month: string;
12+
date: DateTime;
1013
year: number;
1114
}
1215

@@ -46,7 +49,7 @@ const StatisticsMonthTimeTrackItem: TOC<Signature> = <template>
4649
</div>
4750
<div class="date">
4851
<div class="month">
49-
{{@data.month}}
52+
{{localeMonth @data.date}}
5053
</div>
5154
<div class="year">
5255
{{@data.year}}

frontend/app/components/statistics/week-time-track/index.gts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import { secondsTo } from 'brn/utils/seconds-to';
1818
import { isNone } from '@ember/utils';
1919
import didInsert from '@ember/render-modifiers/modifiers/did-insert';
2020
import didUpdate from '@ember/render-modifiers/modifiers/did-update';
21+
import { service } from '@ember/service';
22+
import type IntlService from 'ember-intl/services/intl';
2123
import { t } from 'ember-intl';
2224
import LoadingSpinner from 'brn/components/loading-spinner';
2325
import StatisticsBarChart from 'brn/components/statistics/bar-chart';
@@ -49,6 +51,8 @@ interface WeekTimeTrackSignature {
4951
export default class WeekTimeTrackComponent extends Component<WeekTimeTrackSignature> {
5052
private static readonly EXERCISING_TIME_NORM_IN_S = 20 * 60;
5153

54+
@service('intl') intl!: IntlService;
55+
5256
@tracked private chartData?: IWeekChartDataItem[];
5357

5458
get barOptions(): BarOptionsType {
@@ -129,6 +133,7 @@ export default class WeekTimeTrackComponent extends Component<WeekTimeTrackSigna
129133
let lastDay = null;
130134
let lastDayIndex = -1;
131135
let dayNumber: number;
136+
const locale = this.intl.primaryLocale;
132137
for (
133138
dayNumber = 1;
134139
dayNumber <= this.selectedMonth.daysInMonth;
@@ -145,13 +150,14 @@ export default class WeekTimeTrackComponent extends Component<WeekTimeTrackSigna
145150
this.chartData.push(
146151
dataItem
147152
? {
148-
x: dataItem.date.weekdayShort.slice(0, 2),
153+
x: dataItem.date.reconfigure({ locale }).weekdayShort.slice(0, 2),
149154
y: dataItem.exercisingTimeSeconds,
150155
progress: dataItem.progress,
151156
}
152157
: {
153158
x: this.selectedMonth
154159
.set({ day: dayNumber })
160+
.reconfigure({ locale })
155161
.weekdayShort.slice(0, 2),
156162
y: 0,
157163
progress: PROGRESS.BAD,
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import Helper from '@ember/component/helper';
2+
import { service } from '@ember/service';
3+
import type IntlService from 'ember-intl/services/intl';
4+
import type { DateTime } from 'luxon';
5+
6+
export default class LocaleMonthHelper extends Helper<{
7+
Args: { Positional: [DateTime]; Named: { format?: string } };
8+
Return: string;
9+
}> {
10+
@service('intl') intl!: IntlService;
11+
12+
compute([date]: [DateTime], { format }: { format?: string } = {}): string {
13+
return date.reconfigure({ locale: this.intl.primaryLocale }).toFormat(format ?? 'LLLL');
14+
}
15+
}

frontend/tests/integration/components/statistics/month-time-track-item/component-test.gts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,5 +84,51 @@ module(
8484
.dom('[data-test-month-track-item]')
8585
.hasNoClass('selected', 'it is unselected');
8686
});
87+
88+
test('it displays localized month name for en-us', async function (assert) {
89+
const itemData: any = {
90+
progress: PROGRESS.GOOD,
91+
time: '01:00:00',
92+
days: 3,
93+
month: 'June',
94+
year: 2021,
95+
date: DateTime.fromISO('2021-06-15'),
96+
};
97+
98+
this.set('itemData', itemData);
99+
100+
const self = this;
101+
102+
await render(
103+
<template><StatisticsMonthTimeTrackItem @data={{self.itemData}} /></template>
104+
);
105+
106+
assert.dom('.month').hasText('June', 'month is displayed in English');
107+
});
108+
109+
module('with ru-ru locale', function (hooks) {
110+
setupIntl(hooks, 'ru-ru');
111+
112+
test('it displays localized month name for ru-ru', async function (assert) {
113+
const itemData: any = {
114+
progress: PROGRESS.GOOD,
115+
time: '01:00:00',
116+
days: 3,
117+
month: 'June',
118+
year: 2021,
119+
date: DateTime.fromISO('2021-06-15'),
120+
};
121+
122+
this.set('itemData', itemData);
123+
124+
const self = this;
125+
126+
await render(
127+
<template><StatisticsMonthTimeTrackItem @data={{self.itemData}} /></template>
128+
);
129+
130+
assert.dom('.month').hasText('июнь', 'month is displayed in Russian');
131+
});
132+
});
87133
},
88134
);

frontend/tests/integration/components/statistics/week-time-track/component-test.gts

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { module, test } from 'qunit';
33
import { setupIntl } from 'ember-intl/test-support';
44
import { setupRenderingTest } from 'ember-qunit';
5-
import { render } from '@ember/test-helpers';
5+
import { render, settled } from '@ember/test-helpers';
66
import { DateTime } from 'luxon';
77
import StatisticsWeekTimeTrack from 'brn/components/statistics/week-time-track';
88

@@ -79,5 +79,95 @@ module(
7979
.dom('[data-test-empty-data]')
8080
.exists('empty data description is shown');
8181
});
82+
83+
test('it uses localized weekday labels for en-us', async function (assert) {
84+
const TRACK_DATA = [
85+
{
86+
date: DateTime.fromISO('2021-06-07'), // Monday
87+
exercisingTimeSeconds: 600,
88+
progress: 'GOOD',
89+
},
90+
{
91+
date: DateTime.fromISO('2021-06-08'), // Tuesday
92+
exercisingTimeSeconds: 300,
93+
progress: 'BAD',
94+
},
95+
];
96+
97+
this.set('isLoadingWeekTimeTrackData', false);
98+
99+
const self = this;
100+
101+
await render(<template><StatisticsWeekTimeTrack
102+
@isLoading={{self.isLoadingWeekTimeTrackData}}
103+
@selectedMonth={{self.selectedMonth}}
104+
@data={{self.rawWeekTimeTrackData}}
105+
/></template>);
106+
107+
const selectedMonth = DateTime.fromISO('2021-06-23');
108+
this.set('selectedMonth', selectedMonth);
109+
this.set('rawWeekTimeTrackData', TRACK_DATA);
110+
await settled();
111+
112+
const tickTexts = this.element.querySelectorAll('.bb-axis-x .tick text');
113+
const labels = Array.from(tickTexts).map((el) => {
114+
const tspan = el.querySelector('tspan');
115+
return tspan ? tspan.textContent?.trim() : el.textContent?.trim();
116+
});
117+
118+
const englishWeekdays = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU'];
119+
const englishLabels = labels.filter((label) =>
120+
englishWeekdays.includes(label ?? ''),
121+
);
122+
// June 2021 has 30 days, so all 30 tick labels should be English weekday abbrevs
123+
assert.strictEqual(englishLabels.length, 30, 'all 30 day labels are English weekday abbreviations');
124+
});
125+
126+
module('with ru-ru locale', function (hooks) {
127+
setupIntl(hooks, 'ru-ru');
128+
129+
test('it uses localized weekday labels for ru-ru', async function (assert) {
130+
const TRACK_DATA = [
131+
{
132+
date: DateTime.fromISO('2021-06-07'), // Monday
133+
exercisingTimeSeconds: 600,
134+
progress: 'GOOD',
135+
},
136+
{
137+
date: DateTime.fromISO('2021-06-08'), // Tuesday
138+
exercisingTimeSeconds: 300,
139+
progress: 'BAD',
140+
},
141+
];
142+
143+
this.set('isLoadingWeekTimeTrackData', false);
144+
145+
const self = this;
146+
147+
await render(<template><StatisticsWeekTimeTrack
148+
@isLoading={{self.isLoadingWeekTimeTrackData}}
149+
@selectedMonth={{self.selectedMonth}}
150+
@data={{self.rawWeekTimeTrackData}}
151+
/></template>);
152+
153+
const selectedMonth = DateTime.fromISO('2021-06-23');
154+
this.set('selectedMonth', selectedMonth);
155+
this.set('rawWeekTimeTrackData', TRACK_DATA);
156+
await settled();
157+
158+
const tickTexts = this.element.querySelectorAll('.bb-axis-x .tick text');
159+
const labels = Array.from(tickTexts).map((el) => {
160+
const tspan = el.querySelector('tspan');
161+
return tspan ? tspan.textContent?.trim() : el.textContent?.trim();
162+
});
163+
164+
const russianWeekdays = ['ПН', 'ВТ', 'СР', 'ЧТ', 'ПТ', 'СБ', 'ВС'];
165+
const russianLabels = labels.filter((label) =>
166+
russianWeekdays.includes(label ?? ''),
167+
);
168+
// June 2021 has 30 days, so all 30 tick labels should be Russian weekday abbrevs
169+
assert.strictEqual(russianLabels.length, 30, 'all 30 day labels are Russian weekday abbreviations');
170+
});
171+
});
82172
},
83173
);

0 commit comments

Comments
 (0)