Skip to content

Commit

Permalink
Merge pull request #3161 from ever-co/3155-bug-settings--enforce-plan…
Browse files Browse the repository at this point in the history
…s-how-it-should-work

3155 bug settings  enforce plans how it should work
  • Loading branch information
Cedric921 authored Oct 18, 2024
2 parents 07f0a94 + 3665230 commit d517bf1
Show file tree
Hide file tree
Showing 21 changed files with 114 additions and 68 deletions.
2 changes: 1 addition & 1 deletion apps/web/app/hooks/features/useStartStopTimerHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export function useStartStopTimerHandler() {
if (timerStatusFetching || !canRunTimer) return;
if (timerStatus?.running) {
stopTimer();
} else if (requirePlan && !isActiveTaskPlaned) {
} else if (requirePlan && hasPlan && !isActiveTaskPlaned) {
openEnforcePlannedTaskModal();
} else {
if (
Expand Down
4 changes: 1 addition & 3 deletions apps/web/app/hooks/features/useTimer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,7 @@ export function useTimer() {
user?.isEmailVerified &&
((!!activeTeamTask && activeTeamTask.status !== 'closed') ||
// If timer is running at some other source and user may or may not have selected the task
timerStatusRef.current?.lastLog?.source !== TimerSource.TEAMS) &&
// If team settings require to have a plan to be able track
canTrack;
timerStatusRef.current?.lastLog?.source !== TimerSource.TEAMS)

// Local time status
const {
Expand Down
54 changes: 30 additions & 24 deletions apps/web/lib/components/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type Props = {
className?: string;
alignCloseIcon?: boolean;
showCloseIcon?: boolean;
closeOnOutsideClick?: boolean;
} & PropsWithChildren;

export function Modal({
Expand All @@ -27,7 +28,8 @@ export function Modal({
description,
className,
alignCloseIcon,
showCloseIcon = true
showCloseIcon = true,
closeOnOutsideClick = false
}: Props) {
const refDiv = useRef(null);

Expand All @@ -44,36 +46,40 @@ export function Modal({
>
<Dialog
initialFocus={refDiv}
onClose={closeModal}
onClose={closeOnOutsideClick ? closeModal : () => null}
as="div"
className="fixed inset-0 backdrop-brightness-90 backdrop-blur-sm z-[9999] w-full h-full"
>
<div ref={refDiv} className="absolute inset-0 flex items-center justify-center p-4 w-full">
<Dialog.Overlay
className={clsxm('flex justify-center items-center flex-col space-y-1 relative', className)}
>
{title && <Dialog.Title className={clsxm(titleClass)}>{title}</Dialog.Title>}
{description && <Dialog.Description>{description}</Dialog.Description>}
{showCloseIcon && (
<div
onClick={() => {
closeModal();
customCloseModal?.();
}}
className={`absolute ${
alignCloseIcon ? 'right-2 top-3' : 'right-3 top-3'
} md:right-2 md:top-3 cursor-pointer z-50`}
>
<Image
src={'/assets/svg/close.svg'}
alt="close"
width={28}
height={28}
className="w-6 md:w-7"
/>
</div>
)}
{children}
<Dialog.Panel
className={clsxm('flex justify-center items-center flex-col space-y-1 relative', className)}
>
{title && <Dialog.Title className={clsxm(titleClass)}>{title}</Dialog.Title>}
{description && <Dialog.Description>{description}</Dialog.Description>}
{showCloseIcon && (
<div
onClick={() => {
closeModal();
customCloseModal?.();
}}
className={`absolute ${
alignCloseIcon ? 'right-2 top-3' : 'right-3 top-3'
} md:right-2 md:top-3 cursor-pointer z-50`}
>
<Image
src={'/assets/svg/close.svg'}
alt="close"
width={28}
height={28}
className="w-6 md:w-7"
/>
</div>
)}
{children}
</Dialog.Panel>
</Dialog.Overlay>
</div>
</Dialog>
Expand Down
4 changes: 4 additions & 0 deletions apps/web/lib/components/switch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Switch } from '@headlessui/react';
import { useCallback, useEffect, useState } from 'react';
import { Text } from './typography';
import { useTranslations } from 'next-intl';
import { DAILY_PLAN_SUGGESTION_MODAL_DATE } from '@app/constants';

export default function TimeTrackingToggle({ activeManager }: { activeManager: OT_Member | undefined }) {
const t = useTranslations();
Expand Down Expand Up @@ -129,6 +130,9 @@ export function RequireDailyPlanToTrack() {
.filter((value, index, array) => array.indexOf(value) === index)
});
setEnabled(!enabled);
if (!enabled) {
localStorage.removeItem(DAILY_PLAN_SUGGESTION_MODAL_DATE);
}
}
}, [activeTeam, editOrganizationTeam, enabled]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function AddDailyPlanWorkHourModal(props: IAddDailyPlanWorkHoursModalProp
}, [handleCloseModal, plan, startTimer, updateDailyPlan, workTimePlanned]);

return (
<Modal isOpen={isOpen} closeModal={handleCloseModal} showCloseIcon={requirePlan ? false : true}>
<Modal isOpen={isOpen} closeModal={handleCloseModal} showCloseIcon>
<Card className="w-full" shadow="custom">
<div className="flex flex-col justify-between">
<div className="mb-7">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,10 @@ export function AddTasksEstimationHoursModal(props: IAddTasksEstimationHoursModa
const t = useTranslations();
const { updateDailyPlan, myDailyPlans } = useDailyPlan();
const { startTimer, timerStatus } = useTimerView();
const { activeTeam, activeTeamTask, setActiveTask } = useTeamTasks();
const { activeTeamTask, setActiveTask } = useTeamTasks();
const [showSearchInput, setShowSearchInput] = useState(false);
const [workTimePlanned, setWorkTimePlanned] = useState<number>(plan?.workTimePlanned ?? 0);
const currentDate = useMemo(() => new Date().toISOString().split('T')[0], []);
const requirePlan = useMemo(() => activeTeam?.requirePlanToTrack, [activeTeam?.requirePlanToTrack]);
const tasksEstimationTimes = useMemo(
() => (plan && plan.tasks ? estimatedTotalTime(plan.tasks).timesEstimated / 3600 : 0),
[plan]
Expand Down Expand Up @@ -466,15 +465,7 @@ export function AddTasksEstimationHoursModal(props: IAddTasksEstimationHoursModa
</div>
<div className=" flex justify-between items-center">
<Button
disabled={
loading || isRenderedInSoftFlow
? canStartWorking && requirePlan
: timerStatus?.running
? canStartWorking && requirePlan && (planEditState.draft || warning)
? true
: false
: canStartWorking && requirePlan && Boolean(warning)
}
disabled={loading}
variant="outline"
type="submit"
className="py-3 px-5 w-40 rounded-md font-light text-md dark:text-white dark:bg-slate-700 dark:border-slate-600"
Expand All @@ -501,7 +492,7 @@ export function AddTasksEstimationHoursModal(props: IAddTasksEstimationHoursModa
return (
<>
{isRenderedInSoftFlow ? (
<Modal isOpen={isOpen} closeModal={closeModalAndSubmit} showCloseIcon={requirePlan ? false : true}>
<Modal isOpen={isOpen} closeModal={closeModalAndSubmit} showCloseIcon>
<Card className="w-[36rem]" shadow="custom">
{content}
</Card>
Expand Down
23 changes: 17 additions & 6 deletions apps/web/lib/features/daily-plan/suggest-daily-plan-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useCallback, useMemo } from 'react';
import { DAILY_PLAN_SUGGESTION_MODAL_DATE, HAS_SEEN_DAILY_PLAN_SUGGESTION_MODAL } from '@app/constants';
import { useTranslations } from 'next-intl';
import Link from 'next/link';
import { useAuthenticateUser } from '@app/hooks';
import { useAuthenticateUser, useTeamTasks, useTimer } from '@app/hooks';
import { usePathname } from 'next/navigation';

interface ISuggestDailyPlanModalProps {
Expand All @@ -14,27 +14,38 @@ interface ISuggestDailyPlanModalProps {

export function SuggestDailyPlanModal(props: ISuggestDailyPlanModalProps) {
const { isOpen, closeModal } = props;

const { hasPlan } = useTimer();
const { activeTeam } = useTeamTasks();
const { user } = useAuthenticateUser();
const name = useMemo(
() => user?.name || user?.firstName || user?.lastName || user?.username || '',
[user?.firstName, user?.lastName, user?.name, user?.username]
);
const requirePlan = useMemo(() => activeTeam?.requirePlanToTrack, [activeTeam?.requirePlanToTrack]);
const path = usePathname();
const t = useTranslations();

const currentDate = useMemo(() => new Date().toISOString().split('T')[0], []);

const handleCloseModal = useCallback(() => {
localStorage.setItem(HAS_SEEN_DAILY_PLAN_SUGGESTION_MODAL, currentDate);
if (!requirePlan || (requirePlan && hasPlan)) {
localStorage.setItem(HAS_SEEN_DAILY_PLAN_SUGGESTION_MODAL, currentDate);
}
if (path.split('/')[1] == 'profile') {
localStorage.setItem(DAILY_PLAN_SUGGESTION_MODAL_DATE, currentDate);
if (!requirePlan || (requirePlan && hasPlan)) {
localStorage.setItem(DAILY_PLAN_SUGGESTION_MODAL_DATE, currentDate);
}
}
closeModal();
}, [closeModal, currentDate, path]);
}, [closeModal, currentDate, hasPlan, path, requirePlan]);

return (
<Modal isOpen={isOpen} closeModal={handleCloseModal} showCloseIcon={false}>
<Modal
closeOnOutsideClick={requirePlan}
isOpen={isOpen}
closeModal={handleCloseModal}
showCloseIcon={requirePlan}
>
<Card className="w-full" shadow="custom">
<div className="flex flex-col items-center justify-between">
<div className="mb-7">
Expand Down
39 changes: 31 additions & 8 deletions apps/web/lib/features/user-profile-plans.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@ import { IoCalendarOutline } from 'react-icons/io5';

import { formatDayPlanDate, formatIntegerToHour } from '@app/helpers';
import { handleDragAndDrop } from '@app/helpers/drag-and-drop';
import { useAuthenticateUser, useCanSeeActivityScreen, useDailyPlan, useUserProfilePage } from '@app/hooks';
import {
useAuthenticateUser,
useCanSeeActivityScreen,
useDailyPlan,
useTeamTasks,
useTimer,
useUserProfilePage
} from '@app/hooks';
import { useDateRange } from '@app/hooks/useDateRange';
import { filterDailyPlan } from '@app/hooks/useFilterDateRange';
import { useLocalStorageState } from '@app/hooks/useLocalStorageState';
Expand Down Expand Up @@ -54,9 +61,7 @@ export function UserProfilePlans() {
const { todayPlan, futurePlans, pastPlans, outstandingPlans, sortedPlans, profileDailyPlans } = useDailyPlan();
const fullWidth = useAtomValue(fullWidthState);
const [currentOutstanding, setCurrentOutstanding] = useLocalStorageState<FilterOutstanding>('outstanding', 'ALL');

const [currentTab, setCurrentTab] = useLocalStorageState<FilterTabs>('daily-plan-tab', 'Today Tasks');

const [currentDataDailyPlan, setCurrentDataDailyPlan] = useAtom(dataDailyPlanState);
const { setDate, date } = useDateRange(currentTab);

Expand All @@ -77,6 +82,9 @@ export function UserProfilePlans() {
const dailyPlanSuggestionModalDate = window && window?.localStorage.getItem(DAILY_PLAN_SUGGESTION_MODAL_DATE);
const path = usePathname();
const haveSeenDailyPlanSuggestionModal = window?.localStorage.getItem(HAS_SEEN_DAILY_PLAN_SUGGESTION_MODAL);
const { hasPlan } = useTimer();
const { activeTeam } = useTeamTasks();
const requirePlan = useMemo(() => activeTeam?.requirePlanToTrack, [activeTeam?.requirePlanToTrack]);

// Set the tab plan tab to outstanding if user has no daily plan and there are outstanding tasks (on first load)
useEffect(() => {
Expand All @@ -85,7 +93,12 @@ export function UserProfilePlans() {
setCurrentTab('Outstanding');
}
if (haveSeenDailyPlanSuggestionModal == new Date().toISOString().split('T')[0]) {
window.localStorage.setItem(DAILY_PLAN_SUGGESTION_MODAL_DATE, new Date().toISOString().split('T')[0]);
if (!requirePlan || (requirePlan && hasPlan)) {
window.localStorage.setItem(
DAILY_PLAN_SUGGESTION_MODAL_DATE,
new Date().toISOString().split('T')[0]
);
}
}
}

Expand Down Expand Up @@ -207,6 +220,9 @@ function AllPlans({ profile, currentTab = 'All Tasks' }: { profile: any; current
const [popupOpen, setPopupOpen] = useState(false);
const [currentDeleteIndex, setCurrentDeleteIndex] = useState(0);
const { date } = useDateRange(currentTab);
const { activeTeam } = useTeamTasks();
const requirePlan = useMemo(() => activeTeam?.requirePlanToTrack, [activeTeam?.requirePlanToTrack]);
const t = useTranslations();

if (currentTab === 'Today Tasks') {
filteredPlans.current = todayPlan;
Expand Down Expand Up @@ -338,29 +354,36 @@ function AllPlans({ profile, currentTab = 'All Tasks' }: { profile: any; current
variant="outline"
className="px-4 py-2 text-sm font-medium text-red-600 border border-red-600 rounded-md bg-light--theme-light dark:!bg-dark--theme-light"
>
Delete this plan
{t('common.plan.DELETE_THIS_PLAN')}
</Button>
}
>
{/*button confirm*/}
<Button
disabled={deleteDailyPlanLoading}
onClick={() => deleteDailyPlan(plan.id ?? '')}
onClick={() => {
if (requirePlan) {
localStorage.removeItem(
DAILY_PLAN_SUGGESTION_MODAL_DATE
);
}
deleteDailyPlan(plan.id ?? '');
}}
variant="destructive"
className="flex items-center justify-center px-4 py-2 text-sm font-medium text-white bg-red-600 rounded-md hover:bg-red-700 disabled:bg-red-400"
>
{deleteDailyPlanLoading && (
<ReloadIcon className="w-4 h-4 mr-2 animate-spin" />
)}
Delete
{t('common.DELETE')}
</Button>
{/*button cancel*/}
<Button
onClick={() => setPopupOpen(false)}
variant="outline"
className="px-4 py-2 text-sm font-medium text-red-600 border border-red-600 rounded-md bg-light--theme-light dark:!bg-dark--theme-light"
>
Cancel
{t('common.CANCEL')}
</Button>
</AlertPopup>
</div>
Expand Down
3 changes: 2 additions & 1 deletion apps/web/locales/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@
"EDIT_PLAN": "تعديل الخطة",
"TRACKED_TIME": "الوقت المتعقب",
"SEE_PLANS": "عرض الخطط",
"ADD_PLAN": "إضافة خطة"
"ADD_PLAN": "إضافة خطة",
"DELETE_THIS_PLAN": "احذف هذه الخطة"
},
"timesheets": {
"SINGULAR": "ورقة الحضور",
Expand Down
3 changes: 2 additions & 1 deletion apps/web/locales/bg.json
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@
"EDIT_PLAN": "Редактиране на план",
"TRACKED_TIME": "Проследено време",
"SEE_PLANS": "Виж планове",
"ADD_PLAN": "Добави план"
"ADD_PLAN": "Добави план",
"DELETE_THIS_PLAN": "Изтрийте този план"
},
"timesheets": {
"SINGULAR": "Работен лист",
Expand Down
3 changes: 2 additions & 1 deletion apps/web/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@
"EDIT_PLAN": "Plan bearbeiten",
"TRACKED_TIME": "Verfolgte Zeit",
"SEE_PLANS": "Pläne anzeigen",
"ADD_PLAN": "Plan hinzufügen"
"ADD_PLAN": "Plan hinzufügen",
"DELETE_THIS_PLAN": "Diesen Plan löschen"
},
"timesheets": {
"SINGULAR": "Stundenzettel",
Expand Down
3 changes: 2 additions & 1 deletion apps/web/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@
"EDIT_PLAN": "Edit Plan",
"TRACKED_TIME": "Tracked time",
"SEE_PLANS": "See plans",
"ADD_PLAN": "Add Plan"
"ADD_PLAN": "Add Plan",
"DELETE_THIS_PLAN": "Delete this plan"
},
"timesheets": {
"SINGULAR": "Timesheet",
Expand Down
3 changes: 2 additions & 1 deletion apps/web/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@
"ADD_PLAN": "Agregar Plan",
"TRACKED_TIME": "Tiempo registrado",
"SEE_PLANS": "Ver planes",
"FOR_TOMORROW": "Plan de mañana"
"FOR_TOMORROW": "Plan de mañana",
"DELETE_THIS_PLAN": "Eliminar este plan"
},
"timesheets": {
"SINGULAR": "Hoja de horas",
Expand Down
3 changes: 2 additions & 1 deletion apps/web/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@
"EDIT_PLAN": "Modifier le plan",
"TRACKED_TIME": "Temps suivi",
"SEE_PLANS": "Voir les plans",
"ADD_PLAN": "Ajouter un plan"
"ADD_PLAN": "Ajouter un plan",
"DELETE_THIS_PLAN": "Supprimer ce plan"
},
"timesheets": {
"SINGULAR": "Feuille de temps",
Expand Down
3 changes: 2 additions & 1 deletion apps/web/locales/he.json
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@
"EDIT_PLAN": "ערוך תוכנית",
"TRACKED_TIME": "זמן מעקב",
"SEE_PLANS": "ראה תוכניות",
"ADD_PLAN": "הוסף תוכנית"
"ADD_PLAN": "הוסף תוכנית",
"DELETE_THIS_PLAN": "מחק את התוכנית הזו"
},
"timesheets": {
"SINGULAR": "דוח שעות",
Expand Down
Loading

0 comments on commit d517bf1

Please sign in to comment.