Skip to content

Commit bc76274

Browse files
author
Dmitry Yadrikhinsky
committed
Start/end date
1 parent 2c5d4e0 commit bc76274

File tree

6 files changed

+59
-34
lines changed

6 files changed

+59
-34
lines changed

src/models/TaskModel.ts

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,23 @@ import isSameDay from 'date-fns/isSameDay';
44
import AbstractModel from '../base/AbstractModel';
55
import { ITreeItem } from '../types/ITreeItem';
66

7+
export interface IJsonTimeRangeModel {
8+
start: string;
9+
end?: string;
10+
description?: string;
11+
}
12+
13+
export interface ITimeRangeModel {
14+
start: Date;
15+
end?: Date;
16+
description?: string;
17+
}
18+
719
interface IJsonTaskModel extends ITreeItem<IJsonTaskModel> {
820
projectId: string;
921
checked: boolean;
1022
active: boolean;
11-
time: string[][];
23+
time: string[][] | IJsonTimeRangeModel[];
1224
datesInProgress: string[];
1325
children: IJsonTaskModel[];
1426
details: string[];
@@ -21,7 +33,7 @@ export default class TaskModel extends AbstractModel {
2133
projectId: string = '';
2234
checked: boolean = false;
2335
active: boolean = false;
24-
time: Date[][] = [];
36+
time: ITimeRangeModel[] = [];
2537
datesInProgress: Date[] = [];
2638
details: string = '';
2739
deleted: boolean = false;
@@ -30,7 +42,24 @@ export default class TaskModel extends AbstractModel {
3042
super();
3143
this.load(props);
3244
this.children = props.children?.map((json) => new TaskModel(json)) || [];
33-
this.time = props.time?.map((range) => range.map((t) => new Date(t))) || [];
45+
this.time =
46+
props.time?.map<ITimeRangeModel>(
47+
(range: string[] | IJsonTimeRangeModel) => {
48+
if (Array.isArray(range)) {
49+
return {
50+
start: new Date(range[0]),
51+
end: range[1] ? new Date(range[1]) : undefined,
52+
description: undefined,
53+
};
54+
} else {
55+
return {
56+
start: new Date(range.start),
57+
end: range.end ? new Date(range.end) : undefined,
58+
description: undefined,
59+
};
60+
}
61+
}
62+
) || [];
3463
this.datesInProgress =
3564
props.datesInProgress?.map((date) => new Date(date)) || [];
3665

@@ -53,14 +82,10 @@ export default class TaskModel extends AbstractModel {
5382
}
5483

5584
get duration() {
56-
return this.time.reduce((prev: number, range: Date[]) => {
57-
if (range.length > 0) {
58-
const duration =
59-
(range.length === 2 ? range[1].getTime() : Date.now()) -
60-
range[0].getTime();
61-
return prev + duration;
62-
}
63-
return prev;
85+
return this.time.reduce((prev: number, range: ITimeRangeModel) => {
86+
const { start, end } = range;
87+
const duration = (end ? end.getTime() : Date.now()) - start.getTime();
88+
return prev + duration;
6489
}, 0);
6590
}
6691

@@ -83,19 +108,18 @@ export default class TaskModel extends AbstractModel {
83108
start() {
84109
this.active = true;
85110
this.addDateWhenWasInProgress(new Date());
86-
this.time.forEach((range) => {
87-
if (range.length === 1) {
88-
range.push(new Date());
89-
}
111+
this.time.push({
112+
start: new Date(),
113+
end: undefined,
114+
description: undefined,
90115
});
91-
this.time.push([new Date()]);
92116
}
93117

94118
end() {
95119
if (this.active) {
96120
this.active = false;
97121
const range = this.time[this.time.length - 1];
98-
range.push(new Date());
122+
range.end = new Date();
99123
}
100124
}
101125

src/models/TaskTimeModel.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import TaskModel from './TaskModel';
1+
import TaskModel, { ITimeRangeModel } from './TaskModel';
22

33
export default class TaskTimeModel {
44
task: TaskModel;
5-
time: Date[];
5+
time: ITimeRangeModel;
66

7-
constructor(task: TaskModel, time: Date[]) {
7+
constructor(task: TaskModel, time: ITimeRangeModel) {
88
this.task = task;
99
this.time = time;
1010
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export default observer(function HoursCard({ taskTime }: HoursCardProps) {
2727
<Card className="hours-card">
2828
<div className="hours-card__info">
2929
<div>{task.title}</div>
30-
<div>{`${timeFormat(time[0])} - ${timeFormat(time[1])}`}</div>
30+
<div>{`${timeFormat(time.start)} - ${timeFormat(time.end)}`}</div>
3131
</div>
3232
<PlayStopButton task={task} />
3333
</Card>

src/screens/projects/components/HoursByTask/HoursByTask.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ export default function HoursByTask({ task }: HoursByTaskProps) {
2828
</IconTile>
2929
{task?.time.length === 0 && <div>No billed hours</div>}
3030
{mapLastCurrent(task?.time || [], (last, range, index) => {
31-
if (!last || !isSameDay(last[0], range[0])) {
31+
if (!last || !isSameDay(last.start, range.start)) {
3232
return (
3333
<div key={index}>
34-
<div className="date">{dateFormat(range[0])}</div>
34+
<div className="date">{dateFormat(range.start)}</div>
3535
<HoursItem range={range} />
3636
</div>
3737
);

src/screens/projects/components/HoursByTask/HoursItem.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,28 @@ import React from 'react';
22
import { Card } from 'antd';
33
import format from 'date-fns/format';
44
import { msToTime } from '../../../../helpers/DateTime';
5+
import { ITimeRangeModel } from '../../../../models/TaskModel';
56

67
function hoursFormat(date: Date) {
78
return format(date, 'HH:mm');
89
}
910

10-
function hoursRangeFormat(date: Date[]) {
11-
if (date.length === 2) {
12-
return `${hoursFormat(date[0])} - ${hoursFormat(date[1])}`;
11+
function hoursRangeFormat(range: ITimeRangeModel) {
12+
if (range.end) {
13+
return `${hoursFormat(range.start)} - ${hoursFormat(range.end)}`;
1314
}
14-
return `${hoursFormat(date[0])} -`;
15+
return `${hoursFormat(range.start)} -`;
1516
}
1617

17-
function getDuration(date: Date[]): string {
18-
if (date.length === 2) {
19-
return msToTime(date[1].getTime() - date[0].getTime(), false);
18+
function getDuration(range: ITimeRangeModel): string {
19+
if (range.end) {
20+
return msToTime(range.end.getTime() - range.start.getTime(), false);
2021
}
2122
return '';
2223
}
2324

2425
interface HoursItemProps {
25-
range: Date[];
26+
range: ITimeRangeModel;
2627
}
2728

2829
export default function HoursItem({ range }: HoursItemProps) {

src/services/TaskTimeItem.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ export default function getTimeItems(
1212
tasks.forEach((task) => {
1313
const timeItems = task.time.filter(
1414
(range) =>
15-
isSameDay(range[0], date) ||
16-
(range.length >= 1 && isSameDay(range[1], date))
15+
isSameDay(range.start, date) ||
16+
(range.end && isSameDay(range.end, date))
1717
);
1818
taskTime = taskTime.concat(
1919
timeItems.map((time) => new TaskTimeModel(task, time))
2020
);
2121
});
22-
taskTime = taskTime.sort((a, b) => compareAsc(a.time[0], b.time[0]));
22+
taskTime = taskTime.sort((a, b) => compareAsc(a.time.start, b.time.start));
2323
return taskTime;
2424
}

0 commit comments

Comments
 (0)