From 0df61a2701dba1c3274cb4c43fbae2b277b296d6 Mon Sep 17 00:00:00 2001 From: Patrick Fic <> Date: Mon, 10 Aug 2020 11:59:12 -0700 Subject: [PATCH] Fixed up scheduling logic using UTC dates instead of local dates. Updated scheduling header. Fixed month view not showing. BOD-179 --- .vscode/launch.json | 17 ++++---- .../chat-message-list.component.jsx | 21 ++++----- ...production-board-kanban-card.component.jsx | 2 +- .../production-board-kanban.container.jsx | 6 +-- .../production-list-table.container.jsx | 6 +-- .../schedule-block-day.component.jsx | 8 +--- .../schedule-calendar-header.component.js | 43 +++++++++++-------- .../schedule-calendar.styles.scss | 8 ++++ .../scoreboard-last-days.component.jsx | 4 +- client/src/graphql/jobs.queries.js | 2 +- .../redux/application/application.sagas.js | 23 +++++----- server/scheduling/scheduling-job.js | 8 ++-- 12 files changed, 75 insertions(+), 73 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 857567401..d210fc9d2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,19 +1,20 @@ { "version": "0.2.0", "configurations": [ + { + "name": "Attach to Chrome", + "port": 9222, + "request": "attach", + "type": "pwa-chrome", + "webRoot": "${workspaceFolder}/client/src" + }, + { "name": "Chrome", "type": "chrome", "request": "launch", "url": "http://localhost:3000", - "webRoot": "${workspaceRoot}/src" - }, - { - "name": "Yarn Dev Server", - "type": "node", - "request": "launch", - "runtimeExecutable": "yarn", - "runtimeArgs": ["dev"] + "webRoot": "${workspaceRoot}/client/src" } ] } diff --git a/client/src/components/chat-messages-list/chat-message-list.component.jsx b/client/src/components/chat-messages-list/chat-message-list.component.jsx index 2f08657fa..c46daaf4e 100644 --- a/client/src/components/chat-messages-list/chat-message-list.component.jsx +++ b/client/src/components/chat-messages-list/chat-message-list.component.jsx @@ -1,6 +1,6 @@ import Icon from "@ant-design/icons"; import React, { useEffect, useRef } from "react"; -import { FaCheck, FaCheckDouble } from "react-icons/fa"; +import { MdDone, MdDoneAll } from "react-icons/md"; import { AutoSizer, CellMeasurer, @@ -38,8 +38,9 @@ export default function ChatMessageListComponent({ messages }) { style={style} className={`${ messages[index].isoutbound ? "mine messages" : "yours messages" - }`}> -
+ }`} + > +
{MessageRender(messages[index])} {StatusRender(messages[index].status)}
@@ -50,7 +51,7 @@ export default function ChatMessageListComponent({ messages }) { }; return ( -
+
{({ height, width }) => ( { if (message.image) { return ( - - Received + + Received ); } else { @@ -89,9 +86,9 @@ const MessageRender = (message) => { const StatusRender = (status) => { switch (status) { case "sent": - return ; + return ; case "delivered": - return ; + return ; default: return null; } diff --git a/client/src/components/production-board-kanban-card/production-board-kanban-card.component.jsx b/client/src/components/production-board-kanban-card/production-board-kanban-card.component.jsx index 6d1cc2258..20965eaf3 100644 --- a/client/src/components/production-board-kanban-card/production-board-kanban-card.component.jsx +++ b/client/src/components/production-board-kanban-card/production-board-kanban-card.component.jsx @@ -36,7 +36,7 @@ export default function ProductionBoardCard(card) {
{`B: ${card.labhrs.aggregate.sum.mod_lb_hrs || "?"}`}
-
{`R: ${card.labhrs.aggregate.sum.mod_lb_hrs || "?"}`}
+
{`R: ${card.larhrs.aggregate.sum.mod_lb_hrs || "?"}`}
{`B: ${ diff --git a/client/src/components/production-board-kanban/production-board-kanban.container.jsx b/client/src/components/production-board-kanban/production-board-kanban.container.jsx index 55950c5bf..252a0d67c 100644 --- a/client/src/components/production-board-kanban/production-board-kanban.container.jsx +++ b/client/src/components/production-board-kanban/production-board-kanban.container.jsx @@ -12,9 +12,9 @@ const mapStateToProps = createStructuredSelector({ export function ProductionBoardKanbanContainer({ bodyshop }) { const { loading, data } = useSubscription(SUBSCRIPTION_JOBS_IN_PRODUCTION, { - variables: { - statusList: bodyshop.md_ro_statuses.production_statuses || [], - }, + // variables: { + // statusList: bodyshop.md_ro_statuses.production_statuses || [], + // }, }); return ( diff --git a/client/src/components/production-list-table/production-list-table.container.jsx b/client/src/components/production-list-table/production-list-table.container.jsx index 4b03ace3f..9b5e0cec0 100644 --- a/client/src/components/production-list-table/production-list-table.container.jsx +++ b/client/src/components/production-list-table/production-list-table.container.jsx @@ -15,9 +15,9 @@ export default connect(mapStateToProps, null)(ProductionListTableContainer); export function ProductionListTableContainer({ bodyshop }) { const { loading, data } = useSubscription(SUBSCRIPTION_JOBS_IN_PRODUCTION, { - variables: { - statusList: bodyshop.md_ro_statuses.production_statuses || [], - }, + // variables: { + // statusList: bodyshop.md_ro_statuses.production_statuses || [], + // }, }); const columnState = useState( diff --git a/client/src/components/schedule-block-day/schedule-block-day.component.jsx b/client/src/components/schedule-block-day/schedule-block-day.component.jsx index 888764f56..f604e2681 100644 --- a/client/src/components/schedule-block-day/schedule-block-day.component.jsx +++ b/client/src/components/schedule-block-day/schedule-block-day.component.jsx @@ -24,10 +24,7 @@ export function ScheduleBlockDay({ date, children, refetch, bodyshop }) { const handleMenu = async (e) => { e.domEvent.stopPropagation(); - if (e.key === "block") { - - const blockAppt = { title: t("appointments.labels.blocked"), block: true, @@ -38,7 +35,6 @@ export function ScheduleBlockDay({ date, children, refetch, bodyshop }) { }; logImEXEvent("dashboard_change_layout"); - const result = await insertBlock({ variables: { app: [blockAppt] }, }); @@ -57,9 +53,7 @@ export function ScheduleBlockDay({ date, children, refetch, bodyshop }) { const menu = ( - {t("appointments.actions.block")} - 2nd menu item - 3rd menu item + {t("appointments.actions.block")} ); 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 index 4218c1885..380300d8a 100644 --- a/client/src/components/schedule-calendar-wrapper/schedule-calendar-header.component.js +++ b/client/src/components/schedule-calendar-wrapper/schedule-calendar-header.component.js @@ -6,8 +6,13 @@ import { 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 { Progress, Statistic } from "antd"; +import { + MdCallReceived, + MdCallMissedOutgoing, + MdFileDownload, + MdFileUpload, +} from "react-icons/md"; import Icon from "@ant-design/icons"; import ScheduleBlockDay from "../schedule-block-day/schedule-block-day.component"; @@ -34,18 +39,24 @@ export function ScheduleCalendarHeaderComponent({ 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)} + - -
- - {(loadData.hoursIn || 0) && loadData.hoursIn.toFixed(2)} - - {(loadData.hoursOut || 0) && loadData.hoursOut.toFixed(2)} -
) : null; @@ -53,11 +64,7 @@ export function ScheduleCalendarHeaderComponent({
{label} - {calculating || JSON.stringify(load) === "{}" ? ( - - ) : ( - LoadComponent - )} + {calculating ? : LoadComponent}
); 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 34e78d4b6..3c6cb4b42 100644 --- a/client/src/components/schedule-calendar-wrapper/schedule-calendar.styles.scss +++ b/client/src/components/schedule-calendar-wrapper/schedule-calendar.styles.scss @@ -12,3 +12,11 @@ .imex-event-block { background-color: rgba(212, 2, 2, 0.6); } + +.rbc-month-view { + height: 125rem; +} + +.rbc-event.rbc-selected { + background-color: slategrey; +} diff --git a/client/src/components/scoreboard-last-days/scoreboard-last-days.component.jsx b/client/src/components/scoreboard-last-days/scoreboard-last-days.component.jsx index 678ba545e..f88b897ef 100644 --- a/client/src/components/scoreboard-last-days/scoreboard-last-days.component.jsx +++ b/client/src/components/scoreboard-last-days/scoreboard-last-days.component.jsx @@ -19,9 +19,7 @@ export function ScoreboardLastDays({ bodyshop, sbEntriesByDate }) { const ArrayOfDate = []; for (var i = lastNumberWorkingDays - 1; i >= 0; i--) { - ArrayOfDate.push( - moment().businessSubtract(i, "day").toISOString().substr(0, 10) - ); + ArrayOfDate.push(moment().businessSubtract(i, "day").format("yyyy-MM-DD")); } return ( diff --git a/client/src/graphql/jobs.queries.js b/client/src/graphql/jobs.queries.js index 4c2cb5add..e4cc44873 100644 --- a/client/src/graphql/jobs.queries.js +++ b/client/src/graphql/jobs.queries.js @@ -52,7 +52,7 @@ export const QUERY_ALL_ACTIVE_JOBS = gql` export const SUBSCRIPTION_JOBS_IN_PRODUCTION = gql` subscription SUBSCRIPTION_JOBS_IN_PRODUCTION($statusList: [String!]!) { - jobs(where: { status: { _in: $statusList } }) { + jobs(where: { inproduction: { _eq: true } }) { id status ro_number diff --git a/client/src/redux/application/application.sagas.js b/client/src/redux/application/application.sagas.js index d48ea9d69..f70af1473 100644 --- a/client/src/redux/application/application.sagas.js +++ b/client/src/redux/application/application.sagas.js @@ -35,7 +35,7 @@ export function* calculateScheduleLoad({ payload: end }) { const { arrJobs, compJobs } = result.data; arrJobs.forEach((item) => { - const itemDate = moment(item.scheduled_in).toISOString().substr(0, 10); + const itemDate = moment(item.scheduled_in).format("yyyy-MM-DD"); if (!!load[itemDate]) { load[itemDate].hoursIn = (load[itemDate].hoursIn || 0) + @@ -44,7 +44,7 @@ export function* calculateScheduleLoad({ payload: end }) { load[itemDate].jobsIn.push(item); } else { load[itemDate] = { - jobsIn: [], + jobsIn: [item], jobsOut: [], hoursIn: item.labhrs.aggregate.sum.mod_lb_hrs + @@ -54,9 +54,7 @@ export function* calculateScheduleLoad({ payload: end }) { }); compJobs.forEach((item) => { - const itemDate = moment(item.scheduled_completion) - .toISOString() - .substr(0, 10); + const itemDate = moment(item.scheduled_completion).format("yyyy-MM-DD"); if (!!load[itemDate]) { load[itemDate].hoursOut = (load[itemDate].hoursOut || 0) + @@ -65,6 +63,7 @@ export function* calculateScheduleLoad({ payload: end }) { load[itemDate].jobsOut.push(item); } else { load[itemDate] = { + jobsOut: [item], hoursOut: item.labhrs.aggregate.sum.mod_lb_hrs + item.larhrs.aggregate.sum.mod_lb_hrs, @@ -75,20 +74,19 @@ export function* calculateScheduleLoad({ payload: end }) { //Propagate the expected load to each day. const range = Math.round(moment.duration(end.diff(today)).asDays()); for (var day = 0; day < range; day++) { - const current = moment(today) - .add(day, "days") - .toISOString() - .substr(0, 10); + const current = moment(today).add(day, "days").format("yyyy-MM-DD"); const prev = moment(today) .add(day - 1, "days") - .toISOString() - .substr(0, 10); + .format("yyyy-MM-DD"); if (!!!load[current]) { load[current] = {}; } if (day === 0) { //Starting on day 1. The load is current. - load[current].expectedLoad = load.productionHoursTotal; + load[current].expectedLoad = + load.productionHoursTotal + + (load[current].hoursIn || 0) - + (load[current].hoursOut || 0); } else { load[current].expectedLoad = load[prev].expectedLoad + @@ -96,7 +94,6 @@ export function* calculateScheduleLoad({ payload: end }) { (load[current].hoursOut || 0); } } - yield put(scheduleLoadSuccess(load)); } catch (error) { //console.log("Error in sendEmailFailure saga.", error.message); diff --git a/server/scheduling/scheduling-job.js b/server/scheduling/scheduling-job.js index 9a43effce..81554839a 100644 --- a/server/scheduling/scheduling-job.js +++ b/server/scheduling/scheduling-job.js @@ -53,7 +53,7 @@ exports.job = async (req, res) => { //Initialize the bucket matrix for (i = 0; i < totalMatrixDays; i++) { - const theDate = moment().add(i, "days").toISOString().substr(0, 10); + const theDate = moment().add(i, "days").format("yyyy-MM-DD"); //Only need to create a matrix for jobs of the same bucket. bucketMatrix[theDate] = { in: 0, out: 0 }; @@ -76,7 +76,7 @@ exports.job = async (req, res) => { )[0]; if (appointmentBucket.id === JobBucket.id) { //Theyre the same classification. Add it to the matrix. - const appDate = moment(appointment.start).toISOString().substr(0, 10); + const appDate = moment(appointment.start).format("yyyy-MM-DD"); bucketMatrix[appDate] = { ...bucketMatrix[appDate], in: bucketMatrix[appDate].in + 1, @@ -85,7 +85,7 @@ exports.job = async (req, res) => { }); //Populate the jobs that are leaving today. - const todayIsoString = moment().toISOString().substr(0, 10); + const todayIsoString = moment().format("yyyy-MM-DD"); productionview.forEach((pjob) => { const jobHrs = pjob.larhrs + pjob.labhrs; //Is the job in the same bucket? @@ -100,7 +100,7 @@ exports.job = async (req, res) => { let dateToUse; dateToUse = compDate.isValid() ? moment().diff(compDate, "days") <= 0 - ? compDate.toISOString().substr(0, 10) + ? compDate.format("yyyy-MM-DD") : todayIsoString : todayIsoString;