Skip to content

Commit

Permalink
Merge pull request #2926 from ever-co/fix-timesheet-statistics-tasks-…
Browse files Browse the repository at this point in the history
…requests

Optimize Task Stats Data Loading
  • Loading branch information
evereq authored Aug 19, 2024
2 parents 3026f5a + a4ee92c commit e68eef4
Show file tree
Hide file tree
Showing 13 changed files with 91 additions and 58 deletions.
7 changes: 5 additions & 2 deletions apps/web/app/[locale]/profile/[memberId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,10 @@ const Profile = React.memo(function ProfilePage({ params }: { params: { memberId
<>
{Array.isArray(members) && members.length && !profile.member ? (
<MainLayout>
<div className=" absolute top-[50%] left-[50%] transform -translate-x-1/2 -translate-y-1/2">
<div
ref={profile.loadTaskStatsIObserverRef}
className="absolute top-[50%] left-[50%] transform -translate-x-1/2 -translate-y-1/2"
>
<div className="flex flex-col justify-center items-center gap-5">
<Text className="text-[40px] font-bold text-center text-[#282048] dark:text-light--theme">
{t('common.MEMBER')} {t('common.NOT_FOUND')}!
Expand All @@ -113,7 +116,7 @@ const Profile = React.memo(function ProfilePage({ params }: { params: { memberId
</div>
</MainLayout>
) : (
<MainLayout showTimer={headerSize <= 11.8 && isTrackingEnabled || !profileIsAuthUser}>
<MainLayout showTimer={(headerSize <= 11.8 && isTrackingEnabled) || !profileIsAuthUser}>
<ResizablePanelGroup direction="vertical">
<ResizablePanel
defaultSize={30}
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/[locale]/task/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const TaskDetails = () => {
showTimer={!profile.isAuthUser && isTrackingEnabled}
childrenClassName="bg-white dark:bg-dark--theme"
>
<div className="pt-20 pb-4 -mt-8 bg-white dark:bg-dark--theme">
<div ref={profile.loadTaskStatsIObserverRef} className="pt-20 pb-4 -mt-8 bg-white dark:bg-dark--theme">
<Container fullWidth={fullWidth}>
<div className="flex items-center gap-8">
<span
Expand Down
38 changes: 38 additions & 0 deletions apps/web/app/hooks/features/useGetTasksStatsData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { useEffect, useRef } from 'react';
import { useTaskStatistics } from './useTaskStatistics';
import { useIntersectionObserver } from '@uidotdev/usehooks';

export function useGetTasksStatsData(employeeId: string | undefined, triggerWithIObserver = true) {
const refMap = useRef(new Map());
const { getTasksStatsData } = useTaskStatistics();
const [IObserverRef, entry] = useIntersectionObserver({
threshold: 0,
root: null,
rootMargin: '0px'
});

useEffect(() => {
if (!employeeId) return;

const map = refMap.current;

const loadTaskStats = () => {
if (!map.has(employeeId)) {
map.set(employeeId, true);
getTasksStatsData(employeeId);
}
};

const supported = 'IntersectionObserver' in window;

if (!triggerWithIObserver || !supported) {
loadTaskStats();
}

if (entry?.isIntersecting && supported) {
loadTaskStats();
}
}, [employeeId, triggerWithIObserver, entry]);

return IObserverRef;
}
3 changes: 2 additions & 1 deletion apps/web/app/hooks/features/useTaskActivity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export function useTaskTimeSheets(id: string) {
return {
taskTimesheets,
getTaskTimesheets,
loading
loading,
loadTaskStatsIObserverRef: profile.loadTaskStatsIObserverRef
};
}
2 changes: 1 addition & 1 deletion apps/web/app/hooks/features/useTaskStatistics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ export function useTaskStatistics(addSeconds = 0) {
Math.min(
Math.floor(
(((_task?.totalWorkedTime || timeSheet?.duration || 0) + addSeconds) * 100) /
(estimate || _task?.estimate || 0)
(estimate || _task?.estimate || 0)
),
100
),
Expand Down
15 changes: 5 additions & 10 deletions apps/web/app/hooks/features/useUserDetails.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
'use client';

import { ITeamTask } from '@app/interfaces';
import { useCallback, useEffect } from 'react';
import { useCallback } from 'react';
import { useAuthenticateUser } from './useAuthenticateUser';
import { useAuthTeamTasks } from './useAuthTeamTasks';
import { useOrganizationTeams } from './useOrganizationTeams';
import { useTaskStatistics } from './useTaskStatistics';
import { useTeamTasks } from './useTeamTasks';
import { useGetTasksStatsData } from './useGetTasksStatsData';

export function useUserDetails(memberId: string) {
const { activeTeam } = useOrganizationTeams();
const { activeTeamTask, updateTask } = useTeamTasks();

const { user: auth } = useAuthenticateUser();
const { getTasksStatsData } = useTaskStatistics();

const members = activeTeam?.members || [];

Expand All @@ -32,12 +31,7 @@ export function useUserDetails(memberId: string) {
/* Filtering the tasks */
const tasksGrouped = useAuthTeamTasks(userProfile);

useEffect(() => {
if (employeeId) {
getTasksStatsData(employeeId);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [employeeId]);
const loadTaskStatsIObserverRef = useGetTasksStatsData(employeeId);

const assignTask = useCallback(
(task: ITeamTask) => {
Expand All @@ -59,7 +53,8 @@ export function useUserDetails(memberId: string) {
userProfile,
tasksGrouped,
member: matchUser,
assignTask
assignTask,
loadTaskStatsIObserverRef
};
}

Expand Down
19 changes: 7 additions & 12 deletions apps/web/app/hooks/features/useUserProfilePage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,21 @@

import { ITeamTask } from '@app/interfaces';
import { useParams } from 'next/navigation';
import { useCallback, useEffect, useMemo } from 'react';
import { useCallback, useMemo } from 'react';
import { useAuthenticateUser } from './useAuthenticateUser';
import { useAuthTeamTasks } from './useAuthTeamTasks';
import { useOrganizationTeams } from './useOrganizationTeams';
import { useTaskStatistics } from './useTaskStatistics';
import { useTeamTasks } from './useTeamTasks';
import { useRecoilValue } from 'recoil';
import { userDetailAccordion } from '@app/stores';
import { useGetTasksStatsData } from './useGetTasksStatsData';

export function useUserProfilePage() {
const { activeTeam } = useOrganizationTeams();
const { activeTeamTask, updateTask } = useTeamTasks();
const userMemberId = useRecoilValue(userDetailAccordion);

const { user: auth } = useAuthenticateUser();
const { getTasksStatsData } = useTaskStatistics();
const params = useParams();
const memberId: string = useMemo(() => {
return (params?.memberId ?? userMemberId) as string;
Expand All @@ -36,17 +35,12 @@ export function useUserProfilePage() {

const userProfile = isAuthUser ? auth : matchUser?.employee.user;

const employeeId = isAuthUser ? auth?.employee?.id : matchUser?.employeeId;

/* Filtering the tasks */
const tasksGrouped = useAuthTeamTasks(userProfile);

useEffect(() => {
if (employeeId) {
getTasksStatsData(employeeId);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [employeeId]);
const employeeId = isAuthUser ? auth?.employee?.id : matchUser?.employeeId;

const loadTaskStatsIObserverRef = useGetTasksStatsData(employeeId);

const assignTask = useCallback(
(task: ITeamTask) => {
Expand All @@ -68,7 +62,8 @@ export function useUserProfilePage() {
userProfile,
tasksGrouped,
member: matchUser,
assignTask
assignTask,
loadTaskStatsIObserverRef
};
}

Expand Down
19 changes: 7 additions & 12 deletions apps/web/app/hooks/features/useUserSelectedPage.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
'use client';

import { ITeamTask } from '@app/interfaces';
import { useCallback, useEffect } from 'react';
import { useCallback } from 'react';
import { useAuthenticateUser } from './useAuthenticateUser';
import { useAuthTeamTasks } from './useAuthTeamTasks';
import { useOrganizationTeams } from './useOrganizationTeams';
import { useTaskStatistics } from './useTaskStatistics';
import { useTeamTasks } from './useTeamTasks';
import { useGetTasksStatsData } from './useGetTasksStatsData';

export function useUserSelectedPage(id?: string) {
const { activeTeam } = useOrganizationTeams();
const { activeTeamTask, updateTask } = useTeamTasks();

const { user: auth } = useAuthenticateUser();
const { getTasksStatsData } = useTaskStatistics();

const memberId: string = id || '';

Expand All @@ -29,17 +28,12 @@ export function useUserSelectedPage(id?: string) {

const userProfile = isAuthUser ? auth : matchUser?.employee.user;

const employeeId = isAuthUser ? auth?.employee?.id : matchUser?.employeeId;

/* Filtering the tasks */
const tasksGrouped = useAuthTeamTasks(userProfile);

useEffect(() => {
if (employeeId) {
getTasksStatsData(employeeId);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [employeeId]);
const employeeId = isAuthUser ? auth?.employee?.id : matchUser?.employeeId;

const loadTaskStatsIObserverRef = useGetTasksStatsData(employeeId);

const assignTask = useCallback(
(task: ITeamTask) => {
Expand All @@ -61,7 +55,8 @@ export function useUserSelectedPage(id?: string) {
userProfile,
tasksGrouped,
member: matchUser,
assignTask
assignTask,
loadTaskStatsIObserverRef
};
}

Expand Down
30 changes: 16 additions & 14 deletions apps/web/lib/features/task/task-activity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function TaskActivity({ task }: { task: ITeamTask }) {

<div className="flex items-center justify-end gap-2.5">
<button onClick={() => setHidden((e) => !e)}>
{hidden ? (
{hidden ? (
<ChevronDownIcon className="h-4 w-4 text-[#293241] dark:text-white cursor-pointer" />
) : (
<ChevronUpIcon className="h-4 w-4 text-[#293241] dark:text-white cursor-pointer" />
Expand All @@ -41,19 +41,21 @@ export function TaskActivity({ task }: { task: ITeamTask }) {
</div>
</div>
<div className={clsxm('flex flex-col max-h-80 gap-3', hidden && ['hidden'])}>
{groupedData.length < 1 ?
<p className="mx-auto ">There is no Activity</p> :
groupedData.map((timesheet, i) => (
<div
key={i}
className="shadow-lg rounded-lg p-4 bg-light dark:bg-dark border border-[#00000014] dark:border-[#26272C]"
>
<h3 className="text-base font-semibold py-2">{timesheet.date}</h3>
{timesheet.items.map((item) => (
<UserTaskActivity key={item.id} timesheet={item} />
))}
</div>
))}
{groupedData.length < 1 ? (
<p className="mx-auto ">There is no Activity</p>
) : (
groupedData.map((timesheet, i) => (
<div
key={i}
className="shadow-lg rounded-lg p-4 bg-light dark:bg-dark border border-[#00000014] dark:border-[#26272C]"
>
<h3 className="text-base font-semibold py-2">{timesheet.date}</h3>
{timesheet.items.map((item) => (
<UserTaskActivity key={item.id} timesheet={item} />
))}
</div>
))
)}
</div>
</Card>
);
Expand Down
2 changes: 1 addition & 1 deletion apps/web/lib/features/team-members-card-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const TeamMembersCardView: React.FC<Props> = ({
profile={profile}
/>

<ul className="mt-7">
<ul className="mt-7" ref={profile.loadTaskStatsIObserverRef}>
{/* Current authenticated user members */}
<Transition
show={!!currentUser}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ export function UserTeamBlockHeader() {

return (
<>
<div className="hidden sm:flex dark:bg-dark-high font-normal pt-7 justify-between dark:text-[#7B8089]">
<div
ref={profile.loadTaskStatsIObserverRef}
className="hidden sm:flex dark:bg-dark-high font-normal pt-7 justify-between dark:text-[#7B8089]"
>
<div className="flex items-center w-9/12">
<div
className={clsxm(
Expand Down
5 changes: 3 additions & 2 deletions apps/web/lib/features/team/user-team-card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ export function UserTeamCard({
onDragEnter={onDragEnter}
onDragEnd={onDragEnd}
onDragOver={onDragOver}
ref={profile.loadTaskStatsIObserverRef}
>
<Card
shadow="bigger"
Expand Down Expand Up @@ -256,8 +257,8 @@ export function UserTeamCard({
<div className="absolute right-2">{menu}</div>
</div>
{userDetailAccordion == memberInfo.memberUser?.id &&
memberInfo.memberUser.id == profile.userProfile?.id &&
!showActivity ? (
memberInfo.memberUser.id == profile.userProfile?.id &&
!showActivity ? (
<div className="h-96 overflow-y-auto">
{canSeeActivity && (
<Container fullWidth={fullWidth} className="py-8">
Expand Down
2 changes: 1 addition & 1 deletion apps/web/lib/features/user-profile-plans.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export function UserProfilePlans() {
}, [currentTab, setCurrentDataDailyPlan, setDate, date]);

return (
<div className="">
<div ref={profile.loadTaskStatsIObserverRef}>
<Container fullWidth={fullWidth} className="pb-8 mb-5">
<>
{profileDailyPlans?.items?.length > 0 ? (
Expand Down

0 comments on commit e68eef4

Please sign in to comment.