Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release #2933

Merged
merged 7 commits into from
Aug 19, 2024
Merged

Release #2933

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions apps/web/app/[locale]/profile/[memberId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,6 @@ const Profile = React.memo(function ProfilePage({ params }: { params: { memberId
{t('common.MEMBER')} {t('common.NOT_FOUND')}!
</Text>

<Text className=" font-light text-center text-gray-400">
{t('pages.profile.MEMBER_NOT_FOUND_MSG_1')}
</Text>
<Text className=" font-light text-center text-gray-400">
{t('pages.profile.MEMBER_NOT_FOUND_MSG_1')}
</Text>
Expand Down
2 changes: 1 addition & 1 deletion apps/web/components/pages/task/ChildIssueCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export const ChildIssueCard = () => {

{childTasks.length > 0 && (
<div className={clsxm('flex flex-col max-h-80 gap-3', hidden && ['hidden'])}>
{childTasks.map((task) => {
{childTasks?.map((task) => {
return <TaskLinkedIssue key={task.id} task={task} className="dark:bg-[#25272D] py-0" />;
})}
</div>
Expand Down
4 changes: 2 additions & 2 deletions apps/web/components/pages/task/IssueCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const RelatedIssueCard = () => {
<div className="flex items-center justify-end gap-2.5">
<div className="border-r border-r-[#0000001A] flex items-center gap-2.5">
<span onClick={modal.openModal}>
<AddIcon className="h-4 w-4 text-[#B1AEBC] dark:text-white cursor-pointer mr-1.5" />
<AddIcon className="h-4 w-4 text-[#B1AEBC] dark:text-white cursor-pointer mr-1.5" />
</span>
</div>

Expand Down Expand Up @@ -84,7 +84,7 @@ export const RelatedIssueCard = () => {

{linkedTasks.length > 0 && (
<div className={clsxm('flex flex-col max-h-80 gap-3', hidden && ['hidden'])}>
{linkedTasks.map(({ task, issue }) => {
{linkedTasks?.map(({ task, issue }) => {
return (
<TaskLinkedIssue
key={task.id}
Expand Down
24 changes: 12 additions & 12 deletions apps/web/lib/features/manual-time/add-manual-time-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ export function AddManualTimeModal(props: IAddManualTimeModalProps) {
<form onSubmit={handleSubmit} className="text-sm w-[90%] md:w-full flex flex-col justify-between gap-4">
<div className="flex flex-col">
<label className="block text-gray-500 mb-1">
Date<span className="text-[#de5505e1] ml-1">*</span>
{t('manualTime.DATE')}<span className="text-[#de5505e1] ml-1">*</span>
</label>
<DatePicker
buttonVariant={'link'}
Expand All @@ -167,7 +167,7 @@ export function AddManualTimeModal(props: IAddManualTimeModalProps) {
"w-[230px] justify-start text-left font-normal text-black h-10 border border-transparent dark:border-transparent",
!date && "text-muted-foreground"
)}>
{date ? format(date, "PPP") : <span>Pick a date</span>}
{date ? format(date, "PPP") : <span>{t('manualTime.PICK_A_DATE')}</span>}
</Button>
</>
}
Expand Down Expand Up @@ -198,7 +198,7 @@ export function AddManualTimeModal(props: IAddManualTimeModalProps) {
<div className="flex items-center">
<div className=" w-[48%] mr-[4%]">
<label className="block text-gray-500 mb-1">
Start time<span className="text-[#de5505e1] ml-1">*</span>
{t('manualTime.START_TIME')}<span className="text-[#de5505e1] ml-1">*</span>
</label>
<input
type="time"
Expand All @@ -211,7 +211,7 @@ export function AddManualTimeModal(props: IAddManualTimeModalProps) {

<div className=" w-[48%]">
<label className="block text-gray-500 mb-1">
End time<span className="text-[#de5505e1] ml-1">*</span>
{t('manualTime.END_TIME')}<span className="text-[#de5505e1] ml-1">*</span>
</label>

<input
Expand All @@ -225,7 +225,7 @@ export function AddManualTimeModal(props: IAddManualTimeModalProps) {
</div>

<div className=" flex items-center">
<label className="block text-primary mb-1">{`${params === 'AddManuelTime' ? 'Total hours' : 'Added hours'}`}: </label>
<label className="block text-primary mb-1">{`${params === 'AddManuelTime' ? t('timer.TOTAL_HOURS') : t('manualTime.ADDED_HOURS')}`}: </label>
<div className="ml-[10px] p-1 flex items-center font-semibold dark:border-regal-rose pr-3">
<div className="mr-[10px] bg-gradient-to-tl text-[#3826A6] rounded-full ">
<IoTime
Expand All @@ -239,7 +239,7 @@ export function AddManualTimeModal(props: IAddManualTimeModalProps) {

<div className="">
<label className="block text-gray-500 mb-1">
Team<span className="text-[#de5505e1] ml-1">*</span>
{t('manualTime.TEAM')}<span className="text-[#de5505e1] ml-1">*</span>
</label>
<SelectItems
defaultValue={activeTeam!}
Expand All @@ -257,7 +257,7 @@ export function AddManualTimeModal(props: IAddManualTimeModalProps) {

<div className="">
<label className="block text-gray-500 mb-1">
Employee<span className="text-[#de5505e1] ml-1">*</span>
{t('manualTime.EMPLOYEE')}<span className="text-[#de5505e1] ml-1">*</span>
</label>
<SelectItems
items={activeTeam?.members ?? []}
Expand All @@ -270,7 +270,7 @@ export function AddManualTimeModal(props: IAddManualTimeModalProps) {

<div className="">
<label className="block text-gray-500 mb-1">
Task<span className="text-[#de5505e1] ml-1">*</span>
{t('manualTime.TASK')}<span className="text-[#de5505e1] ml-1">*</span>
</label>
<SelectItems
items={manualTimeReasons.map((reason) => t(`manualTime.reasons.${reason}`))}
Expand All @@ -282,7 +282,7 @@ export function AddManualTimeModal(props: IAddManualTimeModalProps) {
/>
</div>
<div className="flex flex-col">
<label className="block text-gray-500 shrink-0">Description (optional)</label>
<label className="block text-gray-500 shrink-0">{t('manualTime.DESCRIPTION')} ({t('manualTime.OPTIONAL')})</label>
<textarea
value={description}
placeholder="What did you worked on..."
Expand All @@ -296,7 +296,7 @@ export function AddManualTimeModal(props: IAddManualTimeModalProps) {

<div className="">
<label className="block text-gray-500 mb-1">
Task<span className="text-[#de5505e1] ml-1">*</span>
{t('manualTime.TASK')}<span className="text-[#de5505e1] ml-1">*</span>
</label>
<SelectItems
defaultValue={activeTeamTask}
Expand All @@ -309,7 +309,7 @@ export function AddManualTimeModal(props: IAddManualTimeModalProps) {
</div>

<div className="flex flex-col">
<label className="block text-gray-500 shrink-0">Description (optional)</label>
<label className="block text-gray-500 shrink-0">{t('manualTime.DESCRIPTION')} ({t('manualTime.OPTIONAL')})</label>
<textarea
value={description}
placeholder="What worked on? "
Expand All @@ -319,7 +319,7 @@ export function AddManualTimeModal(props: IAddManualTimeModalProps) {
</div>

<div className="">
<label className="block text-gray-500 mb-1">Reason (optional)</label>
<label className="block text-gray-500 mb-1">{t('manualTime.REASON')} ({t('manualTime.OPTIONAL')})</label>
<SelectItems
items={manualTimeReasons.map((reason) => t(`manualTime.reasons.${reason}`))}
onValueChange={(reason) => setReason(reason)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { secondsToTime } from '@app/helpers';
import { IDailyPlan } from '@app/interfaces';
import { VerticalSeparator } from 'lib/components';
import { useTranslations } from 'next-intl';

interface ITaskEstimatedCount {
outstandingPlans: any[];
Expand All @@ -9,18 +10,19 @@ export function TaskEstimatedCount({ outstandingPlans }: ITaskEstimatedCount) {
const element = outstandingPlans?.map((plan: IDailyPlan) => plan.tasks?.map((task) => task));
const { timesEstimated, totalTasks } = estimatedTotalTime(element || []);
const { h: hour, m: minute } = secondsToTime(timesEstimated || 0);
const t = useTranslations()

return (
<div className="flex space-x-10">
<div className="flex space-x-2">
<span className="text-slate-600 dark:text-slate-200">Estimated:</span>
<span className="text-slate-600 dark:text-slate-200">{t('dailyPlan.ESTIMATED')} :</span>
<span className="text-slate-900 dark:text-slate-200 font-semibold text-[12px]">
{hour}h{minute}m
</span>
</div>
<VerticalSeparator className="border-slate-400" />
<div className="flex space-x-2">
<span className="text-slate-600 dark:text-slate-200">Total tasks:</span>
<span className="text-slate-600 dark:text-slate-200">{t('dailyPlan.TOTAL_TASK')}:</span>
<span className="text-slate-900 dark:text-slate-200 font-semibold text-[12px]">{totalTasks}</span>
</div>
</div>
Expand Down
49 changes: 4 additions & 45 deletions apps/web/lib/features/team-members-card-view.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
import {
useAuthenticateUser,
useDailyPlan,
useModal,
useOrganizationEmployeeTeams,
useTeamInvitations,
useUserProfilePage
} from '@app/hooks';
import { useAuthenticateUser, useModal, useOrganizationEmployeeTeams, useTeamInvitations } from '@app/hooks';
import { Transition } from '@headlessui/react';
import { InviteFormModal } from './team/invite/invite-form-modal';
import { InvitedCard, InviteUserTeamCard } from './team/invite/user-invite-card';
import { InviteUserTeamSkeleton, UserTeamCard, UserTeamCardSkeleton } from '.';
import { OT_Member } from '@app/interfaces';
import React, { useCallback, useEffect, useState } from 'react';
import { DailyPlanCompareEstimatedModal } from './daily-plan';
import { DAILY_PLAN_ESTIMATE_HOURS_MODAL_DATE } from '@app/constants';
import React, { useCallback, useEffect } from 'react';

interface Props {
teamMembers: OT_Member[];
Expand All @@ -30,14 +21,6 @@ const TeamMembersCardView: React.FC<Props> = ({
}) => {
const { isTeamManager } = useAuthenticateUser();
const { teamInvitations } = useTeamInvitations();
const [isOpen, setIsOpen] = useState(false);
const { todayPlan } = useDailyPlan();
const profile = useUserProfilePage();
const defaultOpenPopup =
typeof window !== 'undefined'
? window.localStorage.getItem(DAILY_PLAN_ESTIMATE_HOURS_MODAL_DATE) || null
: new Date().toISOString().split('T')[0];
const plan = todayPlan.find((plan) => plan.date?.toString()?.startsWith(new Date()?.toISOString().split('T')[0]));

const { updateOrganizationTeamEmployeeOrderOnList } = useOrganizationEmployeeTeams();

Expand All @@ -48,16 +31,6 @@ const TeamMembersCardView: React.FC<Props> = ({

useEffect(() => setMemberOrdereds(members), [members]);

useEffect(() => {
if (plan) {
const currentDateString = new Date().toISOString().split('T')[0];
window.localStorage.setItem(DAILY_PLAN_ESTIMATE_HOURS_MODAL_DATE, currentDateString);
if (defaultOpenPopup !== currentDateString || !defaultOpenPopup) {
setIsOpen(true);
}
}
}, [defaultOpenPopup, plan]);

const handleChangeOrder = useCallback(
(employee: OT_Member, order: number) => {
updateOrganizationTeamEmployeeOrderOnList(employee, order);
Expand All @@ -78,22 +51,8 @@ const TeamMembersCardView: React.FC<Props> = ({

return (
<>
<DailyPlanCompareEstimatedModal
open={isOpen}
closeModal={() =>
setIsOpen((prev) => {
window.localStorage.setItem(
DAILY_PLAN_ESTIMATE_HOURS_MODAL_DATE,
new Date().toISOString().split('T')[0]
);
return !prev;
})
}
todayPlan={todayPlan}
profile={profile}
/>

<ul className="mt-7" ref={profile.loadTaskStatsIObserverRef}>
<ul className="mt-7">

{/* Current authenticated user members */}
<Transition
show={!!currentUser}
Expand Down
6 changes: 4 additions & 2 deletions apps/web/lib/features/team/invite/invite-email-dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { InviteEmailItem, mapTeamMemberItems } from './invite-email-item';
import { clsxm } from '@app/utils';
import { IInviteEmail } from '@app/interfaces';
import { useSyncRef } from '@app/hooks';
import { useTranslations } from 'next-intl';

export const InviteEmailDropdown = ({
emails,
Expand All @@ -18,7 +19,8 @@ export const InviteEmailDropdown = ({
selectedEmail: IInviteEmail | undefined;
error: string;
handleAddNew: (email: string) => void;
}) => {
}) => {
const t = useTranslations()
const items = useMemo(() => mapTeamMemberItems(emails), [emails]);
const $items = useSyncRef(items);

Expand Down Expand Up @@ -48,7 +50,7 @@ export const InviteEmailDropdown = ({
value={emailItem}
onChange={onChangeActive}
items={items}
placeholder={'Team member email address'}
placeholder={t('common.TEAM_MEMBER_EMAIL_ADDRESS')}
error={error}
handleAddNew={handleAddNew}
useHandleKeyUp={true}
Expand Down
17 changes: 16 additions & 1 deletion apps/web/lib/features/team/invite/invite-form-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { IInviteEmail } from '@app/interfaces';
import { AxiosError } from 'axios';
import { isEmail, isNotEmpty } from 'class-validator';
import { BackButton, Button, Card, InputField, Modal, Text } from 'lib/components';
import { useCallback, useEffect, useState } from 'react';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useTranslations } from 'next-intl';
import { InviteEmailDropdown } from './invite-email-dropdown';

Expand All @@ -21,6 +21,8 @@ export function InviteFormModal({ open, closeModal }: { open: boolean; closeModa
const { workingEmployees } = useEmployee();
const [currentOrgEmails, setCurrentOrgEmails] = useState<IInviteEmail[]>([]);
const { activeTeam } = useOrganizationTeams();
const nameInputRef = useRef<HTMLInputElement>(null);


useEffect(() => {
if (activeTeam?.members) {
Expand All @@ -38,9 +40,21 @@ export function InviteFormModal({ open, closeModal }: { open: boolean; closeModa
}, [workingEmployees, workingEmployees.length, activeTeam]);

const handleAddNew = (email: string) => {

if (!email.includes('@')) {
email = `${email}@gmail.com`;
}

const newItem = { title: email, name: '' };
setSelectedEmail(newItem);

setCurrentOrgEmails([...currentOrgEmails, newItem]);
const extractedName = email.split('@')[0];
if (nameInputRef.current) {
nameInputRef.current.value = extractedName;
nameInputRef.current.focus();
nameInputRef.current.select();
}
};

const handleSubmit = useCallback(
Expand Down Expand Up @@ -99,6 +113,7 @@ export function InviteFormModal({ open, closeModal }: { open: boolean; closeModa
/>

<InputField
ref={nameInputRef}
type="text"
name="name"
placeholder={t('form.TEAM_MEMBER_NAME_PLACEHOLDER')}
Expand Down
Loading
Loading