diff --git a/fittrackee_client/src/components/Common/StatsChart/index.vue b/fittrackee_client/src/components/Common/StatsChart/index.vue index 352f73e5..0016ad9f 100644 --- a/fittrackee_client/src/components/Common/StatsChart/index.vue +++ b/fittrackee_client/src/components/Common/StatsChart/index.vue @@ -145,7 +145,8 @@ props.sports, props.displayedSportIds, statistics.value, - props.user.imperial_units + props.user.imperial_units, + props.user.date_format ) ) diff --git a/fittrackee_client/src/utils/statistics.ts b/fittrackee_client/src/utils/statistics.ts index cee603d6..0574b645 100644 --- a/fittrackee_client/src/utils/statistics.ts +++ b/fittrackee_client/src/utils/statistics.ts @@ -14,6 +14,7 @@ import { subYears, } from 'date-fns' +import createI18n from '@/i18n' import { IChartDataset } from '@/types/chart' import { ISport } from '@/types/sports' import { @@ -23,14 +24,17 @@ import { TStatisticsDatasets, TStatisticsFromApi, } from '@/types/statistics' -import { incrementDate, getStartDate } from '@/utils/dates' +import { incrementDate, getStartDate, getDateFormat } from '@/utils/dates' +import { localeFromLanguage } from '@/utils/locales' import { sportColors } from '@/utils/sports' import { convertStatsDistance } from '@/utils/units' +const { locale } = createI18n.global + const dateFormats: Record> = { week: { api: 'yyyy-MM-dd', - chart: 'dd/MM/yyyy', + chart: 'MM/dd/yyyy', }, month: { api: 'yyyy-MM', @@ -135,7 +139,8 @@ export const formatStats = ( sports: ISport[], displayedSportsId: number[], apiStats: TStatisticsFromApi, - useImperialUnits: boolean + useImperialUnits: boolean, + userDateFormat: string ): IStatisticsChartData => { const dayKeys = getDateKeys(params, weekStartingMonday) const dateFormat = dateFormats[params.duration] @@ -151,7 +156,13 @@ export const formatStats = ( dayKeys.map((key) => { const date: string = format(key, dateFormat.api) - const label: string = format(key, dateFormat.chart) + const label: string = format( + key, + params.duration === 'week' + ? getDateFormat(userDateFormat, locale.value) + : dateFormat.chart, + { locale: localeFromLanguage[locale.value] } + ) labels.push(label) datasetKeys.map((datasetKey) => { datasets[datasetKey].map((dataset) => { diff --git a/fittrackee_client/tests/unit/utils/statistics.spec.ts b/fittrackee_client/tests/unit/utils/statistics.spec.ts index 90ea06ce..4084b065 100644 --- a/fittrackee_client/tests/unit/utils/statistics.spec.ts +++ b/fittrackee_client/tests/unit/utils/statistics.spec.ts @@ -2,6 +2,7 @@ import { assert } from 'chai' import { sports } from './fixtures' +import createI18n from '@/i18n' import { IStatisticsChartData, TStatisticsDatasets, @@ -15,6 +16,8 @@ import { updateChartParams, } from '@/utils/statistics' +const { locale } = createI18n.global + describe('getDateKeys (week starting Sunday)', () => { const testsParams = [ { @@ -353,7 +356,15 @@ describe('formatStats', () => { }, } assert.deepEqual( - formatStats(inputParams, false, sports, [], inputStats, false), + formatStats( + inputParams, + false, + sports, + [], + inputStats, + false, + 'MM/dd/yyyy' + ), expected ) }) @@ -416,7 +427,15 @@ describe('formatStats', () => { }, } assert.deepEqual( - formatStats(inputParams, false, sports, [2], inputStats, false), + formatStats( + inputParams, + false, + sports, + [2], + inputStats, + false, + 'MM/dd/yyyy' + ), expected ) }) @@ -479,7 +498,15 @@ describe('formatStats', () => { }, } assert.deepEqual( - formatStats(inputParams, false, sports, [], inputStats, false), + formatStats( + inputParams, + false, + sports, + [], + inputStats, + false, + 'MM/dd/yyyy' + ), expected ) }) @@ -581,7 +608,15 @@ describe('formatStats', () => { }, } assert.deepEqual( - formatStats(inputParams, false, sports, [1], inputStats, false), + formatStats( + inputParams, + false, + sports, + [1], + inputStats, + false, + 'MM/dd/yyyy' + ), expected ) }) @@ -685,13 +720,21 @@ describe('formatStats (duration)', () => { }, } assert.deepEqual( - formatStats(inputParams, false, sports, [1], inputStats, false), + formatStats( + inputParams, + false, + sports, + [1], + inputStats, + false, + 'MM/dd/yyyy' + ), expected ) }) - it("returns datasets when duration is 'year'", () => { + it("returns datasets when duration is 'month'", () => { const inputStats: TStatisticsFromApi = { - '2020': { + '2021-10': { 1: { average_speed: 12, nb_workouts: 1, @@ -701,7 +744,7 @@ describe('formatStats (duration)', () => { total_descent: 100, }, }, - '2021': { + '2021-11': { 1: { average_speed: 18, nb_workouts: 1, @@ -719,7 +762,7 @@ describe('formatStats (duration)', () => { total_descent: 200, }, }, - '2022': { + '2021-12': { 3: { average_speed: 8.64, nb_workouts: 2, @@ -731,19 +774,19 @@ describe('formatStats (duration)', () => { }, } const inputParams = { - duration: 'year', - start: new Date('January 1, 2020 00:00:00'), + duration: 'month', + start: new Date('October 1, 2021 00:00:00'), end: new Date('December 31, 2021 23:59:59.999'), } const expected: IStatisticsChartData = { - labels: ['2020', '2021'], + labels: ['10/2021', '11/2021', '12/2021'], datasets: { average_speed: [ { label: 'Cycling (Sport)', backgroundColor: ['#4c9792'], borderColor: ['#4c9792'], - data: [12, 18], + data: [12, 18, null], type: 'line', spanGaps: true, }, @@ -752,41 +795,49 @@ describe('formatStats (duration)', () => { { label: 'Cycling (Sport)', backgroundColor: ['#4c9792'], - data: [1, 1], + data: [1, 1, 0], }, ], total_distance: [ { label: 'Cycling (Sport)', backgroundColor: ['#4c9792'], - data: [10, 15], + data: [10, 15, 0], }, ], total_duration: [ { label: 'Cycling (Sport)', backgroundColor: ['#4c9792'], - data: [3000, 3500], + data: [3000, 3500, 0], }, ], total_ascent: [ { label: 'Cycling (Sport)', backgroundColor: ['#4c9792'], - data: [150, 250], + data: [150, 250, 0], }, ], total_descent: [ { label: 'Cycling (Sport)', backgroundColor: ['#4c9792'], - data: [100, 150], + data: [100, 150, 0], }, ], }, } assert.deepEqual( - formatStats(inputParams, false, sports, [1], inputStats, false), + formatStats( + inputParams, + false, + sports, + [1], + inputStats, + false, + 'MM/dd/yyyy' + ), expected ) }) @@ -838,7 +889,7 @@ describe('formatStats (duration)', () => { end: new Date('October 23, 2021 23:59:59.999'), } const expected: IStatisticsChartData = { - labels: ['03/10/2021', '10/10/2021', '17/10/2021'], + labels: ['10/03/2021', '10/10/2021', '10/17/2021'], datasets: { average_speed: [ { @@ -888,7 +939,15 @@ describe('formatStats (duration)', () => { }, } assert.deepEqual( - formatStats(inputParams, false, sports, [1], inputStats, false), + formatStats( + inputParams, + false, + sports, + [1], + inputStats, + false, + 'MM/dd/yyyy' + ), expected ) }) @@ -940,7 +999,7 @@ describe('formatStats (duration)', () => { end: new Date('October 24, 2021 23:59:59.999'), } const expected: IStatisticsChartData = { - labels: ['04/10/2021', '11/10/2021', '18/10/2021'], + labels: ['10/04/2021', '10/11/2021', '10/18/2021'], datasets: { average_speed: [ { @@ -990,12 +1049,20 @@ describe('formatStats (duration)', () => { }, } assert.deepEqual( - formatStats(inputParams, true, sports, [1], inputStats, false), + formatStats( + inputParams, + true, + sports, + [1], + inputStats, + false, + 'MM/dd/yyyy' + ), expected ) }) - it('returns datasets after conversion to imperial units', () => { + it("returns datasets when duration is 'week' and date format 'dd/MM/yyyy'", () => { const inputStats: TStatisticsFromApi = { '2021-10-03': { 1: { @@ -1043,6 +1110,227 @@ describe('formatStats (duration)', () => { } const expected: IStatisticsChartData = { labels: ['03/10/2021', '10/10/2021', '17/10/2021'], + datasets: { + average_speed: [ + { + label: 'Cycling (Sport)', + backgroundColor: ['#4c9792'], + borderColor: ['#4c9792'], + data: [12, 18, null], + type: 'line', + spanGaps: true, + }, + ], + nb_workouts: [ + { + label: 'Cycling (Sport)', + backgroundColor: ['#4c9792'], + data: [1, 1, 0], + }, + ], + total_distance: [ + { + label: 'Cycling (Sport)', + backgroundColor: ['#4c9792'], + data: [10, 15, 0], + }, + ], + total_duration: [ + { + label: 'Cycling (Sport)', + backgroundColor: ['#4c9792'], + data: [3000, 3500, 0], + }, + ], + total_ascent: [ + { + label: 'Cycling (Sport)', + backgroundColor: ['#4c9792'], + data: [150, 250, 0], + }, + ], + total_descent: [ + { + label: 'Cycling (Sport)', + backgroundColor: ['#4c9792'], + data: [100, 150, 0], + }, + ], + }, + } + assert.deepEqual( + formatStats( + inputParams, + false, + sports, + [1], + inputStats, + false, + 'dd/MM/yyyy' + ), + expected + ) + }) + + it("returns datasets when duration is 'week' and date format is 'date_string'", () => { + locale.value = 'fr' + const inputStats: TStatisticsFromApi = { + '2021-10-03': { + 1: { + average_speed: 12, + nb_workouts: 1, + total_distance: 10, + total_duration: 3000, + total_ascent: 150, + total_descent: 100, + }, + }, + '2021-10-10': { + 1: { + average_speed: 18, + nb_workouts: 1, + total_distance: 15, + total_duration: 3500, + total_ascent: 250, + total_descent: 150, + }, + 2: { + average_speed: 24, + nb_workouts: 2, + total_distance: 20, + total_duration: 3000, + total_ascent: 150, + total_descent: 200, + }, + }, + '2021-10-17': { + 3: { + average_speed: 8.64, + nb_workouts: 2, + total_distance: 20, + total_duration: 3000, + total_ascent: 100, + total_descent: 100, + }, + }, + } + const inputParams = { + duration: 'week', + start: new Date('October 03, 2021 00:00:00'), + end: new Date('October 23, 2021 23:59:59.999'), + } + const expected: IStatisticsChartData = { + labels: ['3 oct. 2021', '10 oct. 2021', '17 oct. 2021'], + datasets: { + average_speed: [ + { + label: 'Cycling (Sport)', + backgroundColor: ['#4c9792'], + borderColor: ['#4c9792'], + data: [12, 18, null], + type: 'line', + spanGaps: true, + }, + ], + nb_workouts: [ + { + label: 'Cycling (Sport)', + backgroundColor: ['#4c9792'], + data: [1, 1, 0], + }, + ], + total_distance: [ + { + label: 'Cycling (Sport)', + backgroundColor: ['#4c9792'], + data: [10, 15, 0], + }, + ], + total_duration: [ + { + label: 'Cycling (Sport)', + backgroundColor: ['#4c9792'], + data: [3000, 3500, 0], + }, + ], + total_ascent: [ + { + label: 'Cycling (Sport)', + backgroundColor: ['#4c9792'], + data: [150, 250, 0], + }, + ], + total_descent: [ + { + label: 'Cycling (Sport)', + backgroundColor: ['#4c9792'], + data: [100, 150, 0], + }, + ], + }, + } + assert.deepEqual( + formatStats( + inputParams, + false, + sports, + [1], + inputStats, + false, + 'date_string' + ), + expected + ) + }) + + it('returns datasets after conversion to imperial units', () => { + const inputStats: TStatisticsFromApi = { + '2021-10-03': { + 1: { + average_speed: 12, + nb_workouts: 1, + total_distance: 10, + total_duration: 3000, + total_ascent: 150, + total_descent: 100, + }, + }, + '2021-10-10': { + 1: { + average_speed: 18, + nb_workouts: 1, + total_distance: 15, + total_duration: 3500, + total_ascent: 250, + total_descent: 150, + }, + 2: { + average_speed: 24, + nb_workouts: 2, + total_distance: 20, + total_duration: 3000, + total_ascent: 150, + total_descent: 200, + }, + }, + '2021-10-17': { + 3: { + average_speed: 8.64, + nb_workouts: 2, + total_distance: 20, + total_duration: 3000, + total_ascent: 100, + total_descent: 100, + }, + }, + } + const inputParams = { + duration: 'week', + start: new Date('October 03, 2021 00:00:00'), + end: new Date('October 23, 2021 23:59:59.999'), + } + const expected: IStatisticsChartData = { + labels: ['10/03/2021', '10/10/2021', '10/17/2021'], datasets: { average_speed: [ { @@ -1092,7 +1380,15 @@ describe('formatStats (duration)', () => { }, } assert.deepEqual( - formatStats(inputParams, false, sports, [1], inputStats, true), + formatStats( + inputParams, + false, + sports, + [1], + inputStats, + true, + 'MM/dd/yyyy' + ), expected ) })