forked from Yadro/time-tracker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHoursByTask.tsx
More file actions
101 lines (94 loc) · 2.83 KB
/
HoursByTask.tsx
File metadata and controls
101 lines (94 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import React from 'react';
import { Card, Space } from 'antd';
import { BellFilled } from '@ant-design/icons';
import isSameDay from 'date-fns/isSameDay';
import format from 'date-fns/format';
import { observer } from 'mobx-react';
import { createUseStyles } from 'react-jss';
import TaskModel, {
ITimeRangeModel,
} from '../../../../modules/tasks/models/TaskModel';
import TaskTimeItemModel from '../../../../modules/tasks/models/TaskTimeItemModel';
import { mapPrevCurrent } from '../../../../helpers/ArrayHelper';
import HoursItem from './components/HoursItem';
import IconTile from '../../../../components/IconTile/IconTile';
import { calcDuration, msToTime } from '../../../../helpers/DateTime';
function dateFormat(date: Date) {
return format(date, 'dd.MM.yyyy');
}
function getDurationPerDay(timeItems: ITimeRangeModel[], date: Date) {
const filteredTimeItems = timeItems.filter((t) => isSameDay(t.start, date));
return msToTime(calcDuration(filteredTimeItems), false);
}
interface HoursByTaskProps {
task?: TaskModel;
onClick: (task: TaskTimeItemModel) => void;
}
export default observer(function HoursByTask({
task,
onClick,
}: HoursByTaskProps) {
const classes = useStyle();
return (
<Card className={classes.root}>
<Space direction="vertical" className={classes.hoursByTask}>
<IconTile backgroundColor="#F5AB28">
<BellFilled style={{ color: 'white' }} />
</IconTile>
{task?.time.length === 0 && <div>No billed hours</div>}
{mapPrevCurrent(task?.time || [], (prev, range, index) => {
const hoursItem = (
<HoursItem
key={index}
range={range}
onClick={() => {
if (task) {
onClick(new TaskTimeItemModel(task, range, index));
}
}}
/>
);
if (!prev || !isSameDay(prev.start, range.start)) {
const duration = getDurationPerDay(task?.time || [], range.start);
return (
<div key={index}>
<div className={classes.headerDate}>
<div className={classes.date}>{dateFormat(range.start)}</div>
<div className={classes.durationDate}>{duration}</div>
</div>
{hoursItem}
</div>
);
}
return hoursItem;
})}
</Space>
</Card>
);
});
const useStyle = createUseStyles({
root: {
'& > .ant-card-body': {
borderLeft: '2px solid #F5AB28',
padding: 8,
},
},
hoursByTask: {
width: '100%',
},
headerDate: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
},
date: {
marginLeft: 8,
fontSize: 11,
fontWeight: 'bold',
},
durationDate: {
marginRight: 8,
fontSize: 11,
fontWeight: 'bold',
},
});