mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-17 16:37:43 +00:00
fix(worklog): avoid misleading export start/end times (#8090)
* fix(worklog): avoid misleading export times #5654 * chore: rerun worklog export checks * fix(worklog): show session times once per day #5654 --------- Co-authored-by: cocojojo5213 <cocojojo5213@users.noreply.github.com>
This commit is contained in:
parent
fe65d4b9a6
commit
ba31037d0f
3 changed files with 57 additions and 4 deletions
|
|
@ -20,7 +20,7 @@ The transformation does the following:
|
|||
- **Iterates over every task** and every day in that task’s “time spent per day” map.
|
||||
- **Builds a hierarchy** — Year → month → day (or, in week view, year → week → day). Each day has a list of entries (task + time for that day) and a **total time** for the day.
|
||||
- **Places subtasks** — When a task has a parent, its entry is placed immediately after the parent (or after a sibling) so the list reflects hierarchy.
|
||||
- **Uses locale and work times** — Day labels use your locale; if you have work start/end times configured, they can be shown per day where available.
|
||||
- **Uses locale and work times** — Day labels use your locale; if you have work start/end times configured, they can be shown for day-level rows where available.
|
||||
- **Aggregates without double-counting** — Only **leaf tasks** (tasks with no subtasks) contribute their time to the day/month/year totals. Parent tasks’ own “time spent per day” is not added again on top of subtask time, so the totals are not inflated.
|
||||
|
||||
So the worklog is a **reorganized view** of the same “time spent per day” data that lives on tasks (and in the archive). When you open History (including its legacy `worklog`/`quick-history` routes) or the daily summary, the app loads the relevant tasks (active + archive for the context), runs this transformation, and shows the result.
|
||||
|
|
@ -37,7 +37,7 @@ So the worklog is a **reorganized view** of the same “time spent per day” da
|
|||
|
||||
- **Inline time correction** — Leaf-task rows can be corrected inline. The app updates the task's “time spent per day” value for that date, so the corrected time is reflected in History, reports, and metrics.
|
||||
- **Parent rows** — Parent tasks show the sum of their subtasks and are not edited directly, which avoids double-counting.
|
||||
- **Export** — You can export the worklog (e.g. to CSV or for external time sheets). Export uses the same task–date–duration data and can be **filtered by project and date range**. An option lets you **exclude time that falls outside the chosen range**, so only time within the range is included in the export. That way you get a clean slice of work for the period you care about.
|
||||
- **Export** — You can export the worklog (e.g. to CSV or for external time sheets). Export uses the same task–date–duration data and can be **filtered by project and date range**. An option lets you **exclude time that falls outside the chosen range**, so only time within the range is included in the export. When export is grouped by individual worklog rows, each row represents a task, date, and duration; start and end times are day-level values rather than per-task session times. That way you get a clean slice of work for the period you care about.
|
||||
|
||||
## Summary
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { WorkStartEnd } from 'src/app/features/work-context/work-context.model';
|
||||
import { WorklogGrouping } from '../worklog.model';
|
||||
import { createRows } from './worklog-export.util';
|
||||
import { createRows, formatRows } from './worklog-export.util';
|
||||
import { DEFAULT_TASK, WorklogTask } from '../../tasks/task.model';
|
||||
import { DEFAULT_PROJECT } from '../../project/project.const';
|
||||
import { DEFAULT_TAG } from '../../tag/tag.const';
|
||||
|
|
@ -372,6 +372,43 @@ describe('createRows', () => {
|
|||
expect(rows[2].titlesWithSub).toEqual([taskId2]);
|
||||
expect(rows[2].dates).toEqual([dateKey2]);
|
||||
});
|
||||
|
||||
it('should only show day-level start and end times on the first task row for a day', () => {
|
||||
const rows = createRows(
|
||||
createWorklogData({
|
||||
tasks: [task1, task2],
|
||||
workTimes,
|
||||
}),
|
||||
WorklogGrouping.WORKLOG,
|
||||
);
|
||||
|
||||
expect(rows.length).toBe(3);
|
||||
expect(rows.map((row) => row.workStart)).toEqual([
|
||||
workTimes.start[dateKey1],
|
||||
0,
|
||||
workTimes.start[dateKey2],
|
||||
]);
|
||||
expect(rows.map((row) => row.workEnd)).toEqual([
|
||||
workTimes.end[dateKey1],
|
||||
0,
|
||||
workTimes.end[dateKey2],
|
||||
]);
|
||||
|
||||
const formattedRows = formatRows(rows, {
|
||||
roundWorkTimeTo: null,
|
||||
roundStartTimeTo: null,
|
||||
roundEndTimeTo: null,
|
||||
separateTasksBy: ' | ',
|
||||
cols: ['DATE', 'START', 'END', 'TIME_CLOCK', 'TITLES_INCLUDING_SUB'],
|
||||
groupBy: WorklogGrouping.WORKLOG,
|
||||
});
|
||||
|
||||
expect(formattedRows.map((row) => row.slice(0, 3))).toEqual([
|
||||
[dateKey1, '10:00', '12:00'],
|
||||
[dateKey1, ' - ', ' - '],
|
||||
[dateKey2, '14:00', '16:00'],
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ export const createRows = (
|
|||
rows.push(groups[key]);
|
||||
});
|
||||
|
||||
return rows;
|
||||
return groupBy === WorklogGrouping.WORKLOG ? clearRepeatedWorklogDayTimes(rows) : rows;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -185,6 +185,22 @@ const handleWorklogGroup = (data: WorklogExportData): ItemsByKey<RowItem> => {
|
|||
return taskGroups;
|
||||
};
|
||||
|
||||
const clearRepeatedWorklogDayTimes = (rows: RowItem[]): RowItem[] => {
|
||||
const seenDays = new Set<string>();
|
||||
return rows.map((row) => {
|
||||
const day = row.dates[0];
|
||||
if (seenDays.has(day)) {
|
||||
return {
|
||||
...row,
|
||||
workStart: 0,
|
||||
workEnd: 0,
|
||||
};
|
||||
}
|
||||
seenDays.add(day);
|
||||
return row;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Unfolds task into taskFields while mapping id's to titles, and minor formatting
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue