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

Commit d932f05

Browse files
committed
ProgressBar
1 parent 29f04e8 commit d932f05

File tree

14 files changed

+2087
-433
lines changed

14 files changed

+2087
-433
lines changed

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"start": "node -r @babel/register ./.erb/scripts/CheckPortInUse.js && cross-env yarn start:renderer",
1515
"start:main": "cross-env NODE_ENV=development electron -r ./.erb/scripts/BabelRegister ./src/main.dev.ts",
1616
"start:renderer": "cross-env NODE_ENV=development webpack serve --config ./.erb/configs/webpack.config.renderer.dev.babel.js",
17-
"test": "jest"
17+
"test": "jest",
18+
"tsc": "tsc"
1819
},
1920
"lint-staged": {
2021
"*.{js,jsx,ts,tsx}": [
@@ -166,6 +167,7 @@
166167
"@types/react": "^16.9.44",
167168
"@types/react-dom": "^16.9.9",
168169
"@types/react-router-dom": "^5.1.6",
170+
"@types/uuid": "^8.3.3",
169171
"@types/webpack-env": "^1.15.2",
170172
"@typescript-eslint/eslint-plugin": "^4.8.1",
171173
"@typescript-eslint/parser": "^4.8.1",
@@ -250,7 +252,8 @@
250252
"react-router-dom": "^5.2.0",
251253
"regenerator-runtime": "^0.13.5",
252254
"source-map-support": "^0.5.19",
253-
"universal-analytics": "^0.4.23"
255+
"universal-analytics": "^0.4.23",
256+
"uuid": "^8.3.2"
254257
},
255258
"devEngines": {
256259
"node": ">=14.x",

src/components/ProgressBar/ProgressBar.tsx

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,30 @@ function ProgressBar() {
1919
const style = useStyle();
2020

2121
const [dayUpdateEveryDay, setDayUpdateEveryDay] = useState(new Date());
22-
const [timer, setTimer] = useState(new Date());
22+
const [_tick, setTick] = useState(new Date());
2323

2424
const shouldDayUpdate = useCallback(() => {
2525
const now = new Date();
26-
setTimer(now);
26+
setTick(now);
2727
if (!isSameDay(dayUpdateEveryDay, now)) {
2828
setDayUpdateEveryDay(now);
2929
}
3030
}, [dayUpdateEveryDay]);
3131

3232
useInterval(shouldDayUpdate);
33-
1 + 1;
34-
const tasks = useMemo(() => tasksStore.getTasksByDate(dayUpdateEveryDay), [
33+
34+
const tasksByProject = useMemo(() => Object.values(tasksStore.tasks), [
3535
tasksStore.tasks,
36+
tasksStore.versionHash,
37+
]);
38+
39+
const tasks = useMemo(() => tasksStore.getTasksByDate(dayUpdateEveryDay), [
40+
tasksByProject,
3641
dayUpdateEveryDay,
3742
]);
3843

3944
const timeItems = useMemo(() => getTimeItems(tasks, dayUpdateEveryDay), [
4045
tasks,
41-
dayUpdateEveryDay,
4246
]);
4347

4448
const workingTimeStart = useMemo(() => getStartWorkingTime(timeItems), [
@@ -49,25 +53,36 @@ function ProgressBar() {
4953
timeItems,
5054
]);
5155

52-
const { estimatedWorkingTimeEnd, progress } = useMemo(
53-
() =>
54-
TaskTimeService.getDayProgress(
55-
timeRangeItems,
56-
workingTimeStart,
57-
workingHoursMs
58-
),
59-
[timer, timeRangeItems, workingTimeStart, workingHoursMs]
56+
const { estimatedWorkingTimeEnd, progress } = TaskTimeService.getDayProgress(
57+
timeRangeItems,
58+
workingTimeStart,
59+
workingHoursMs
6060
);
6161

62-
const marks = useMemo(
63-
() => ({
64-
0: toTimeFormat(workingTimeStart),
65-
100: toTimeFormat(estimatedWorkingTimeEnd),
66-
}),
67-
[timer, workingTimeStart, estimatedWorkingTimeEnd]
68-
);
62+
const progressRound = Math.round(progress);
63+
const marks: Record<number, string> = {
64+
0: toTimeFormat(workingTimeStart),
65+
100: toTimeFormat(estimatedWorkingTimeEnd),
66+
};
67+
if (progressRound > 10 && progressRound < 90) {
68+
marks[progressRound] = `${progressRound}%`;
69+
}
6970

70-
return <Slider marks={marks} value={progress} className={style.slider} />;
71+
const tipFormatter = useMemo(() => {
72+
if (progressRound <= 10 || progressRound >= 90) {
73+
return (value?: number) => `${value}%`;
74+
}
75+
return null;
76+
}, [progressRound]);
77+
78+
return (
79+
<Slider
80+
marks={marks}
81+
value={progress}
82+
className={style.slider}
83+
tipFormatter={tipFormatter}
84+
/>
85+
);
7186
}
7287

7388
const useStyle = createUseStyles({

src/helpers/ArrayHelper.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
type CallbackPrev<T, R> = (prev: T | undefined, cur: T, index: number) => R;
22

3-
export function iterPrevCurrent<T, R = any>(
3+
export function iterPrevCurrent<T>(
44
items: T[],
5-
callback: CallbackPrev<T, R>
5+
callback: CallbackPrev<T, void>
66
) {
77
for (let i = 0; i < items.length; i++) {
88
if (i === 0) {
@@ -13,11 +13,11 @@ export function iterPrevCurrent<T, R = any>(
1313
}
1414
}
1515

16-
export function mapPrevCurrent<T, R = any>(
16+
export function mapPrevCurrent<T, Result = any>(
1717
items: T[],
18-
callback: CallbackPrev<T, R>
19-
): R[] {
20-
const result: R[] = [];
18+
callback: CallbackPrev<T, Result>
19+
): Result[] {
20+
const result: Result[] = [];
2121
for (let i = 0; i < items.length; i++) {
2222
if (i === 0) {
2323
result.push(callback(undefined, items[i], i));
@@ -30,11 +30,11 @@ export function mapPrevCurrent<T, R = any>(
3030

3131
type CallbackNext<T, R> = (cur: T, next: T | undefined, index: number) => R;
3232

33-
export function mapCurrentNext<T, R = any>(
33+
export function mapCurrentNext<T, Result = any>(
3434
items: T[],
35-
callback: CallbackNext<T, R>
36-
): R[] {
37-
const result: R[] = [];
35+
callback: CallbackNext<T, Result>
36+
): Result[] {
37+
const result: Result[] = [];
3838
for (let i = 0; i < items.length; i++) {
3939
if (i === items.length - 1) {
4040
result.push(callback(items[i], undefined, i));
@@ -47,4 +47,4 @@ export function mapCurrentNext<T, R = any>(
4747

4848
export function last<T>(arr: T[]): T | undefined {
4949
return arr[arr.length - 1];
50-
}
50+
}

src/helpers/DateTime.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,6 @@ export function calcDurationGaps(taskTime: ITimeRangeModel[]): number {
8484
}
8585
});
8686

87-
const lastTask = taskTime[taskTime.length - 1];
88-
if (lastTask && lastTask.end) {
89-
result += new Date().getTime() - lastTask.end.getTime();
90-
}
91-
9287
return result;
9388
}
9489

src/helpers/TaskHelper.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,15 @@ export function getTimeItems(
2323
): TaskTimeItemModel[] {
2424
const taskTime: TaskTimeItemModel[] = [];
2525
tasks.forEach((task) => {
26-
const taskTimeItems: TaskTimeItemModel[] = [];
2726
for (let i = 0; i < task.time.length; i++) {
2827
const range = task.time[i];
2928
if (
3029
isSameDay(range.start, date) ||
3130
(range.end && isSameDay(range.end, date))
3231
) {
33-
taskTimeItems.push(new TaskTimeItemModel(task, range, i));
32+
taskTime.push(new TaskTimeItemModel(task, range, i));
3433
}
3534
}
36-
taskTime.push(...taskTimeItems);
3735
});
3836
taskTime.sort((a, b) => compareAsc(a.time.start, b.time.start));
3937

src/helpers/TreeModelHelper.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,4 @@ describe('TreeModelHelper', () => {
8383
const task22 = testTasks.proj[1].children[0];
8484
expect(TreeModelHelper.getPathToNode(task22)).toStrictEqual(['2', '21']);
8585
});
86-
87-
test('');
8886
});

src/helpers/TreeModelHelper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const TreeModelHelper = {
4242
details: [],
4343
expanded: true,
4444
inMyDay: new Date().toString(),
45-
parent: null,
45+
parent: undefined,
4646
time: [],
4747
withoutActions: true,
4848
})

src/hooks/TaskHooks.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2-
import { isBefore } from 'date-fns';
1+
import { useCallback, useEffect, useRef, useState } from 'react';
32

43
import { calcDuration, calcDurationGaps, msToTime } from '../helpers/DateTime';
54
import TaskModel, { ITimeRangeModel } from '../modules/tasks/models/TaskModel';

src/modules/tasks/TaskStore.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { autorun, makeAutoObservable } from 'mobx';
2-
1+
import { autorun, makeAutoObservable, observable } from 'mobx';
2+
import { v4 as uuid } from 'uuid';
33
import TaskService from './TaskService';
44
import TaskModel, { ITimeRangeModel } from './models/TaskModel';
55
import {
@@ -23,6 +23,7 @@ import { ITreeItemWithParent } from '../../types/ITreeItem';
2323
export default class TaskStore {
2424
tasks: TasksByProject = {};
2525
activeTask: TaskModel | undefined;
26+
versionHash = uuid();
2627
private tasksService = new TaskService();
2728
private interval: NodeJS.Timeout | undefined;
2829

@@ -37,13 +38,14 @@ export default class TaskStore {
3738
}
3839

3940
set(projectId: string, tasksInProject: TaskModel[]) {
40-
this.tasks[projectId] = tasksInProject;
41+
this.tasks[projectId] = observable.array(tasksInProject);
4142
this.tasksService.save(this.tasks);
4243
}
4344

4445
setTime(task: TaskModel, timeIndex: number, timeRange: ITimeRangeModel) {
4546
task.time[timeIndex] = timeRange;
4647
this.tasksService.save(this.tasks);
48+
this.updateVersion();
4749
GaService.event(EEventCategory.TimeRange, ETimeRangeEvents.Update);
4850
}
4951

@@ -54,6 +56,7 @@ export default class TaskStore {
5456

5557
task.time.splice(timeIndex, 1);
5658
this.tasksService.save(this.tasks);
59+
this.updateVersion();
5760
GaService.event(EEventCategory.TimeRange, ETimeRangeEvents.Delete);
5861
}
5962

@@ -92,10 +95,10 @@ export default class TaskStore {
9295
add(task: TaskModel) {
9396
const { projectId } = task;
9497
if (!Array.isArray(this.tasks[projectId])) {
95-
this.tasks[projectId] = [];
98+
this.tasks[projectId] = observable.array(); // TODO this.set()
9699
}
97100
this.tasks[projectId].push(task);
98-
this.tasks[projectId] = this.tasks[projectId].slice();
101+
this.updateVersion();
99102
this.tasksService.save(this.tasks);
100103
GaService.event(EEventCategory.Tasks, ETasksEvents.Create);
101104
}
@@ -130,12 +133,14 @@ export default class TaskStore {
130133
}
131134
}
132135
this.tasksService.save(this.tasks);
136+
this.updateVersion();
133137
GaService.event(EEventCategory.Tasks, ETasksEvents.Delete);
134138
}
135139

136140
deleteProjectTasks(projectKey: string) {
137141
delete this.tasks[projectKey];
138142
this.tasksService.save(this.tasks);
143+
this.updateVersion();
139144
}
140145

141146
startTimer(task: TaskModel) {
@@ -144,6 +149,7 @@ export default class TaskStore {
144149
task.start();
145150
this.setupReminder(task);
146151
this.tasksService.save(this.tasks);
152+
this.updateVersion();
147153
}
148154

149155
stopTimer(silent?: boolean) {
@@ -155,6 +161,7 @@ export default class TaskStore {
155161
if (!silent) {
156162
this.setupReminder();
157163
this.tasksService.save(this.tasks);
164+
this.updateVersion();
158165
}
159166
}
160167

@@ -188,7 +195,7 @@ export default class TaskStore {
188195
checkTaskFn
189196
);
190197

191-
this.set(projectId, this.tasks[projectId].slice());
198+
this.set(projectId, this.tasks[projectId]);
192199
}
193200
GaService.event(EEventCategory.Tasks, ETasksEvents.Check);
194201
}
@@ -207,7 +214,7 @@ export default class TaskStore {
207214
markExpanded
208215
);
209216

210-
this.set(projectId, this.tasks[projectId].slice());
217+
this.set(projectId, this.tasks[projectId]);
211218
}
212219
}
213220

@@ -275,4 +282,8 @@ export default class TaskStore {
275282
clearInterval(this.interval);
276283
}
277284
}
285+
286+
private updateVersion() {
287+
this.versionHash = uuid();
288+
}
278289
}

src/modules/tasks/models/TaskWithProjectNameModel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export class TaskWithProjectNameModel extends AbstractModel
1313
implements ITreeItemWithParent<TaskModel> {
1414
key: string = '';
1515
title: string = '';
16-
parent: TaskModel | null = null;
16+
parent: TaskModel | undefined = undefined;
1717
children: TaskModel[] = [];
1818

1919
constructor(props: ITaskWithProjectName) {

0 commit comments

Comments
 (0)