Skip to content

Commit a937a4e

Browse files
committed
fix(#1240): fix overall balance to stay anchored to today across calendar navigation
1 parent 6cb9a4c commit a937a4e

7 files changed

Lines changed: 88 additions & 25 deletions

File tree

__tests__/__renderer__/calendar.mjs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,14 @@ const testPreferences = structuredClone(getDefaultPreferences());
2121
describe('Test Calendar Window', () =>
2222
{
2323
let handleToggleMainWindowWaitCallback = undefined;
24+
let waitUntilHandlersSetup = undefined;
2425
before(async() =>
2526
{
27+
waitUntilHandlersSetup = new Promise(resolve =>
28+
{
29+
window.__resolveCalendarHandlersSetup = resolve;
30+
});
31+
2632
// Mocking APIs
2733
window.rendererApi = {
2834
getLanguageDataPromise: () =>
@@ -37,7 +43,11 @@ describe('Test Calendar Window', () =>
3743
};
3844

3945
window.calendarApi = {
40-
handleToggleMainWindowWait: (callback) => { handleToggleMainWindowWaitCallback = callback; },
46+
handleToggleMainWindowWait: (callback) =>
47+
{
48+
handleToggleMainWindowWaitCallback = callback;
49+
window.__resolveCalendarHandlersSetup();
50+
},
4151
handleCalendarReload: () => {},
4252
handleRefreshOnDayChange: () => {},
4353
handlePreferencesSaved: () => {},
@@ -50,6 +60,8 @@ describe('Test Calendar Window', () =>
5060
// Using dynamic imports because when the file is imported a $() callback is triggered and
5161
// methods must be mocked before-hand
5262
await import('../../src/calendar.js');
63+
await waitUntilHandlersSetup;
64+
delete window.__resolveCalendarHandlersSetup;
5365
});
5466

5567
beforeEach(async function()

__tests__/__renderer__/classes/DayCalendar.mjs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,34 @@ describe('DayCalendar class Tests', () =>
313313
assert.strictEqual(calendar._getCalendarYear(), today.getFullYear());
314314
});
315315

316+
describe('DayCalendar overall balance target date', () =>
317+
{
318+
it('Stays anchored to today while browsing other days', () =>
319+
{
320+
const expectedTargetDate = new Date(today.getFullYear(), today.getMonth(), today.getDate());
321+
322+
calendar._prevDay();
323+
assert.strictEqual(calendar._getTargetDayForAllTimeBalance().getTime(), expectedTargetDate.getTime());
324+
325+
calendar._goToCurrentDate();
326+
calendar._nextDay();
327+
assert.strictEqual(calendar._getTargetDayForAllTimeBalance().getTime(), expectedTargetDate.getTime());
328+
});
329+
330+
it('Includes today when count-today is enabled', async() =>
331+
{
332+
const preferences = structuredClone(getDefaultPreferences());
333+
preferences['view'] = 'day';
334+
preferences['count-today'] = true;
335+
const anchoredCalendar = await CalendarFactory.getInstance(preferences, languageData);
336+
const expectedTargetDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
337+
338+
anchoredCalendar._prevDay();
339+
340+
assert.strictEqual(anchoredCalendar._getTargetDayForAllTimeBalance().getTime(), expectedTargetDate.getTime());
341+
});
342+
});
343+
316344
describe('DayCalendar RefreshOnDayChange', () =>
317345
{
318346
it('DayCalendar refresh set correctly', () =>

__tests__/__renderer__/classes/MonthCalendar.mjs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,33 @@ describe('MonthCalendar class Tests', () =>
206206
assert.strictEqual(calendar._getCalendarYear(), today.getFullYear());
207207
});
208208

209+
describe('MonthCalendar overall balance target date', () =>
210+
{
211+
it('Stays anchored to today while browsing other months', () =>
212+
{
213+
const expectedTargetDate = new Date(today.getFullYear(), today.getMonth(), today.getDate());
214+
215+
calendar._prevMonth();
216+
assert.strictEqual(calendar._getTargetDayForAllTimeBalance().getTime(), expectedTargetDate.getTime());
217+
218+
calendar._goToCurrentDate();
219+
calendar._nextMonth();
220+
assert.strictEqual(calendar._getTargetDayForAllTimeBalance().getTime(), expectedTargetDate.getTime());
221+
});
222+
223+
it('Includes today when count-today is enabled', async() =>
224+
{
225+
const preferences = structuredClone(getDefaultPreferences());
226+
preferences['count-today'] = true;
227+
const anchoredCalendar = await CalendarFactory.getInstance(preferences, languageData);
228+
const expectedTargetDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
229+
230+
anchoredCalendar._prevMonth();
231+
232+
assert.strictEqual(anchoredCalendar._getTargetDayForAllTimeBalance().getTime(), expectedTargetDate.getTime());
233+
});
234+
});
235+
209236
describe('MonthCalendar RefreshOnDayChange', () =>
210237
{
211238
it('MonthCalendar refresh set correctly', () =>

locales/en/translation.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"month-balance": "Month Balance",
55
"month-balance-title": "Balance up until today for this month. A positive balance means extra hours you don't need to work today (or the rest of the month).",
66
"overall-balance": "Overall Balance",
7-
"overall-balance-title": "Overall balance until end of the month or current day",
7+
"overall-balance-title": "Overall balance up to the current day",
88
"switch-view": "Switch View"
99
},
1010
"$DateUtil": {

renderer/classes/BaseCalendar.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,28 @@ class BaseCalendar
3838

3939
/**
4040
* Returns a date object for which the all time balance will be calculated.
41-
* If current month, returns the actual day. If not, first day of following month.
4241
* @return {Date}
4342
*/
4443
_getTargetDayForAllTimeBalance()
4544
{
4645
throw Error('Please implement this.');
4746
}
4847

48+
/**
49+
* Returns the current-day target date for overall balance calculations.
50+
* If "count today" is active, returns the following day so today is included.
51+
* @return {Date}
52+
*/
53+
_getCurrentDayTargetForAllTimeBalance()
54+
{
55+
const targetDate = new Date(this._getTodayYear(), this._getTodayMonth(), this._getTodayDate());
56+
if (this._getCountToday())
57+
{
58+
targetDate.setDate(targetDate.getDate() + 1);
59+
}
60+
return targetDate;
61+
}
62+
4963
/**
5064
* Searches for an i18n code inside the last loaded language data
5165
* @return {String}

renderer/classes/DayCalendar.js

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -710,18 +710,12 @@ class DayCalendar extends BaseCalendar
710710

711711
/**
712712
* Returns a date object for which the all time balance will be calculated.
713-
* For DayCalendar, it's the day of CalendarDate => the day being displayed.
714-
* If "count_today" is active, the following day.
713+
* Overall balance is anchored to the current day even while browsing other days.
715714
* @return {Date}
716715
*/
717716
_getTargetDayForAllTimeBalance()
718717
{
719-
const targetDate = new Date(this._getCalendarYear(), this._getCalendarMonth(), this._getCalendarDate());
720-
if (this._getCountToday())
721-
{
722-
targetDate.setDate(targetDate.getDate() + 1);
723-
}
724-
return targetDate;
718+
return this._getCurrentDayTargetForAllTimeBalance();
725719
}
726720
}
727721

renderer/classes/MonthCalendar.js

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,24 +35,12 @@ class MonthCalendar extends BaseCalendar
3535

3636
/**
3737
* Returns a date object for which the all time balance will be calculated.
38-
* If current month, returns the actual day. If not, first day of following month.
38+
* Overall balance is anchored to the current day even while browsing other months.
3939
* @return {Date}
4040
*/
4141
_getTargetDayForAllTimeBalance()
4242
{
43-
const targetYear = this._getCalendarYear(),
44-
targetMonth = this._getCalendarMonth(),
45-
// If we are not displaying the current month we need to compute the balance including the
46-
// last day of the month. To do so we move to the first day of the following month
47-
isCurrentMonth = targetYear === this._getTodayYear() && targetMonth === this._getTodayMonth(),
48-
targetDate = isCurrentMonth ?
49-
new Date(targetYear, targetMonth, this._getTodayDate()) :
50-
new Date(targetYear, targetMonth + 1, 1);
51-
if (isCurrentMonth && this._getCountToday())
52-
{
53-
targetDate.setDate(targetDate.getDate() + 1);
54-
}
55-
return targetDate;
43+
return this._getCurrentDayTargetForAllTimeBalance();
5644
}
5745

5846
/*

0 commit comments

Comments
 (0)