From 6d6b7c2b92f0e92df3f09e2782408f19dddfb301 Mon Sep 17 00:00:00 2001 From: Sigrid Elnan <55406589+sigridge@users.noreply.github.com> Date: Wed, 24 Jul 2024 13:57:24 +0200 Subject: [PATCH] Feat: Base step on workhours pr day for organisation (#504) --- .../app/[organisation]/kunder/[customer]/page.tsx | 10 +++++++++- .../[organisation]/prosjekt/[project]/page.tsx | 6 +++++- .../components/CostumerTable/CustomerTable.tsx | 3 +++ .../components/CostumerTable/EngagementRow.tsx | 3 +++ .../src/components/Staffing/ConsultantRow.tsx | 2 ++ .../components/Staffing/DetailedBookingRows.tsx | 15 +++++++++++---- .../AddEngagementHoursRow.tsx | 3 +++ .../DetailedEngagementModalCell.tsx | 10 +++++++--- .../EditEngagementHour.tsx | 4 ++++ .../EditEngagementHoursModal.tsx | 4 ++++ .../EditEngagementHoursRow.tsx | 13 ++++++++++--- .../components/Staffing/NewDetailedBookingRow.tsx | 15 +++++++++++---- 12 files changed, 72 insertions(+), 16 deletions(-) diff --git a/frontend/src/app/[organisation]/kunder/[customer]/page.tsx b/frontend/src/app/[organisation]/kunder/[customer]/page.tsx index 61be0609..bbdff74c 100644 --- a/frontend/src/app/[organisation]/kunder/[customer]/page.tsx +++ b/frontend/src/app/[organisation]/kunder/[customer]/page.tsx @@ -6,6 +6,7 @@ import CustomerSidebar from "@/components/CostumerTable/CustomerSidebar"; import CustomerTable from "@/components/CostumerTable/CustomerTable"; import { fetchWithToken } from "@/data/apiCallsWithToken"; import { ConsultantFilterProvider } from "@/hooks/ConsultantFilterProvider"; +import { fetchWorkHoursPerWeek } from "@/hooks/fetchWorkHoursPerDay"; import { Metadata } from "next"; export const metadata: Metadata = { @@ -27,6 +28,9 @@ export default async function Kunde({ `organisations/${params.organisation}/departments`, )) ?? []; + const numWorkHours = + (await fetchWorkHoursPerWeek(params.organisation)) ?? 37.5; + return ( - + )} diff --git a/frontend/src/app/[organisation]/prosjekt/[project]/page.tsx b/frontend/src/app/[organisation]/prosjekt/[project]/page.tsx index 9ab21266..76203365 100644 --- a/frontend/src/app/[organisation]/prosjekt/[project]/page.tsx +++ b/frontend/src/app/[organisation]/prosjekt/[project]/page.tsx @@ -7,6 +7,7 @@ import { ProjectWithCustomerModel } from "@/api-types"; import Sidebar from "./Sidebar"; import { ConsultantFilterProvider } from "@/hooks/ConsultantFilterProvider"; import { parseYearWeekFromUrlString } from "@/data/urlUtils"; +import { fetchWorkHoursPerWeek } from "@/hooks/fetchWorkHoursPerDay"; export default async function Project({ params, @@ -25,6 +26,9 @@ export default async function Project({ ); const weekSpan = searchParams.weekSpan || undefined; + const numWorkHours = + (await fetchWorkHoursPerWeek(params.organisation)) ?? 37.5; + const consultants = (await fetchEmployeesWithImageAndToken( `${params.organisation}/staffings${ @@ -49,7 +53,7 @@ export default async function Project({

{project.customerName}

- + ); diff --git a/frontend/src/components/CostumerTable/CustomerTable.tsx b/frontend/src/components/CostumerTable/CustomerTable.tsx index e9fda6b1..78b1dcd5 100644 --- a/frontend/src/components/CostumerTable/CustomerTable.tsx +++ b/frontend/src/components/CostumerTable/CustomerTable.tsx @@ -12,9 +12,11 @@ import { WeekSpanTableHead } from "../Staffing/WeekTableHead"; export default function CustomerTable({ customer, orgUrl, + numWorkHours, }: { customer: CustomersWithProjectsReadModel; orgUrl: string; + numWorkHours: number; }) { const { selectedWeek, @@ -111,6 +113,7 @@ export default function CustomerTable({ selectedWeek={selectedWeek} selectedWeekSpan={selectedWeekSpan} weekList={weekList} + numWorkHours={numWorkHours} /> ))} diff --git a/frontend/src/components/CostumerTable/EngagementRow.tsx b/frontend/src/components/CostumerTable/EngagementRow.tsx index c7ced0e9..788f64bd 100644 --- a/frontend/src/components/CostumerTable/EngagementRow.tsx +++ b/frontend/src/components/CostumerTable/EngagementRow.tsx @@ -23,12 +23,14 @@ export default function EngagementRows({ selectedWeek, selectedWeekSpan, weekList, + numWorkHours, }: { engagement: EngagementReadModel; orgUrl: string; selectedWeek: Week; selectedWeekSpan: number; weekList: DateTime[]; + numWorkHours: number; }) { const [isListElementVisible, setIsListElementVisible] = useState(false); const [isRowHovered, setIsRowHovered] = useState(false); @@ -148,6 +150,7 @@ export default function EngagementRows({ consultants={selectedConsultants} setConsultants={setSelectedConsultants} withBorder={true} + numWorkHours={numWorkHours} /> ))} diff --git a/frontend/src/components/Staffing/ConsultantRow.tsx b/frontend/src/components/Staffing/ConsultantRow.tsx index b476ff49..54001e6e 100644 --- a/frontend/src/components/Staffing/ConsultantRow.tsx +++ b/frontend/src/components/Staffing/ConsultantRow.tsx @@ -212,6 +212,7 @@ export default function ConsultantRows({ modalRef={changeEngagementModalRef} project={selectedProject} onClose={onCloseEngagementModal} + numWorkHours={numWorkHours} /> )} @@ -240,6 +241,7 @@ export default function ConsultantRows({ consultant={currentConsultant} detailedBooking={db} openEngagementAndSetID={openEngagementAndSetID} + numWorkHours={numWorkHours} /> ))} {isListElementVisible && addNewRow && ( diff --git a/frontend/src/components/Staffing/DetailedBookingRows.tsx b/frontend/src/components/Staffing/DetailedBookingRows.tsx index e7fd8197..c8fad65d 100644 --- a/frontend/src/components/Staffing/DetailedBookingRows.tsx +++ b/frontend/src/components/Staffing/DetailedBookingRows.tsx @@ -54,10 +54,12 @@ export function DetailedBookingRows(props: { consultant: ConsultantReadModel; detailedBooking: DetailedBooking; openEngagementAndSetID: (id: number) => void; + numWorkHours: number; }) { const { setConsultants } = useContext(FilteredContext); - const { consultant, detailedBooking, openEngagementAndSetID } = props; + const { consultant, detailedBooking, openEngagementAndSetID, numWorkHours } = + props; const [hourDragValue, setHourDragValue] = useState( undefined, ); @@ -178,6 +180,7 @@ export function DetailedBookingRows(props: { startDragWeek={startDragWeek} setStartDragWeek={setStartDragWeek} setCurrentDragWeek={setCurrentDragWeek} + numWorkHours={numWorkHours} /> ))} @@ -226,6 +229,7 @@ function DetailedBookingCell({ startDragWeek, setStartDragWeek, setCurrentDragWeek, + numWorkHours, }: { detailedBooking: DetailedBooking; detailedBookingHours: WeeklyHours; @@ -236,6 +240,7 @@ function DetailedBookingCell({ setHourDragValue: React.Dispatch>; setStartDragWeek: React.Dispatch>; setCurrentDragWeek: React.Dispatch>; + numWorkHours: number; }) { const { setConsultants } = useContext(FilteredContext); const [hours, setHours] = useState(detailedBookingHours.hours); @@ -248,6 +253,8 @@ function DetailedBookingCell({ const organisationName = usePathname().split("/")[1]; const numWeeks = detailedBooking.hours.length; + const workHoursPerDay = numWorkHours / 5; + function updateSingularHours() { setIsDisabledHotkeys(false); if (oldHours != hours && hourDragValue == undefined) { @@ -343,7 +350,7 @@ function DetailedBookingCell({ numWeeks <= 12 && "lg:flex" } `} onClick={() => { - setHours(Math.max(hours - 7.5, 0)); + setHours(Math.max(hours - workHoursPerDay, 0)); }} > { - setHours(hours + 7.5); + setHours(hours + workHoursPerDay); }} > diff --git a/frontend/src/components/Staffing/EditEngagementHourModal/AddEngagementHoursRow.tsx b/frontend/src/components/Staffing/EditEngagementHourModal/AddEngagementHoursRow.tsx index 98c5e38d..7965901e 100644 --- a/frontend/src/components/Staffing/EditEngagementHourModal/AddEngagementHoursRow.tsx +++ b/frontend/src/components/Staffing/EditEngagementHourModal/AddEngagementHoursRow.tsx @@ -11,11 +11,13 @@ export function AddEngagementHoursRow({ weekList, project, consultantWWeekHours, + numWorkHours, }: { consultant: ConsultantReadModel; weekList: DateTime[]; project?: ProjectWithCustomerModel; consultantWWeekHours?: ConsultantWithWeekHours; + numWorkHours: number; }) { const [hourDragValue, setHourDragValue] = useState( undefined, @@ -97,6 +99,7 @@ export function AddEngagementHoursRow({ )?.hours || 0 } updateHours={updateHours} + numWorkHours={numWorkHours} /> ))} diff --git a/frontend/src/components/Staffing/EditEngagementHourModal/DetailedEngagementModalCell.tsx b/frontend/src/components/Staffing/EditEngagementHourModal/DetailedEngagementModalCell.tsx index 9ec9df8f..d59158ca 100644 --- a/frontend/src/components/Staffing/EditEngagementHourModal/DetailedEngagementModalCell.tsx +++ b/frontend/src/components/Staffing/EditEngagementHourModal/DetailedEngagementModalCell.tsx @@ -25,6 +25,7 @@ export function DetailedEngagementModalCell({ firstDayInWeek, initHours, updateHours, + numWorkHours, }: { project?: ProjectWithCustomerModel; consultant: ConsultantReadModel; @@ -38,6 +39,7 @@ export function DetailedEngagementModalCell({ firstDayInWeek: DateTime; initHours: number; updateHours: (res: ConsultantReadModel | undefined) => void; + numWorkHours: number; }) { const [hours, setHours] = useState(initHours); const [isChangingHours, setIsChangingHours] = useState(false); @@ -47,6 +49,8 @@ export function DetailedEngagementModalCell({ const inputRef = useRef(null); const organisationName = usePathname().split("/")[1]; + const workHoursPerDay = numWorkHours / 5; + function updateSingularHours() { if (oldHours != hours && hourDragValue == undefined) { setOldHours(hours); @@ -137,7 +141,7 @@ export function DetailedEngagementModalCell({ numWeeks <= 12 && "lg:flex" } `} onClick={() => { - setHours(Math.max(hours - 7.5, 0)); + setHours(Math.max(hours - workHoursPerDay, 0)); }} > @@ -190,7 +194,7 @@ export function DetailedEngagementModalCell({ numWeeks <= 8 && "md:flex" } ${numWeeks <= 12 && "lg:flex"} `} onClick={() => { - setHours(hours + 7.5); + setHours(hours + workHoursPerDay); }} > diff --git a/frontend/src/components/Staffing/EditEngagementHourModal/EditEngagementHour.tsx b/frontend/src/components/Staffing/EditEngagementHourModal/EditEngagementHour.tsx index afa1ec18..1792ef23 100644 --- a/frontend/src/components/Staffing/EditEngagementHourModal/EditEngagementHour.tsx +++ b/frontend/src/components/Staffing/EditEngagementHourModal/EditEngagementHour.tsx @@ -23,8 +23,10 @@ import ChangeEngagementState from "@/components/ChangeEngagementState"; export function EditEngagementHour({ project, + numWorkHours, }: { project?: ProjectWithCustomerModel; + numWorkHours: number; }) { const { selectedWeek, @@ -164,6 +166,7 @@ export function EditEngagementHour({ } consultants={selectedConsultants} setConsultants={setSelectedConsultants} + numWorkHours={numWorkHours} /> ))} @@ -182,6 +185,7 @@ export function EditEngagementHour({ weekList={weekList} project={chosenProject} consultantWWeekHours={consultant} + numWorkHours={numWorkHours} /> ))} diff --git a/frontend/src/components/Staffing/EditEngagementHourModal/EditEngagementHoursModal.tsx b/frontend/src/components/Staffing/EditEngagementHourModal/EditEngagementHoursModal.tsx index 14e4d83e..d9fb7699 100644 --- a/frontend/src/components/Staffing/EditEngagementHourModal/EditEngagementHoursModal.tsx +++ b/frontend/src/components/Staffing/EditEngagementHourModal/EditEngagementHoursModal.tsx @@ -22,10 +22,12 @@ export function EditEngagementHourModal({ modalRef, project, onClose, + numWorkHours, }: { modalRef: RefObject; project?: ProjectWithCustomerModel; onClose: () => void; + numWorkHours: number; }) { const { selectedWeek, @@ -164,6 +166,7 @@ export function EditEngagementHourModal({ } consultants={selectedConsultants} setConsultants={setSelectedConsultants} + numWorkHours={numWorkHours} /> ))} @@ -185,6 +188,7 @@ export function EditEngagementHourModal({ weekList={weekList} project={chosenProject} consultantWWeekHours={consultant} + numWorkHours={numWorkHours} /> ))} diff --git a/frontend/src/components/Staffing/EditEngagementHourModal/EditEngagementHoursRow.tsx b/frontend/src/components/Staffing/EditEngagementHourModal/EditEngagementHoursRow.tsx index 4ddda31d..35ecb8f9 100644 --- a/frontend/src/components/Staffing/EditEngagementHourModal/EditEngagementHoursRow.tsx +++ b/frontend/src/components/Staffing/EditEngagementHourModal/EditEngagementHoursRow.tsx @@ -20,12 +20,14 @@ export function EditEngagementHoursRow({ consultants, setConsultants, withBorder = false, + numWorkHours, }: { consultant: ConsultantReadModel; detailedBooking?: DetailedBooking; consultants: ConsultantReadModel[]; setConsultants: React.Dispatch>; withBorder?: boolean; + numWorkHours: number; }) { const [hourDragValue, setHourDragValue] = useState( undefined, @@ -71,6 +73,7 @@ export function EditEngagementHoursRow({ setCurrentDragWeek={setCurrentDragWeek} setConsultants={setConsultants} consultants={consultants} + numWorkHours={numWorkHours} /> ))} @@ -91,6 +94,7 @@ function EditBookingCell({ setCurrentDragWeek, setConsultants, consultants, + numWorkHours, }: { detailedBooking: DetailedBooking; detailedBookingHours: WeeklyHours; @@ -103,6 +107,7 @@ function EditBookingCell({ setCurrentDragWeek: React.Dispatch>; setConsultants: React.Dispatch>; consultants: ConsultantReadModel[]; + numWorkHours: number; }) { const [hours, setHours] = useState(detailedBookingHours.hours); const [isChangingHours, setIsChangingHours] = useState(false); @@ -113,6 +118,8 @@ function EditBookingCell({ const organisationName = usePathname().split("/")[1]; const numWeeks = detailedBooking.hours.length; + const workHoursPerDay = numWorkHours / 5; + function updateSingularHours() { if (oldHours != hours && hourDragValue == undefined) { setDetailedBookingHours({ @@ -206,7 +213,7 @@ function EditBookingCell({ numWeeks <= 12 && "lg:flex" } `} onClick={() => { - setHours(Math.max(hours - 7.5, 0)); + setHours(Math.max(hours - workHoursPerDay, 0)); }} > { - setHours(hours + 7.5); + setHours(hours + workHoursPerDay); }} > diff --git a/frontend/src/components/Staffing/NewDetailedBookingRow.tsx b/frontend/src/components/Staffing/NewDetailedBookingRow.tsx index 538dfb60..a6e798af 100644 --- a/frontend/src/components/Staffing/NewDetailedBookingRow.tsx +++ b/frontend/src/components/Staffing/NewDetailedBookingRow.tsx @@ -53,10 +53,12 @@ export function DetailedBookingRows(props: { consultant: ConsultantReadModel; detailedBooking: DetailedBooking; openEngagementAndSetID: (id: number) => void; + numWorkHours: number; }) { const { setConsultants } = useContext(FilteredContext); - const { consultant, detailedBooking, openEngagementAndSetID } = props; + const { consultant, detailedBooking, openEngagementAndSetID, numWorkHours } = + props; const [hourDragValue, setHourDragValue] = useState( undefined, ); @@ -187,6 +189,7 @@ export function DetailedBookingRows(props: { startDragWeek={startDragWeek} setStartDragWeek={setStartDragWeek} setCurrentDragWeek={setCurrentDragWeek} + numWorkHours={numWorkHours} /> ))} @@ -235,6 +238,7 @@ function DetailedBookingCell({ startDragWeek, setStartDragWeek, setCurrentDragWeek, + numWorkHours, }: { detailedBooking: DetailedBooking; detailedBookingHours: WeeklyHours; @@ -245,6 +249,7 @@ function DetailedBookingCell({ setHourDragValue: React.Dispatch>; setStartDragWeek: React.Dispatch>; setCurrentDragWeek: React.Dispatch>; + numWorkHours: number; }) { const { setConsultants } = useContext(FilteredContext); const [hours, setHours] = useState(detailedBookingHours.hours); @@ -257,6 +262,8 @@ function DetailedBookingCell({ const organisationName = usePathname().split("/")[1]; const numWeeks = detailedBooking.hours.length; + const workHoursPerDay = numWorkHours / 5; + function updateSingularHours() { setIsDisabledHotkeys(false); if (oldHours != hours && hourDragValue == undefined) { @@ -352,7 +359,7 @@ function DetailedBookingCell({ numWeeks <= 12 && "lg:flex" } `} onClick={() => { - setHours(Math.max(hours - 7.5, 0)); + setHours(Math.max(hours - workHoursPerDay, 0)); }} > { - setHours(hours + 7.5); + setHours(hours + workHoursPerDay); }} >