Skip to content

Commit

Permalink
Merge pull request #1503 from ever-co/develop
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
evereq authored Oct 4, 2023
2 parents 28c6c2f + 40cce9c commit 52445c6
Show file tree
Hide file tree
Showing 37 changed files with 341 additions and 285 deletions.
58 changes: 34 additions & 24 deletions apps/mobile/app/services/client/queries/timer/timer.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,47 @@
import { useQuery } from "react-query"
import { getTimerStatusRequest, syncTimeSlotRequest } from "../../requests/timer"
import { ITimerTimeslotParams } from "../../../interfaces/ITimer"
import { ITimerTimeslotParams, TimerSource } from "../../../interfaces/ITimer"

type IGetTimerStatusParams = ITimerTimeslotParams & { authToken: string }

const fetchTimerStatus = async (params: IGetTimerStatusParams) => {
const fetchTimerStatus = async (
params: IGetTimerStatusParams,
isTimerRunning: boolean,
lastlogTimerSource: TimerSource | null,
) => {
const { tenantId, organizationId, logType, authToken, employeeId } = params

const { data } = await getTimerStatusRequest(
{ source: "MOBILE", tenantId, organizationId },
authToken,
)
if (isTimerRunning) {
await syncTimeSlotRequest(
{
tenantId,
organizationId,
source: lastlogTimerSource || TimerSource.MOBILE,
employeeId,
duration: 5,
logType,
},
authToken,
)
}

await syncTimeSlotRequest(
{
tenantId,
organizationId,
source: "MOBILE",
employeeId,
duration: 5,
logType,
},
authToken,
)
const { data } = await getTimerStatusRequest({ tenantId, organizationId }, authToken)

return data
}

const useFetchTimerStatus = (IGetTimerStatusParams, isTimerRunning: boolean) =>
useQuery(["status-timer", IGetTimerStatusParams], () => fetchTimerStatus(IGetTimerStatusParams), {
enabled: isTimerRunning,
refetchInterval: 5000,
notifyOnChangeProps: ["data"], // Re-render only when data changes
notifyOnChangePropsExclusions: ["isFetching"],
})
const useFetchTimerStatus = (
IGetTimerStatusParams,
isTimerRunning: boolean,
lastlogTimerSource: TimerSource,
) =>
useQuery(
["status-timer", IGetTimerStatusParams],
() => fetchTimerStatus(IGetTimerStatusParams, isTimerRunning, lastlogTimerSource),
{
refetchInterval: 5000,
notifyOnChangeProps: ["data"], // Re-render only when data changes
notifyOnChangePropsExclusions: ["isFetching"],
},
)
export default useFetchTimerStatus
13 changes: 10 additions & 3 deletions apps/mobile/app/services/client/requests/timer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import {
ITimerStatus,
ITimerParams,
ITimerTimeslotParams,
TimerSource,
} from "../../interfaces/ITimer"
import { serverFetch } from "../fetch"

export function getTimerStatusRequest(
{ source = "MOBILE", tenantId, organizationId }: ITimerStatusParams,
{ tenantId, organizationId }: ITimerStatusParams,
bearer_token: string,
) {
const params = new URLSearchParams({ source, tenantId, organizationId })
const params = new URLSearchParams({ tenantId, organizationId })
return serverFetch<ITimerStatus>({
path: `/timesheet/timer/status?${params.toString()}`,
method: "GET",
Expand Down Expand Up @@ -42,7 +43,13 @@ export function stopTimerRequest(params: ITimerParams, bearer_token: string) {
}

export function toggleTimerRequest(
{ source = "MOBILE", logType = "TRACKED", taskId, tenantId, organizationId }: ITimerParams,
{
source = TimerSource.MOBILE,
logType = "TRACKED",
taskId,
tenantId,
organizationId,
}: ITimerParams,
bearer_token: string,
) {
return serverFetch<ITimer>({
Expand Down
24 changes: 17 additions & 7 deletions apps/mobile/app/services/hooks/useTimer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { convertMsToTime, secondsToTime } from "../../helpers/date"
import { startTimerRequest, stopTimerRequest, toggleTimerRequest } from "../client/requests/timer"
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
import { useSyncRef } from "./useSyncRef"
import { ILocalTimerStatus, ITimerParams, ITimerStatus } from "../interfaces/ITimer"
import { ILocalTimerStatus, ITimerParams, ITimerStatus, TimerSource } from "../interfaces/ITimer"
import { useFirstLoad } from "./useFirstLoad"
import isEqual from "lodash/isEqual"
import AsyncStorage from "@react-native-async-storage/async-storage"
Expand All @@ -12,6 +12,7 @@ import { ITeamTask } from "../interfaces/ITask"
import { useTeamTasks } from "./features/useTeamTasks"
import useFetchTimerStatus from "../client/queries/timer/timer"
import { useTaskStatistics } from "./features/useTaskStatics"
import moment from "moment-timezone"

const LOCAL_TIMER_STORAGE_KEY = "local-timer-ever-teams"

Expand Down Expand Up @@ -70,9 +71,17 @@ function useLocalTimeCounter(
;(async () => {
const localStatus = await getLocalCounterStatus()
localStatus && setLocalTimerStatus(localStatus)

const timerStatusDate = timerStatus?.lastLog?.createdAt
? moment(timerStatus?.lastLog?.createdAt).unix() * 1000 - timerStatus?.lastLog?.duration
: 0

timerStatus &&
updateLocalTimerStatus({
runnedDateTime: localStatus?.runnedDateTime || (timerStatus.running ? Date.now() : 0),
runnedDateTime:
(timerStatus.running ? timerStatusDate || Date.now() : 0) ||
localStatus?.runnedDateTime ||
0,
running: timerStatus.running,
lastTaskId: timerStatus.lastLog?.taskId || null,
})
Expand Down Expand Up @@ -164,13 +173,14 @@ export function useTimer() {
employeeId: user?.employee?.id,
},
timerStatus?.running,
timerStatusRef.current?.lastLog?.source,
)

const toggleTimer = useCallback(async (taskId: string) => {
const response = await toggleTimerRequest(
{
logType: "TRACKED",
source: "MOBILE",
source: TimerSource.MOBILE,
tags: [],
taskId,
tenantId,
Expand Down Expand Up @@ -208,7 +218,7 @@ export function useTimer() {
tenantId,
taskId: activeTask?.id,
logType: "TRACKED",
source: "MOBILE",
source: TimerSource.MOBILE,
tags: [],
}

Expand All @@ -225,11 +235,11 @@ export function useTimer() {
/**
* Updating the task status to "In Progress" when the timer is started.
*/
if (activeTeamTaskRef.current && activeTeamTaskRef.current.status !== "in progress") {
if (activeTeamTaskRef.current && activeTeamTaskRef.current.status !== "in-progress") {
updateTask(
{
...activeTeamTaskRef.current,
status: "in progress",
status: "in-progress",
},
taskId.current,
)
Expand All @@ -251,7 +261,7 @@ export function useTimer() {
tenantId,
taskId: activeTask?.id,
logType: "TRACKED",
source: "MOBILE",
source: timerStatusRef.current.lastLog.source || TimerSource.MOBILE,
tags: [],
}

Expand Down
18 changes: 14 additions & 4 deletions apps/mobile/app/services/interfaces/ITimer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export interface ITimer {
startedAt: string
stoppedAt: string
logType: string
source: string
source: TimerSource
description: any
reason: any
isBillable: boolean
Expand All @@ -22,6 +22,16 @@ export interface ITimer {
isEdited: boolean
}

export enum TimerSource {
"MOBILE" = "MOBILE",
"BROWSER" = "BROWSER",
"DESKTOP" = "DESKTOP",
"BROWSER_EXTENSION" = "BROWSER_EXTENSION",
"HUBSTAFF" = "HUBSTAFF",
"UPWORK" = "UPWORK",
"TEAMS" = "TEAMS",
}

export interface ITimerStatus {
duration: number
lastLog?: ITimer
Expand All @@ -45,15 +55,15 @@ export type ITimerTimeslotParams = {
organizationId: string
employeeId: string
logType: "TRACKED"
source: "MOBILE"
source: TimerSource
tenantId: string
duration?: number
recordedAt?: Date | string
startedAt?: Date | string
}

export type ITimerStatusParams = {
source?: "MOBILE"
source?: TimerSource
tenantId: string
organizationId: string
}
Expand All @@ -63,7 +73,7 @@ export type ITimerParams = {
tenantId: string
taskId: string
logType: "TRACKED"
source: "MOBILE"
source: TimerSource
tags: any[]
}

Expand Down
35 changes: 16 additions & 19 deletions apps/web/app/hooks/auth/useEmailVerifyToken.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { verifyUserEmailByTokenAPI } from '@app/services/client/api';
import { AxiosError } from 'axios';
import { useRouter } from 'next/router';
import { useEffect, useRef, useState } from 'react';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useQuery } from '../useQuery';

export function useEmailVerifyToken() {
Expand All @@ -17,23 +17,20 @@ export function useEmailVerifyToken() {
/**
* Verify Email by token request
*/
const verifyEmailRequest = ({
email,
token
}: {
email: string;
token: string;
}) => {
queryCall(email, token)
.then(() => {
window.location.replace('/');
})
.catch((err: AxiosError) => {
if (err.response?.status === 400) {
setErrors((err.response?.data as any)?.errors || {});
}
});
};
const verifyEmailRequest = useCallback(
({ email, token }: { email: string; token: string }) => {
queryCall(email, token)
.then(() => {
window.location.replace('/');
})
.catch((err: AxiosError) => {
if (err.response?.status === 400) {
setErrors((err.response?.data as any)?.errors || {});
}
});
},
[queryCall]
);

/**
* Verify token immediately if email and token were passed from url
Expand All @@ -47,7 +44,7 @@ export function useEmailVerifyToken() {

loginFromQuery.current = true;
}
}, [query]);
}, [query, verifyEmailRequest]);

return {
errors,
Expand Down
16 changes: 9 additions & 7 deletions apps/web/app/hooks/features/useAuthTeamTasks.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { IUser } from '@app/interfaces';
import { tasksByTeamState, tasksStatisticsState } from '@app/stores';
import { tasksByTeamState } from '@app/stores';
import { useMemo } from 'react';
import { useRecoilValue } from 'recoil';
import { useOrganizationTeams } from './useOrganizationTeams';

export function useAuthTeamTasks(user: IUser | undefined) {
const tasks = useRecoilValue(tasksByTeamState);
const statTasks = useRecoilValue(tasksStatisticsState);

const { activeTeam } = useOrganizationTeams();
const currentMember = activeTeam?.members.find(
Expand All @@ -27,16 +26,19 @@ export function useAuthTeamTasks(user: IUser | undefined) {
});
}, [tasks, user]);

const totalTodayTasks =
currentMember?.totalTodayTasks && currentMember?.totalTodayTasks.length
? currentMember?.totalTodayTasks.map((task) => task.id)
: [];
const totalTodayTasks = useMemo(
() =>
currentMember?.totalTodayTasks && currentMember?.totalTodayTasks.length
? currentMember?.totalTodayTasks.map((task) => task.id)
: [],
[currentMember]
);

const workedTasks = useMemo(() => {
return tasks.filter((tsk) => {
return totalTodayTasks.includes(tsk.id);
});
}, [statTasks, tasks, totalTodayTasks]);
}, [tasks, totalTodayTasks]);

return {
assignedTasks,
Expand Down
8 changes: 6 additions & 2 deletions apps/web/app/hooks/features/useEmployee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,15 @@ export const useEmployee = () => {
setWorkingEmployeesEmail(items.map((item) => item.user?.email || ''));
}
});
}, [getWorkingEmployeeQueryCall]);
}, [
getWorkingEmployeeQueryCall,
setWorkingEmployees,
setWorkingEmployeesEmail
]);

useEffect(() => {
getWorkingEmployee();
}, []);
}, [getWorkingEmployee]);

return {
getWorkingEmployeeQueryCall,
Expand Down
Loading

0 comments on commit 52445c6

Please sign in to comment.