From 0c93488c1f92cc0781bbf9b8f71e94c5415729e0 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Fri, 8 May 2020 17:25:42 -0700 Subject: [PATCH] BOD-84 Load calculates for this week. Bug exists going past current week. --- .../loading-skeleton.component.jsx | 2 +- .../schedule-calendar-header.component.js | 62 ++++++++++++++++++ .../schedule-calendar.styles.scss | 7 +- .../scheduler-calendar-wrapper.component.jsx | 13 +--- .../schedule-calendar.container.jsx | 30 ++------- .../schedule-datecellwrapper.component.jsx | 18 ----- .../redux/application/application.actions.js | 10 +++ .../redux/application/application.reducer.js | 2 +- .../redux/application/application.sagas.js | 65 ++++++++++++++----- 9 files changed, 139 insertions(+), 70 deletions(-) create mode 100644 client/src/components/schedule-calendar-wrapper/schedule-calendar-header.component.js delete mode 100644 client/src/components/schedule-datecellwrapper/schedule-datecellwrapper.component.jsx diff --git a/client/src/components/loading-skeleton/loading-skeleton.component.jsx b/client/src/components/loading-skeleton/loading-skeleton.component.jsx index b4c306d6b..45b7dc535 100644 --- a/client/src/components/loading-skeleton/loading-skeleton.component.jsx +++ b/client/src/components/loading-skeleton/loading-skeleton.component.jsx @@ -4,5 +4,5 @@ import "./loading-skeleton.styles.scss"; import { Skeleton } from "antd"; export default function LoadingSkeleton(props) { - return ; + return ; } diff --git a/client/src/components/schedule-calendar-wrapper/schedule-calendar-header.component.js b/client/src/components/schedule-calendar-wrapper/schedule-calendar-header.component.js new file mode 100644 index 000000000..69a5d6ac5 --- /dev/null +++ b/client/src/components/schedule-calendar-wrapper/schedule-calendar-header.component.js @@ -0,0 +1,62 @@ +import React from "react"; +import { connect } from "react-redux"; +import { createStructuredSelector } from "reselect"; +import { + selectScheduleLoad, + selectScheduleLoadCalculating, +} from "../../redux/application/application.selectors"; +import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component"; +import { Progress } from "antd"; +import { MdCallReceived, MdCallMissedOutgoing } from "react-icons/md"; +import Icon from "@ant-design/icons"; +const ShopTargetHrs = 100; + +const mapStateToProps = createStructuredSelector({ + //currentUser: selectCurrentUser + load: selectScheduleLoad, + calculating: selectScheduleLoadCalculating, +}); + +const mapDispatchToProps = (dispatch) => ({ + //setUserLanguage: language => dispatch(setUserLanguage(language)) +}); + +export function ScheduleCalendarHeaderComponent({ + label, + date, + load, + calculating, + ...otherProps +}) { + const loadData = load[date.toISOString().substr(0, 10)]; + + const LoadComponent = loadData ? ( +
+ + +
+ + {(loadData.hoursIn || 0) && loadData.hoursIn.toFixed(2)} + + {(loadData.hoursOut || 0) && loadData.hoursOut.toFixed(2)} +
+
+ ) : null; + + return ( +
+ {label} + {calculating || JSON.stringify(load) === "{}" ? ( + + ) : ( + LoadComponent + )} +
+ ); +} +export default connect( + mapStateToProps, + mapDispatchToProps +)(ScheduleCalendarHeaderComponent); diff --git a/client/src/components/schedule-calendar-wrapper/schedule-calendar.styles.scss b/client/src/components/schedule-calendar-wrapper/schedule-calendar.styles.scss index 059edf709..699f4fd54 100644 --- a/client/src/components/schedule-calendar-wrapper/schedule-calendar.styles.scss +++ b/client/src/components/schedule-calendar-wrapper/schedule-calendar.styles.scss @@ -1 +1,6 @@ -@import 'react-big-calendar/lib/sass/styles'; +@import "react-big-calendar/lib/sass/styles"; + +.rbc-time-view .rbc-row { + box-sizing: unset !important; + min-height: unset !important; +} diff --git a/client/src/components/schedule-calendar-wrapper/scheduler-calendar-wrapper.component.jsx b/client/src/components/schedule-calendar-wrapper/scheduler-calendar-wrapper.component.jsx index 70b36d7ab..91042b69d 100644 --- a/client/src/components/schedule-calendar-wrapper/scheduler-calendar-wrapper.component.jsx +++ b/client/src/components/schedule-calendar-wrapper/scheduler-calendar-wrapper.component.jsx @@ -1,10 +1,10 @@ -import { Progress } from "antd"; import moment from "moment"; import queryString from "query-string"; import React from "react"; import { Calendar, momentLocalizer } from "react-big-calendar"; import { useHistory, useLocation } from "react-router-dom"; import Event from "../schedule-event/schedule-event.container"; +import HeaderComponent from "./schedule-calendar-header.component"; //import "react-big-calendar/lib/css/react-big-calendar.css"; import "./schedule-calendar.styles.scss"; @@ -37,21 +37,14 @@ export default function ScheduleCalendarWrapperComponent({ history.push({ search: queryString.stringify(search) }); }} step={30} + timeslots={1} showMultiDayTimes localizer={localizer} min={new Date("2020-01-01T06:00:00")} //TODO Read from business settings. max={new Date("2020-01-01T20:00:00")} components={{ event: (e) => Event({ event: e.event, refetch: refetch }), - header: (props) => { - return ( - -
{props.label}
- -
- ); - }, - //dateCellWrapper: DateCellWrapper, + header: HeaderComponent, }} {...otherProps} /> diff --git a/client/src/components/schedule-calendar/schedule-calendar.container.jsx b/client/src/components/schedule-calendar/schedule-calendar.container.jsx index 9750d6ad7..001894888 100644 --- a/client/src/components/schedule-calendar/schedule-calendar.container.jsx +++ b/client/src/components/schedule-calendar/schedule-calendar.container.jsx @@ -31,7 +31,7 @@ export function ScheduleCalendarContainer({ calculateScheduleLoad }) { ); if (loading) return ; - if (error) return ; + if (error) return ; let normalizedData = data.appointments.map((e) => { //Required becuase Hasura returns a string instead of a date object. return Object.assign( @@ -42,29 +42,13 @@ export function ScheduleCalendarContainer({ calculateScheduleLoad }) { ); }); - console.log("ScheduleCalendarContainer -> normalizedData", normalizedData); - normalizedData.push({ - id: 1, - title: "All day event", - allDay: true, - isintake: false, - start: new Date(), - end: new Date(), - }); + calculateScheduleLoad(range.end); + return ( - - - - + ); } export default connect( diff --git a/client/src/components/schedule-datecellwrapper/schedule-datecellwrapper.component.jsx b/client/src/components/schedule-datecellwrapper/schedule-datecellwrapper.component.jsx deleted file mode 100644 index bdc31a4a2..000000000 --- a/client/src/components/schedule-datecellwrapper/schedule-datecellwrapper.component.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from "react"; - -export default function ScheduleDateCellWrapper(dateCellWrapperProps) { - // Show 'click me' text in arbitrary places by using the range prop - - const style = { - display: "flex", - flex: 1, - borderLeft: "1px solid #DDD", - backgroundColor: "#fff", - }; - return ( -
- PLACEHOLDER:DATA - {dateCellWrapperProps.children} -
- ); -} diff --git a/client/src/redux/application/application.actions.js b/client/src/redux/application/application.actions.js index 958abcc77..796206185 100644 --- a/client/src/redux/application/application.actions.js +++ b/client/src/redux/application/application.actions.js @@ -18,3 +18,13 @@ export const calculateScheduleLoad = (rangeEnd) => ({ type: ApplicationActionTypes.CALCULATE_SCHEDULE_LOAD, payload: rangeEnd, }); + +export const scheduleLoadSuccess = (load) => ({ + type: ApplicationActionTypes.CALCULATE_SCHEDULE_LOAD_SUCCESS, + payload: load, +}); + +export const scheduleLoadFailure = (error) => ({ + type: ApplicationActionTypes.CALCULATE_SCHEDULE_LOAD_FAILURE, + payload: error, +}); diff --git a/client/src/redux/application/application.reducer.js b/client/src/redux/application/application.reducer.js index 15753a113..9b9e13ef7 100644 --- a/client/src/redux/application/application.reducer.js +++ b/client/src/redux/application/application.reducer.js @@ -4,7 +4,7 @@ const INITIAL_STATE = { loading: false, breadcrumbs: [], scheduleLoad: { - load: [], + load: {}, calculating: false, error: null, }, diff --git a/client/src/redux/application/application.sagas.js b/client/src/redux/application/application.sagas.js index b11e65448..6b71ca79c 100644 --- a/client/src/redux/application/application.sagas.js +++ b/client/src/redux/application/application.sagas.js @@ -1,7 +1,11 @@ -import { all, takeLatest, call } from "redux-saga/effects"; +import { all, takeLatest, call, put } from "redux-saga/effects"; import ApplicationActionTypes from "./application.types"; import { client } from "../../App/App.container"; import { QUERY_SCHEDULE_LOAD_DATA } from "../../graphql/appointments.queries"; +import { + scheduleLoadFailure, + scheduleLoadSuccess, +} from "./application.actions"; import moment from "moment"; export function* onCalculateScheduleLoad() { @@ -11,6 +15,7 @@ export function* onCalculateScheduleLoad() { ); } export function* calculateScheduleLoad({ payload: end }) { + //REMINDER: Moment.js is not immutable. Today WILL change when adjusted. const today = moment(new Date()).startOf("day"); try { const result = yield client.query({ @@ -21,21 +26,12 @@ export function* calculateScheduleLoad({ payload: end }) { }, }); - const productionHoursTotal = - result.data.productionview_aggregate.aggregate.sum.larhrs + - result.data.productionview_aggregate.aggregate.sum.labhrs; + let load = { + productionHoursTotal: + result.data.productionview_aggregate.aggregate.sum.larhrs + + result.data.productionview_aggregate.aggregate.sum.labhrs, + }; - const range = Math.round(moment.duration(end.diff(today)).asDays()); - let load = {}; - - //Start from today and go until the range. - // for (var day = 0; day < range; day++) { - // let workingDate = today.add(day, "days"); - // console.log( - // "function*calculateScheduleLoad -> workingDate", - // workingDate.toLocaleString() - // ); - // } const { arrJobs, compJobs } = result.data; arrJobs.forEach((item) => { @@ -45,8 +41,11 @@ export function* calculateScheduleLoad({ payload: end }) { (load[itemDate].hoursIn || 0) + item.labhrs.aggregate.sum.mod_lb_hrs + item.larhrs.aggregate.sum.mod_lb_hrs; + load[itemDate].jobsIn.push(item); } else { load[itemDate] = { + jobsIn: [], + jobsOut: [], hoursIn: item.labhrs.aggregate.sum.mod_lb_hrs + item.larhrs.aggregate.sum.mod_lb_hrs, @@ -63,6 +62,7 @@ export function* calculateScheduleLoad({ payload: end }) { (load[itemDate].hoursOut || 0) + item.labhrs.aggregate.sum.mod_lb_hrs + item.larhrs.aggregate.sum.mod_lb_hrs; + load[itemDate].jobsOut.push(item); } else { load[itemDate] = { hoursOut: @@ -72,10 +72,43 @@ export function* calculateScheduleLoad({ payload: end }) { } }); - console.log("load", load); + //Propagate the expected load to each day. + const range = Math.round(moment.duration(end.diff(today)).asDays()); + for (var day = 0; day < range; day++) { + console.log( + "function*calculateScheduleLoad -> today", + today.toISOString() + ); + const current = moment(today) + .add(day, "days") + .toISOString() + .substr(0, 10); + console.log( + "function*calculateScheduleLoad -> today", + today.toISOString() + ); + console.log("function*calculateScheduleLoad -> current", current); + const prev = moment(today) + .add(day - 1, "days") + .toISOString() + .substr(0, 10); + console.log("function*calculateScheduleLoad -> prev", prev); + if (day === 0) { + //Starting on day 1. The load is current. + load[current].expectedLoad = load.productionHoursTotal; + } else { + load[current].expectedLoad = + load[prev].expectedLoad + + (load[current].hoursIn || 0) - + (load[current].hoursOut || 0); + } + } + + yield put(scheduleLoadSuccess(load)); } catch (error) { //console.log("Error in sendEmailFailure saga.", error.message); console.log("error", error); + yield put(scheduleLoadFailure(error)); } }