diff --git a/apps/web/app/[locale]/profile/[memberId]/page.tsx b/apps/web/app/[locale]/profile/[memberId]/page.tsx
index 5e1860dbd..3df5aebe6 100644
--- a/apps/web/app/[locale]/profile/[memberId]/page.tsx
+++ b/apps/web/app/[locale]/profile/[memberId]/page.tsx
@@ -41,21 +41,33 @@ const Profile = React.memo(function ProfilePage({ params }: { params: { memberId
const setActivityTypeFilter = useSetRecoilState(activityTypeState);
const hook = useTaskFilter(profile);
- const isManagerConnectedUser = activeTeamManagers.findIndex((member) => member.employee?.user?.id == user?.id);
- const canSeeActivity = profile.userProfile?.id === user?.id || isManagerConnectedUser != -1;
+ const isManagerConnectedUser = useMemo(
+ () => activeTeamManagers.findIndex((member) => member.employee?.user?.id == user?.id),
+ [activeTeamManagers, user?.id]
+ );
+ const canSeeActivity = useMemo(
+ () => profile.userProfile?.id === user?.id || isManagerConnectedUser != -1,
+ [isManagerConnectedUser, profile.userProfile?.id, user?.id]
+ );
const t = useTranslations();
- const breadcrumb = [
- { title: activeTeam?.name || '', href: '/' },
- { title: JSON.parse(t('pages.profile.BREADCRUMB')) || '', href: `/profile/${params.memberId}` }
- ];
-
- const activityScreens = {
- Tasks: ,
- Screenshots: ,
- Apps: ,
- 'Visited Sites':
- };
+ const breadcrumb = useMemo(
+ () => [
+ { title: activeTeam?.name || '', href: '/' },
+ { title: JSON.parse(t('pages.profile.BREADCRUMB')) || '', href: `/profile/${params.memberId}` }
+ ],
+ [activeTeam?.name, params.memberId, t]
+ );
+
+ const activityScreens = useMemo(
+ () => ({
+ Tasks: ,
+ Screenshots: ,
+ Apps: ,
+ 'Visited Sites':
+ }),
+ [hook, profile]
+ );
const profileIsAuthUser = useMemo(() => profile.isAuthUser, [profile.isAuthUser]);
const hookFilterType = useMemo(() => hook.filterType, [hook.filterType]);
diff --git a/apps/web/lib/features/task/task-card.tsx b/apps/web/lib/features/task/task-card.tsx
index 152ba751d..937afae9e 100644
--- a/apps/web/lib/features/task/task-card.tsx
+++ b/apps/web/lib/features/task/task-card.tsx
@@ -101,51 +101,64 @@ export function TaskCard(props: Props) {
const seconds = useRecoilValue(timerSecondsState);
const { activeTaskDailyStat, activeTaskTotalStat, addSeconds } = useTaskStatistics(seconds);
const { isTrackingEnabled, activeTeam } = useOrganizationTeams();
- const members = activeTeam?.members || [];
- const currentMember = members.find((m) => {
- return m.employee.user?.id === profile?.userProfile?.id;
- });
+ const members = useMemo(() => activeTeam?.members || [], [activeTeam?.members]);
+ const currentMember = useMemo(
+ () =>
+ members.find((m) => {
+ return m.employee.user?.id === profile?.userProfile?.id;
+ }),
+ [members, profile?.userProfile?.id]
+ );
const { h, m } = secondsToTime((activeTaskTotalStat?.duration || 0) + addSeconds);
- const totalWork =
- isAuthUser && activeAuthTask ? (
-
- {t('pages.taskDetails.TOTAL_TIME')}:
-
- {h}h : {m}m
-
-
- ) : (
- <>>
- );
-
+ const totalWork = useMemo(
+ () =>
+ isAuthUser && activeAuthTask ? (
+
+ {t('pages.taskDetails.TOTAL_TIME')}:
+
+ {h}h : {m}m
+
+
+ ) : (
+ <>>
+ ),
+ [activeAuthTask, h, isAuthUser, m, t]
+ );
// Daily work
- const { h: dh, m: dm } = secondsToTime((activeTaskDailyStat?.duration || 0) + addSeconds);
- const todayWork =
- isAuthUser && activeAuthTask ? (
-
- {t('common.TOTAL_WORK')}
-
- {dh}h : {dm}m
-
-
- ) : (
- <>>
- );
-
+ const { h: dh, m: dm } = useMemo(
+ () => secondsToTime((activeTaskDailyStat?.duration || 0) + addSeconds),
+ [activeTaskDailyStat?.duration, addSeconds]
+ );
+ const todayWork = useMemo(
+ () =>
+ isAuthUser && activeAuthTask ? (
+
+ {t('common.TOTAL_WORK')}
+
+ {dh}h : {dm}m
+
+
+ ) : (
+ <>>
+ ),
+ [activeAuthTask, dh, dm, isAuthUser, t]
+ );
const memberInfo = useTeamMemberCard(currentMember || undefined);
const taskEdition = useTMCardTaskEdit(task);
- const activeMembers = task != null && task?.members?.length > 0;
- const hasMembers = task?.members && task?.members?.length > 0;
- const taskAssignee: ImageOverlapperProps[] =
- task?.members?.map((member: any) => {
- return {
- id: member.user?.id,
- url: member.user?.imageUrl,
- alt: member.user?.firstName
- };
- }) || [];
-
+ const activeMembers = useMemo(() => task != null && task?.members?.length > 0, [task]);
+ const hasMembers = useMemo(() => task?.members && task?.members?.length > 0, [task?.members]);
+ const taskAssignee: ImageOverlapperProps[] = useMemo(
+ () =>
+ task?.members?.map((member: any) => {
+ return {
+ id: member.user?.id,
+ url: member.user?.imageUrl,
+ alt: member.user?.firstName
+ };
+ }) || [],
+ [task?.members]
+ );
return (
<>
} & IClassName) {
const t = useTranslations();
- const members = task?.members || [];
+ const members = useMemo(() => task?.members || [], [task?.members]);
return (
diff --git a/apps/web/lib/features/task/task-filters.tsx b/apps/web/lib/features/task/task-filters.tsx
index ff6c8f95d..9932545f3 100644
--- a/apps/web/lib/features/task/task-filters.tsx
+++ b/apps/web/lib/features/task/task-filters.tsx
@@ -48,15 +48,22 @@ type StatusFilter = { [x in IStatusType]: string[] };
*/
export function useTaskFilter(profile: I_UserProfilePage) {
const t = useTranslations();
- const defaultValue =
- typeof window !== 'undefined' ? (window.localStorage.getItem('task-tab') as ITab) || null : 'worked';
-
+ const defaultValue = useMemo(
+ () => (typeof window !== 'undefined' ? (window.localStorage.getItem('task-tab') as ITab) || null : 'worked'),
+ []
+ );
const { activeTeamManagers, activeTeam } = useOrganizationTeams();
const { user } = useAuthenticateUser();
const { profileDailyPlans } = useDailyPlan();
- const isManagerConnectedUser = activeTeamManagers.findIndex((member) => member.employee?.user?.id == user?.id);
- const canSeeActivity = profile.userProfile?.id === user?.id || isManagerConnectedUser != -1;
+ const isManagerConnectedUser = useMemo(
+ () => activeTeamManagers.findIndex((member) => member.employee?.user?.id == user?.id),
+ [activeTeamManagers, user?.id]
+ );
+ const canSeeActivity = useMemo(
+ () => profile.userProfile?.id === user?.id || isManagerConnectedUser != -1,
+ [isManagerConnectedUser, profile.userProfile?.id, user?.id]
+ );
const [tab, setTab] = useState(defaultValue || 'worked');
const [filterType, setFilterType] = useState(undefined);
@@ -67,14 +74,17 @@ export function useTaskFilter(profile: I_UserProfilePage) {
const [taskName, setTaskName] = useState('');
- const tasksFiltered: { [x in ITab]: ITeamTask[] } = {
- unassigned: profile.tasksGrouped.unassignedTasks,
- assigned: profile.tasksGrouped.assignedTasks,
- worked: profile.tasksGrouped.workedTasks,
- dailyplan: [] // Change this soon
- };
+ const tasksFiltered: { [x in ITab]: ITeamTask[] } = useMemo(
+ () => ({
+ unassigned: profile.tasksGrouped.unassignedTasks,
+ assigned: profile.tasksGrouped.assignedTasks,
+ worked: profile.tasksGrouped.workedTasks,
+ dailyplan: [] // Change this soon
+ }),
+ [profile.tasksGrouped.assignedTasks, profile.tasksGrouped.unassignedTasks, profile.tasksGrouped.workedTasks]
+ );
- const tasks = tasksFiltered[tab];
+ const tasks = useMemo(() => tasksFiltered[tab], [tab, tasksFiltered]);
const outclickFilterCard = useOutsideClick(() => {
if (filterType === 'search' && taskName.trim().length === 0) {
diff --git a/apps/web/lib/features/task/task-status.tsx b/apps/web/lib/features/task/task-status.tsx
index 72d78f1f1..df23da5ab 100644
--- a/apps/web/lib/features/task/task-status.tsx
+++ b/apps/web/lib/features/task/task-status.tsx
@@ -775,18 +775,18 @@ export function TaskStatus({
isEpic
}: PropsWithChildren<
TStatusItem &
- IClassName & {
- active?: boolean;
- issueType?: 'status' | 'issue';
- showIssueLabels?: boolean;
- forDetails?: boolean;
- titleClassName?: string;
- cheched?: boolean;
- sidebarUI?: boolean;
- value?: string;
- isVersion?: boolean;
- isEpic?: boolean;
- }
+ IClassName & {
+ active?: boolean;
+ issueType?: 'status' | 'issue';
+ showIssueLabels?: boolean;
+ forDetails?: boolean;
+ titleClassName?: string;
+ cheched?: boolean;
+ sidebarUI?: boolean;
+ value?: string;
+ isVersion?: boolean;
+ isEpic?: boolean;
+ }
>) {
const { theme } = useTheme();
const readableColorHex = readableColor(backgroundColor || (theme === 'light' ? '#FFF' : '#000'));
@@ -839,8 +839,8 @@ export function TaskStatus({
style={
isVersion || isEpic
? {
- color: theme === 'light' ? '#000' : '#FFF'
- }
+ color: theme === 'light' ? '#000' : '#FFF'
+ }
: {}
}
>
@@ -996,7 +996,7 @@ export function StatusDropdown({
sidebarUI && ['text-xs'],
'text-dark dark:text-white bg-[#F2F2F2] dark:bg-dark--theme-light',
forDetails &&
- 'bg-transparent border dark:border-[#FFFFFF33] dark:bg-[#1B1D22]',
+ 'bg-transparent border dark:border-[#FFFFFF33] dark:bg-[#1B1D22]',
taskStatusClassName
)}
name={
diff --git a/apps/web/lib/features/task/task-times.tsx b/apps/web/lib/features/task/task-times.tsx
index 79fd6b9f3..92d3ea545 100644
--- a/apps/web/lib/features/task/task-times.tsx
+++ b/apps/web/lib/features/task/task-times.tsx
@@ -4,6 +4,7 @@ import { IClassName, ITeamTask, Nullable, OT_Member } from '@app/interfaces';
import { clsxm } from '@app/utils';
import { Text, Tooltip } from 'lib/components';
import { useTranslations } from 'next-intl';
+import { useMemo } from 'react';
type Props = {
task: Nullable;
@@ -18,23 +19,35 @@ type Props = {
export function TaskTimes({ className, task, memberInfo, showDaily = true, showTotal = true, isBlock = false }: Props) {
// For public page
const { activeTeam } = useOrganizationTeams();
- const currentMember = activeTeam?.members.find((member) => member.id === memberInfo?.member?.id || memberInfo?.id);
+ const currentMember = useMemo(
+ () => activeTeam?.members.find((member) => member.id === memberInfo?.member?.id || memberInfo?.id),
+ [activeTeam?.members, memberInfo?.id, memberInfo?.member?.id]
+ );
- const { h, m } = secondsToTime(
- (currentMember?.totalWorkedTasks &&
- currentMember?.totalWorkedTasks?.length &&
- currentMember?.totalWorkedTasks
- .filter((t) => t.id === task?.id)
- .reduce((previousValue, currentValue) => previousValue + currentValue.duration, 0)) ||
- 0
+ const { h, m } = useMemo(
+ () =>
+ secondsToTime(
+ (currentMember?.totalWorkedTasks &&
+ currentMember?.totalWorkedTasks?.length &&
+ currentMember?.totalWorkedTasks
+ .filter((t) => t.id === task?.id)
+ .reduce((previousValue, currentValue) => previousValue + currentValue.duration, 0)) ||
+ 0
+ ),
+ [currentMember?.totalWorkedTasks, task?.id]
);
- const { h: dh, m: dm } = secondsToTime(
- (currentMember?.totalTodayTasks &&
- currentMember?.totalTodayTasks.length &&
- currentMember?.totalTodayTasks
- .filter((t) => t.id === task?.id)
- .reduce((previousValue, currentValue) => previousValue + currentValue.duration, 0)) ||
- 0
+
+ const { h: dh, m: dm } = useMemo(
+ () =>
+ secondsToTime(
+ (currentMember?.totalTodayTasks &&
+ currentMember?.totalTodayTasks.length &&
+ currentMember?.totalTodayTasks
+ .filter((t) => t.id === task?.id)
+ .reduce((previousValue, currentValue) => previousValue + currentValue.duration, 0)) ||
+ 0
+ ),
+ [currentMember?.totalTodayTasks, task?.id]
);
return (
diff --git a/apps/web/lib/features/user-profile-tasks.tsx b/apps/web/lib/features/user-profile-tasks.tsx
index 027b545fa..f7857f225 100644
--- a/apps/web/lib/features/user-profile-tasks.tsx
+++ b/apps/web/lib/features/user-profile-tasks.tsx
@@ -4,6 +4,7 @@ import { UserProfilePlans } from 'lib/features';
import { TaskCard } from './task/task-card';
import { I_TaskFilter } from './task/task-filters';
import { useTranslations } from 'next-intl';
+import { useMemo } from 'react';
type Props = {
tabFiltered: I_TaskFilter;
profile: I_UserProfilePage;
@@ -23,10 +24,11 @@ export function UserProfileTask({ profile, tabFiltered }: Props) {
/**
* When tab is worked, then filter exclude the active task
*/
- const tasks = tabFiltered.tasksFiltered;
+ const tasks = useMemo(() => tabFiltered.tasksFiltered, [tabFiltered.tasksFiltered]);
- const otherTasks = tasks.filter((t) =>
- profile.member?.running == true ? t.id !== profile.activeUserTeamTask?.id : t
+ const otherTasks = useMemo(
+ () => tasks.filter((t) => (profile.member?.running == true ? t.id !== profile.activeUserTeamTask?.id : t)),
+ [profile.activeUserTeamTask?.id, profile.member?.running, tasks]
);
// const data = otherTasks.length < 10 ? otherTasks : data;