Skip to content

Commit 10fec66

Browse files
committed
Prototype
1 parent f0909f1 commit 10fec66

File tree

10 files changed

+141
-43
lines changed

10 files changed

+141
-43
lines changed

src/components/Header.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ function Header() {
2828
<HeaderLink>
2929
<Link to="/dashboard">Dashboard</Link>
3030
</HeaderLink>
31-
<HeaderLink>
32-
<Link to="/timeline">TL</Link>
33-
</HeaderLink>
3431
<span className={style.flex1}>{isBigScreen && <ProgressBar />}</span>
3532
<TaskControl />
3633
<Profile />

src/menu.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,8 @@ export default class MenuBuilder {
2727
}
2828

2929
const template =
30-
process.platform === 'darwin'
31-
? this.buildDarwinTemplate()
32-
: [];
33-
// : this.buildDefaultTemplate(); // Disable menu for Win and Linux
30+
process.platform === 'darwin' ? this.buildDarwinTemplate() : [];
31+
// : this.buildDefaultTemplate(); // Disable menu for Win and Linux
3432

3533
const menu = Menu.buildFromTemplate(template);
3634
Menu.setApplicationMenu(menu);
@@ -54,6 +52,7 @@ export default class MenuBuilder {
5452
}
5553

5654
buildDarwinTemplate(): MenuItemConstructorOptions[] {
55+
// TODO
5756
const subMenuAbout: DarwinMenuItemConstructorOptions = {
5857
label: 'Electron',
5958
submenu: [

src/screens/Main.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { Layout } from 'antd';
55
import ProjectsScreen from './projects/ProjectsScreen';
66
import HoursScreen from './hours/HoursScreen';
77
import DashboardScreen from './dashboard/Dashboard';
8-
import TimelineScreen from './timeline/TimelineScreen';
98
import GaService from '../services/gaService/GaService';
109
import Header from '../components/Header';
1110

@@ -27,7 +26,6 @@ const Main = () => {
2726
<Route path="/hours" component={HoursScreen} />
2827
<Route path="/projects" component={ProjectsScreen} />
2928
<Route path="/dashboard" component={DashboardScreen} />
30-
<Route path="/timeline" component={TimelineScreen} />
3129
<Redirect from="*" to="/projects" />
3230
</Switch>
3331
</Layout>

src/screens/hours/HoursScreen.tsx

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@ import rootStore from '../../modules/RootStore';
77
import { getTimeItems } from '../../helpers/TaskHelper';
88
import TotalHours from './components/TotalHours/TotalHours';
99
import Header from './components/Header';
10-
import EditableTimeItemsView from './components/EditableTimeItemsView';
10+
import GridWithTimeItemsView from './components/GridWithTimeItemsView';
11+
import { HoursTabView } from './types';
12+
import TimelineScreen from './components/TimelineScreen';
1113

1214
const { tasksStore } = rootStore;
1315

1416
export default observer(function HoursScreen() {
1517
const classes = useStyles();
1618
const [date, setDate] = useState<Date>(new Date());
19+
const [tab, setTab] = useState<HoursTabView>(HoursTabView.Edit);
1720

1821
const tasks = useMemo(() => tasksStore.getTasksByDate(date), [
1922
tasksStore.tasks,
@@ -22,28 +25,35 @@ export default observer(function HoursScreen() {
2225
const timeItems = getTimeItems(tasks, date);
2326

2427
return (
25-
<Layout className={classes.hours}>
26-
<Space direction="vertical">
27-
<Header date={date} setDate={setDate} />
28+
<Layout className={classes.hoursView}>
29+
<Space direction="vertical" className={classes.space}>
30+
<Header date={date} setDate={setDate} tab={tab} setTab={setTab} />
2831
<TotalHours timeItems={timeItems} />
29-
<EditableTimeItemsView date={date} />
32+
{tab === HoursTabView.Edit ? (
33+
<GridWithTimeItemsView date={date} />
34+
) : (
35+
<TimelineScreen date={date} />
36+
)}
3037
</Space>
3138
</Layout>
3239
);
3340
});
3441

3542
const useStyles = createUseStyles({
36-
hours: {
43+
hoursView: {
3744
overflowY: 'auto',
3845
padding: 12,
46+
},
47+
space: {
48+
flex: 1,
3949

4050
'& .ant-space-item': {
4151
display: 'flex',
4252
justifyContent: 'center',
4353
},
4454

45-
'& .ant-card-body': {
46-
padding: 8,
55+
'& .ant-space-item:last-child': {
56+
flex: 1,
4757
},
4858
},
4959
});

src/screens/hours/components/EditableTimeItemsView.tsx renamed to src/screens/hours/components/GridWithTimeItemsView.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,15 @@ type Props = {
2929
date: Date;
3030
};
3131

32-
const EditableTimeItemsView: FC<Props> = ({ date }: Props) => {
32+
const GridWithTimeItemsView: FC<Props> = ({ date }: Props) => {
3333
const classes = useStyles();
3434

3535
const [currentTaskTime, setCurrentTaskTime] = useState<
3636
Undefined<TaskTimeItemModel>
3737
>();
3838

3939
const timeItems = useMemo(() => {
40+
// TODO Doesn't update
4041
const tasks = tasksStore.getTasksByDate(date);
4142
return getTimeItems(tasks, date);
4243
}, [tasksStore.tasks, date]);
@@ -65,12 +66,16 @@ const EditableTimeItemsView: FC<Props> = ({ date }: Props) => {
6566
);
6667
};
6768

68-
export default observer(EditableTimeItemsView);
69+
export default observer(GridWithTimeItemsView);
6970

7071
const useStyles = createUseStyles({
7172
cards: {
7273
display: 'flex',
7374
flexWrap: 'wrap',
75+
76+
'& .ant-card-body': {
77+
padding: 8,
78+
},
7479
},
7580
breakTime: {
7681
display: 'flex',

src/screens/hours/components/Header.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ import { createUseStyles } from 'react-jss';
55

66
import SelectDate from '../../../components/SelectDate';
77
import RadioGroupChangeHoursView from './RadioGroupChangeHoursView';
8+
import { HoursTabView } from '../types';
89

910
type Props = {
1011
date: Date;
1112
setDate(date: Date): void;
13+
tab: HoursTabView;
14+
setTab(tab: HoursTabView): void;
1215
};
1316

14-
const Header: FC<Props> = ({ date, setDate }: Props) => {
17+
const Header: FC<Props> = ({ date, setDate, tab, setTab }: Props) => {
1518
const classes = useStyles();
1619

1720
return (
@@ -20,7 +23,7 @@ const Header: FC<Props> = ({ date, setDate }: Props) => {
2023
<SelectDate date={date} onChange={setDate} />
2124
</Col>
2225
<Col span={8} className={classes.alignRight}>
23-
<RadioGroupChangeHoursView onChange={(_option) => {}} />
26+
<RadioGroupChangeHoursView tab={tab} onChange={setTab} />
2427
</Col>
2528
</Row>
2629
);

src/screens/hours/components/RadioGroupChangeHoursView.tsx

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,43 @@
1-
import React, { FC } from 'react';
1+
import React, { FC, useCallback } from 'react';
22
import { CheckboxOptionType } from 'antd/lib/checkbox/Group';
33
import { AppstoreOutlined, BuildOutlined } from '@ant-design/icons';
4-
import { Radio } from 'antd';
4+
import { Radio, RadioChangeEvent } from 'antd';
55
import { observer } from 'mobx-react';
66

7-
enum Options {
8-
Edit,
9-
Timeline,
10-
}
7+
import { HoursTabView } from '../types';
118

129
const ICON_STYLE = { fontSize: '20px' };
10+
const ICON_MIRRORED_STYLE = { ...ICON_STYLE, transform: 'scale(-1, 1)' };
1311

1412
const options: CheckboxOptionType[] = [
15-
{ label: <AppstoreOutlined style={ICON_STYLE} />, value: Options.Edit },
16-
{ label: <BuildOutlined style={ICON_STYLE} />, value: Options.Timeline },
13+
{ label: <AppstoreOutlined style={ICON_STYLE} />, value: HoursTabView.Edit },
14+
{
15+
label: <BuildOutlined style={ICON_MIRRORED_STYLE} />,
16+
value: HoursTabView.Timeline,
17+
},
1718
];
1819

1920
type Props = {
20-
onChange(val: Options): void;
21+
tab: HoursTabView;
22+
onChange(val: HoursTabView): void;
2123
};
2224

23-
const RadioGroupChangeHoursView: FC<Props> = () => {
25+
const RadioGroupChangeHoursView: FC<Props> = ({ tab, onChange }: Props) => {
26+
const handleOnChange = useCallback(
27+
(e: RadioChangeEvent) => {
28+
onChange(e.target.value);
29+
},
30+
[onChange]
31+
);
32+
2433
return (
25-
<Radio.Group options={options} optionType="button" buttonStyle="solid" />
34+
<Radio.Group
35+
options={options}
36+
optionType="button"
37+
buttonStyle="solid"
38+
value={tab}
39+
onChange={handleOnChange}
40+
/>
2641
);
2742
};
2843

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import React, { FC, memo, useMemo } from 'react';
2+
import { Chart } from 'react-google-charts';
3+
import { createUseStyles } from 'react-jss';
4+
5+
import rootStore from '../../../modules/RootStore';
6+
import { getTimeItems } from '../../../helpers/TaskHelper';
7+
import TaskTimeItemModel from '../../../modules/tasks/models/TaskTimeItemModel';
8+
9+
const { tasksStore } = rootStore;
10+
11+
const columns = [
12+
{ type: 'string', id: 'Task' },
13+
{ type: 'date', id: 'Start' },
14+
{ type: 'date', id: 'End' },
15+
];
16+
17+
function mapTimeItemToChartItem({ task, time }: TaskTimeItemModel): any[] {
18+
return [task.title || '-', time.start || new Date(), time.end || new Date()];
19+
}
20+
21+
type Props = {
22+
date: Date;
23+
};
24+
25+
const Timeline: FC<Props> = ({ date }: Props) => {
26+
const classes = useStyles();
27+
28+
const data = useMemo(() => {
29+
const tasks = tasksStore.getTasksByDate(date);
30+
const filteredTimeItems = getTimeItems(tasks, date);
31+
const items = filteredTimeItems.map(mapTimeItemToChartItem);
32+
if (items.length === 0) {
33+
return undefined;
34+
}
35+
return [columns, ...items];
36+
}, [date]);
37+
38+
if (!data) {
39+
return null;
40+
}
41+
42+
return (
43+
<div className={classes.main}>
44+
<Chart
45+
style={{ flex: 1 }}
46+
chartType="Timeline"
47+
data={data}
48+
height="100%"
49+
/>
50+
</div>
51+
);
52+
};
53+
54+
export default memo(Timeline);
55+
56+
const useStyles = createUseStyles({
57+
main: {
58+
display: 'flex',
59+
flex: 1,
60+
height: '100%',
61+
},
62+
});

src/screens/hours/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export enum HoursTabView {
2+
Edit,
3+
Timeline,
4+
}

src/screens/timeline/TimelineScreen.tsx

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
1-
import React, {FC, memo, useMemo} from 'react';
2-
import {Chart} from 'react-google-charts';
3-
import {createUseStyles} from 'react-jss';
1+
import React, { FC, memo, useMemo } from 'react';
2+
import { Chart } from 'react-google-charts';
3+
import { createUseStyles } from 'react-jss';
44

55
import rootStore from '../../modules/RootStore';
6-
import {getTimeItems} from '../../helpers/TaskHelper';
6+
import { getTimeItems } from '../../helpers/TaskHelper';
77

8-
const {tasksStore} = rootStore;
8+
const { tasksStore } = rootStore;
99

1010
const columns = [
11-
{type: 'string', id: 'Task'},
12-
{type: 'date', id: 'Start'},
13-
{type: 'date', id: 'End'},
11+
{ type: 'string', id: 'Task' },
12+
{ type: 'date', id: 'Start' },
13+
{ type: 'date', id: 'End' },
1414
];
1515

1616
const nowDate = new Date();
17-
17+
// TODO remove
1818
const Timeline: FC = () => {
1919
const classes = useStyles();
2020

2121
const data = useMemo(() => {
2222
const tasks = tasksStore.getTasksByDate(nowDate);
2323
const filteredTimeItems = getTimeItems(tasks, nowDate);
24-
const items = filteredTimeItems.map(({task, time}) => [
24+
const items = filteredTimeItems.map(({ task, time }) => [
2525
task.title || '-',
2626
time.start || new Date(),
2727
time.end || new Date(),
@@ -31,7 +31,12 @@ const Timeline: FC = () => {
3131

3232
return (
3333
<div className={classes.main}>
34-
<Chart style={{flex: 1}} chartType="Timeline" data={data} height='100%'/>
34+
<Chart
35+
style={{ flex: 1 }}
36+
chartType="Timeline"
37+
data={data}
38+
height="100%"
39+
/>
3540
</div>
3641
);
3742
};

0 commit comments

Comments
 (0)