Skip to content
This repository was archived by the owner on Dec 26, 2022. It is now read-only.

Commit 34f4a9c

Browse files
committed
Path to task
1 parent c550b02 commit 34f4a9c

File tree

9 files changed

+65
-35
lines changed

9 files changed

+65
-35
lines changed

src/helpers/DateTime.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ export function calcDurationGaps(taskTime: ITimeRangeModel[]): number {
9595
const TIME_FORMAT = 'HH:mm';
9696
const NO_TIME = '--:--';
9797

98-
export function getTime(date: Date | undefined) {
98+
export function toTimeFormat(date: Date | undefined) {
9999
if (!date) {
100100
return NO_TIME;
101101
}

src/helpers/TaskHelper.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { isSameDay, compareAsc } from 'date-fns';
33
import TaskModel from '../modules/tasks/models/TaskModel';
44
import TaskTimeItemModel from '../modules/tasks/models/TaskTimeItemModel';
55
import TaskWithDurationModel from '../modules/tasks/models/TaskWithDurationModel';
6+
import TreeModelHelper from './TreeModelHelper';
67

78
/**
89
* Returns TaskTimeItemModel contains time range
@@ -18,7 +19,7 @@ import TaskWithDurationModel from '../modules/tasks/models/TaskWithDurationModel
1819
*/
1920
export function getTimeItems(
2021
tasks: TaskModel[],
21-
date: Date,
22+
date: Date
2223
): TaskTimeItemModel[] {
2324
let taskTime: TaskTimeItemModel[] = [];
2425
tasks.forEach((task) => {
@@ -45,9 +46,28 @@ export function getTimeItems(
4546
*/
4647
export function getTasksWithTotalTimeForDay(
4748
tasks: TaskModel[],
48-
date: Date,
49+
date: Date
4950
): TaskWithDurationModel[] {
5051
return tasks.map(
51-
(task) => new TaskWithDurationModel(task, task.getDurationByDate(date)),
52+
(task) => new TaskWithDurationModel(task, task.getDurationByDate(date))
5253
);
5354
}
55+
56+
/**
57+
* @example task1 → task2 → task
58+
* @param task
59+
*/
60+
export function getTaskTitlesPath(task: TaskModel) {
61+
const titlePath: string[] = [];
62+
63+
function processParent(nParent: TaskModel) {
64+
titlePath.push(nParent.title);
65+
}
66+
67+
TreeModelHelper.walkToParent(processParent, task);
68+
let titlePathStr = titlePath.reverse().join(' → ');
69+
if (titlePath.length > 0) {
70+
titlePathStr += ' →';
71+
}
72+
return titlePathStr;
73+
}

src/helpers/TreeModelHelper.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ const TreeModelHelper = {
145145
},
146146

147147
walkRecursive<T extends ITreeItem<any>>(
148-
fn: (t: T, p?: T) => void,
148+
fn: (item: T, parent?: T) => void,
149149
treeItems: T[],
150150
parent?: T
151151
) {
@@ -157,6 +157,16 @@ const TreeModelHelper = {
157157
});
158158
},
159159

160+
walkToParent<T extends ITreeItemWithParent<any>>(
161+
fn: (nParent: T) => void,
162+
treeItem: T
163+
) {
164+
if (treeItem.parent) {
165+
fn(treeItem.parent);
166+
TreeModelHelper.walkToParent(fn, treeItem.parent);
167+
}
168+
},
169+
160170
modifyItemsWithIdsRecursive<T extends ITreeItem<any>>(
161171
treeItems: T[],
162172
ids: string[],

src/main.dev.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ const createWindow = async () => {
8989
process.env.NODE_ENV === 'development' ||
9090
process.env.DEBUG_PROD === 'true'
9191
) {
92-
// Doesnt work
9392
await installExtensions();
9493
}
9594

src/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "time-tracker",
33
"productName": "TimeTracker",
4-
"version": "1.0.6",
4+
"version": "1.0.7",
55
"description": "Start and stop time, jump between tasks, and add details on how time was spent.",
66
"main": "./main.prod.js",
77
"author": {

src/screens/hours/components/HoursCard/HoursCard.tsx

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,16 @@
11
import React, { useMemo } from 'react';
22
import { Card } from 'antd';
3-
import format from 'date-fns/format';
43
import { observer } from 'mobx-react';
54
import { createUseStyles } from 'react-jss';
65

76
import TaskTimeItemModel from '../../../../modules/tasks/models/TaskTimeItemModel';
87
import PlayStopButton from '../../../../components/PlayStopButton/PlayStopButton';
98
import rootStore from '../../../../modules/RootStore';
10-
import { msToTime } from '../../../../helpers/DateTime';
9+
import { msToTime, toTimeFormat } from '../../../../helpers/DateTime';
10+
import { getTaskTitlesPath } from '../../../../helpers/TaskHelper';
1111

1212
const { projectStore } = rootStore;
1313

14-
const formatStr = 'HH:mm';
15-
function timeFormat(date: Date | undefined) {
16-
if (date) {
17-
return format(date, formatStr);
18-
}
19-
return '';
20-
}
21-
2214
interface HoursCardProps {
2315
taskTime: TaskTimeItemModel;
2416
onClick: (taskTime: TaskTimeItemModel) => void;
@@ -31,9 +23,11 @@ export default observer(function HoursCard({
3123
const { task, time } = taskTime;
3224
const classes = useStyle();
3325
const project = useMemo(() => projectStore.get(task.projectId), [task]);
34-
const duration = time.end
35-
? msToTime(time.end.getTime() - time.start.getTime())
36-
: '';
26+
const duration = useMemo(
27+
() => (time.end ? msToTime(time.end.getTime() - time.start.getTime()) : ''),
28+
[time.end, time.start]
29+
);
30+
const titlePath = useMemo(() => getTaskTitlesPath(task), [task]);
3731

3832
return (
3933
<Card
@@ -45,12 +39,13 @@ export default observer(function HoursCard({
4539
>
4640
<div className={classes.hoursCard}>
4741
<div className={classes.projectTitle}>{project?.title}</div>
42+
<div className={classes.taskTitlePath}>{titlePath}</div>
4843
<div className={classes.taskTitle}>{task.title}</div>
4944
<div className={classes.description}>{time.description}</div>
5045
<div className={classes.timeContainer}>
51-
<div className={classes.time}>{`${timeFormat(
52-
time.start
53-
)} - ${timeFormat(time.end)}`}</div>
46+
<div className={classes.time}>
47+
{`${toTimeFormat(time.start)} - ${toTimeFormat(time.end)}`}
48+
</div>
5449
<div className={classes.time}>{duration}</div>
5550
</div>
5651
</div>
@@ -80,6 +75,9 @@ const useStyle = createUseStyles({
8075
projectTitle: {
8176
fontSize: 12,
8277
},
78+
taskTitlePath: {
79+
fontSize: 12,
80+
},
8381
taskTitle: {
8482
fontWeight: 'bold',
8583
fontSize: 12,

src/screens/hours/components/TotalHours/TotalHours.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as TaskHooks from '../../../../hooks/TaskHooks';
66
import TaskTimeItemModel from '../../../../modules/tasks/models/TaskTimeItemModel';
77
import {
88
estimateWorkingTimeEnd,
9-
getTime,
9+
toTimeFormat,
1010
msToTime,
1111
} from '../../../../helpers/DateTime';
1212
import LabelWithTooltip, { ILabelWithTooltipProps } from './LabelWithTooltip';
@@ -38,7 +38,7 @@ const TotalHours = observer((props: TotalHoursProps) => {
3838

3939
const items: ILabelWithTooltipProps[] = [
4040
{
41-
label: getTime(startWorkingTime),
41+
label: toTimeFormat(startWorkingTime),
4242
tooltip: 'Start time',
4343
},
4444
{
@@ -53,7 +53,7 @@ const TotalHours = observer((props: TotalHoursProps) => {
5353
},
5454
{
5555
icon: 'mi-notifications',
56-
label: getTime(estimatedWorkingTimeEnd),
56+
label: toTimeFormat(estimatedWorkingTimeEnd),
5757
tooltip: 'Estimated end time',
5858
},
5959
{

src/screens/projects/components/TreeList.tsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import React from 'react';
22
import { Empty, Tree } from 'antd';
3+
import { TreeProps } from 'antd/lib/tree/Tree';
34
import { observer } from 'mobx-react';
45
import { Key } from 'rc-tree/lib/interface';
56

67
import { IDragInfo } from '../../../types/IDragInfo';
7-
import { ITreeItem } from '../../../types/ITreeItem';
8-
import { TreeProps } from 'antd/lib/tree/Tree';
8+
import { ITreeItemWithParent } from '../../../types/ITreeItem';
99

1010
interface TreeListProps {
1111
onSelect?: (selectedKeys: Key[]) => void;
@@ -19,7 +19,7 @@ interface TreePropsExtended<T>
1919
isDraggable?: () => boolean;
2020
}
2121

22-
export default function TreeList<T extends ITreeItem<any>>(
22+
export default function TreeList<T extends ITreeItemWithParent<any>>(
2323
getData: () => T[],
2424
updateData: (items: T[]) => void,
2525
options: TreePropsExtended<T>
@@ -37,24 +37,24 @@ export default function TreeList<T extends ITreeItem<any>>(
3737
info.dropPosition - Number(dropPos[dropPos.length - 1]);
3838

3939
const loop = (
40-
items: ITreeItem[],
40+
items: T[],
4141
key: string | number,
42-
callback: (item: ITreeItem, key: number, items: ITreeItem[]) => void
42+
callback: (item: T, key: number, items: T[]) => void
4343
) => {
4444
for (let i = 0; i < items.length; i++) {
4545
if (items[i].key === key) {
4646
return callback(items[i], i, items);
4747
}
4848
if (items[i].children) {
49-
loop(items[i].children as ITreeItem[], key, callback);
49+
loop(items[i].children || [], key, callback);
5050
}
5151
}
5252
return undefined;
5353
};
5454
const dataCopy = [...data];
5555

5656
// Find dragObject
57-
let dragObj: ITreeItem;
57+
let dragObj: T;
5858
loop(dataCopy, dragKey, (item, index, arr) => {
5959
arr.splice(index, 1);
6060
dragObj = item;
@@ -64,6 +64,7 @@ export default function TreeList<T extends ITreeItem<any>>(
6464
// Drop on the content
6565
loop(dataCopy, dropKey, (item) => {
6666
item.children = item.children || [];
67+
dragObj.parent = item;
6768
// where to insert
6869
item.children.unshift(dragObj);
6970
});
@@ -74,17 +75,19 @@ export default function TreeList<T extends ITreeItem<any>>(
7475
) {
7576
loop(dataCopy, dropKey, (item) => {
7677
item.children = item.children || [];
78+
dragObj.parent = item;
7779
// where to insert
7880
item.children.unshift(dragObj);
7981
// in previous version, we use item.children.push(dragObj) to insert the
8082
// item to the tail of the children
8183
});
8284
} else {
83-
let ar: ITreeItem[];
85+
let ar: T[];
8486
let i: number;
8587
loop(dataCopy, dropKey, (_item, index, arr) => {
8688
ar = arr;
8789
i = index;
90+
dragObj.parent = undefined;
8891
});
8992
if (dropPosition === -1) {
9093
// @ts-ignore

src/types/ITreeItem.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ export interface ITreeItem<T extends ITreeItem<any> = ITreeItem<any>> {
77
export interface ITreeItemWithParent<
88
T extends ITreeItemWithParent<any> = ITreeItemWithParent<any>
99
> extends ITreeItem<T> {
10-
parent: T | null;
10+
parent: T | undefined;
1111
}

0 commit comments

Comments
 (0)