Skip to content

Commit

Permalink
Merge pull request #288 from goinvo/addMarkersForStartEndDates
Browse files Browse the repository at this point in the history
Add markers for start end dates
  • Loading branch information
HankC138 authored Oct 28, 2024
2 parents bf8d134 + 5abafd6 commit 1442e99
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 16 deletions.
102 changes: 102 additions & 0 deletions app/components/projectAssignment/draggableProjectDates.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
'use client'

import React, { DragEvent, FC } from 'react';
import { useMutation } from "@apollo/client";
import { UPSERT_PROJECT } from "@/app/gqlQueries";
import { useProjectsDataContext } from '@/app/contexts/projectsDataContext';
import { getISODateFromWeek, getWeekNumberAndYear } from '../scrollingCalendar/helpers';
import { PROJECT_DATES_TYPE } from '../scrollingCalendar/constants';

interface DraggableDatesProps {
weekNumberOfTheYear: number;
monthYear: number;
monthLabel: string;
}

const DraggableDates: FC<DraggableDatesProps> = ({
weekNumberOfTheYear,
monthYear,
monthLabel,
}) => {
const { projectList, setProjectList, singleProjectPage } = useProjectsDataContext()
let endDateWeekNumber;
let startDateWeekNumber;

if (singleProjectPage?.endsOn) {
endDateWeekNumber = getWeekNumberAndYear(singleProjectPage?.endsOn)
}
if (singleProjectPage?.startsOn) {
startDateWeekNumber = getWeekNumberAndYear(singleProjectPage?.startsOn)
}
const isEndDateWeek = endDateWeekNumber?.weekNumber === weekNumberOfTheYear && monthYear === endDateWeekNumber?.year
const isStartDateWeek = startDateWeekNumber?.weekNumber === weekNumberOfTheYear && monthYear === startDateWeekNumber?.year

const [upsertProject] = useMutation(UPSERT_PROJECT, {
errorPolicy: "all",
onCompleted({ upsertProject }) {
const { id, endsOn, startsOn } = upsertProject
const updatedProjectList = projectList.map(project =>
project.id === id
? { ...project, endsOn, startsOn }
: project
);
setProjectList(updatedProjectList)
},
});

const handleDragStart = (e: DragEvent<HTMLDivElement>) => {
const type = isStartDateWeek ? PROJECT_DATES_TYPE.STARTS_ON : PROJECT_DATES_TYPE.ENDS_ON
e.dataTransfer.setData('text/plain', JSON.stringify(type));
e.stopPropagation();
e.currentTarget.style.zIndex = '100';
e.currentTarget.style.opacity = '0.5';
};

const handleDrop = async (e: DragEvent<HTMLDivElement>) => {
const typeDate = JSON.parse(e.dataTransfer.getData('text/plain'));
const newTargetDate = getISODateFromWeek(monthYear, weekNumberOfTheYear, Number(monthLabel))
const newDateForComparison = new Date(newTargetDate)
e.preventDefault();
e.currentTarget.style.zIndex = '';
e.currentTarget.style.opacity = '1';
if (typeDate === PROJECT_DATES_TYPE.ENDS_ON && singleProjectPage?.startsOn) {
const startDate = new Date(singleProjectPage.startsOn);
if (startDate >= newDateForComparison) return;

}
if (typeDate === PROJECT_DATES_TYPE.STARTS_ON && singleProjectPage?.endsOn) {
const endDate = new Date(singleProjectPage.endsOn)
if (newDateForComparison >= endDate) return;
}
const variables = {
id: singleProjectPage?.id,
name: singleProjectPage?.name,
[typeDate]: newTargetDate
}
await upsertProject({
variables
});

};

const handleDragEnd = (e: DragEvent<HTMLDivElement>) => {
e.currentTarget.style.zIndex = '';
e.currentTarget.style.opacity = '1';
};

return (
<div
draggable={isStartDateWeek || isEndDateWeek}
onDragStart={handleDragStart}
onDragEnd={handleDragEnd}
onDragOver={(e) => e.preventDefault()}
onDrop={handleDrop}
className={`absolute top-0 left-0 right-0 inset-0 flex flex-col leading-none h-full w-full ${(isStartDateWeek || isEndDateWeek) ? 'cursor-pointer navbar' : ''
} `}
>
<span className='text-contrastGrey text-2xs px-1 pt-1 font-normal'>{isStartDateWeek && 'START' || isEndDateWeek && 'END'}</span>
</div>
);
};

export default DraggableDates;
21 changes: 16 additions & 5 deletions app/components/scrollingCalendar/calendarHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { AssignmentType, MonthsDataType, ProjectType } from '@/app/typeInterface
import { calculateTotalHoursPerWeek, isBeforeWeek, showMonthAndYear, getNextWeeksPerView, getPrevWeeksPerView, currentWeek, currentYear } from './helpers';
import ViewsMenu from '../viewsMenu/viewsMenu';
import EditFormController from './editFormController';
import DraggableDates from '../projectAssignment/draggableProjectDates';

interface ColumnHeaderTitle {
title: string;
Expand All @@ -31,6 +32,7 @@ type CalendarHeaderProps = {
editable?: boolean,
projectInfo?: string,
columnHeaderTitles: ColumnHeaderTitle[],
draggableDates?: boolean
}

const CalendarHeader: React.FC<CalendarHeaderProps> = ({
Expand All @@ -41,7 +43,9 @@ const CalendarHeader: React.FC<CalendarHeaderProps> = ({
userName,
editable = false,
projectInfo,
columnHeaderTitles }) => {
columnHeaderTitles,
draggableDates = false,
}) => {
const [isEditing, setIsEditing] = useState(false);
const { setDateRange, scrollToTodayFunction } = useGeneralDataContext();
const { totalActualHours, totalEstimatedHours, proposedEstimatedHours, maxTotalHours } = calculateTotalHoursPerWeek(assignments as AssignmentType[], months)
Expand Down Expand Up @@ -99,8 +103,15 @@ const CalendarHeader: React.FC<CalendarHeaderProps> = ({
</th>
{months?.map((month) => {
return month.weeks.map((week) => {
return (<th key={`month-${month.monthLabel}-week-${week.weekNumberOfTheYear}`}
className={`sm:block hidden relative px-1 ${currentWeek === week.weekNumberOfTheYear && currentYear === month.year ? 'navbar font-bold' : 'font-normal'}`}>
const isCurrentWeek = currentWeek === week.weekNumberOfTheYear && currentYear === month.year
return (<th
key={`month-${month.monthLabel}-week-${week.weekNumberOfTheYear}`}
className={`sm:block hidden relative px-1 ${isCurrentWeek ? 'navbar font-bold' : 'font-normal'}`}>
{draggableDates && <DraggableDates
weekNumberOfTheYear={week.weekNumberOfTheYear}
monthYear={month.year}
monthLabel={month.monthLabel}
/>}
<ColumnChart
hasActualHoursForWeek={hasActualHoursForWeek(month.year, week.weekNumberOfTheYear)}
height={hasActualHoursForWeek(month.year, week.weekNumberOfTheYear) ? totalActualHours[`${month.year}-${week.weekNumberOfTheYear}`] : totalEstimatedHours[`${month.year}-${week.weekNumberOfTheYear}`]}
Expand Down Expand Up @@ -136,9 +147,9 @@ const CalendarHeader: React.FC<CalendarHeaderProps> = ({
</th>
{months?.map((month) => {
return month.weeks.map((week, index) => {
const isCurrentWeek = currentWeek === week.weekNumberOfTheYear && currentYear === month.year
return (
<th key={`${month.monthLabel}-${index}`} className={`relative py-2 px-1 font-normal text-contrastBlue ${currentWeek === week.weekNumberOfTheYear && currentYear === month.year && 'bg-selectedColumnBg'
}`}>
<th key={`${month.monthLabel}-${index}`} className={`relative py-2 px-1 font-normal text-contrastBlue ${isCurrentWeek ? 'bg-selectedColumnBg' : ''}`}>
<div className={`flex flex-col items-center sm:text-base text-2xl sm:w-[34px] w-[68px] ${currentWeek === week.weekNumberOfTheYear && currentYear === month.year ? 'font-bold' : 'font-normal'}`}>
<span>{`W${week.weekNumberOfTheMonth}`}</span>
<span className={`${week.weekNumberOfTheMonth !== 1 ? 'sm:hidden' : ''}`}>
Expand Down
5 changes: 5 additions & 0 deletions app/components/scrollingCalendar/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,8 @@ export const MONTHS_COUNT: MonthsCount = {

export const ACTUAL_HOURS = "actualHours";
export const ESTIMATED_HOURS = "estimatedHours";

export enum PROJECT_DATES_TYPE {
STARTS_ON = "startsOn",
ENDS_ON = "endsOn",
}
5 changes: 4 additions & 1 deletion app/components/scrollingCalendar/scrollingCalendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ interface ScrollingCalendarProps {
userName?: string;
projectInfo?: string;
editable?: boolean;
draggableDates?: boolean
}

export const ScrollingCalendar = ({
Expand All @@ -31,7 +32,8 @@ export const ScrollingCalendar = ({
avatarUrl,
userName,
projectInfo,
editable
editable,
draggableDates
}: ScrollingCalendarProps) => {
const [months, setMonths] = useState<MonthsDataType[]>([]);
const { dateRange, setDateRange } = useGeneralDataContext();
Expand Down Expand Up @@ -72,6 +74,7 @@ export const ScrollingCalendar = ({
title={title}
projectInfo={projectInfo}
editable={editable}
draggableDates={draggableDates}
/>
<tbody>
{React.Children.map(children, (child) =>
Expand Down
26 changes: 16 additions & 10 deletions app/projects/[projectId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,17 @@ const ProjectPage: React.FC = () => {
const startDate = singleProjectPage?.startsOn ? DateTime.fromISO(singleProjectPage.startsOn) : null;
const endDate = singleProjectPage?.endsOn ? DateTime.fromISO(singleProjectPage.endsOn) : null;

if (!startDate || !endDate) {
if (!startDate && !endDate) {
return 'Start Date - End Date';
}
const formattedStartDate = startDate.toFormat('d.MMM');
const formattedEndDate = endDate.toFormat('d.MMM');
const startYear = startDate.year;
const endYear = endDate.year;
if (startYear === endYear) {
return `${formattedStartDate}-${formattedEndDate}.${endYear}`;
} else {
return `${formattedStartDate}.${startYear}-${formattedEndDate} ${endYear}`;
const formattedStartDate = startDate?.toFormat('d.MMM')
const formattedEndDate = endDate?.toFormat('d.MMM')
const startYear = startDate?.year || ''
const endYear = endDate?.year || ''
if (startDate && startYear && startYear !== endYear) {
return `${formattedStartDate}.${startYear}-${formattedEndDate || 'End Date'} ${endYear}`;
}
return `${formattedStartDate || 'Start Date'}-${formattedEndDate}.${endYear}`;
}

const columnHeaderTitles = [{ title: 'People', showIcon: true, onClick: () => addNewAssignmentRow() }]
Expand All @@ -94,7 +93,14 @@ const ProjectPage: React.FC = () => {
<>
{singleProjectPage && projectList.length ? (
<>
<ScrollingCalendar columnHeaderTitles={columnHeaderTitles} title={singleProjectPage.name} projectInfo={projectInfoSubtitle} assignments={sortedSingleProjectAssignments || []} editable={true}>
<ScrollingCalendar
columnHeaderTitles={columnHeaderTitles}
title={singleProjectPage.name}
projectInfo={projectInfoSubtitle}
assignments={sortedSingleProjectAssignments || []}
editable={true}
draggableDates={true}
>
{sortedSingleProjectAssignments?.map((assignment: AssignmentType, rowIndex) => {
return (
<ProjectAssignmentRow
Expand Down
1 change: 1 addition & 0 deletions tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const config: Config = {
selectedColumnBg: "#dfe0ec",
},
fontSize: {
"2xs": "10px",
tiny: "14px",
huge: "28px",
},
Expand Down

0 comments on commit 1442e99

Please sign in to comment.