BOD-84 Added base calculations for schedule load
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
import moment from "moment";
|
||||
|
||||
export function getRange(dateParam, viewParam) {
|
||||
let start, end;
|
||||
let date = dateParam || new Date();
|
||||
let view = viewParam || "week";
|
||||
// if view is day: from moment(date).startOf('day') to moment(date).endOf('day');
|
||||
if (view === "day") {
|
||||
start = moment(date).startOf("day");
|
||||
end = moment(date).endOf("day");
|
||||
}
|
||||
// if view is week: from moment(date).startOf('isoWeek') to moment(date).endOf('isoWeek');
|
||||
else if (view === "week") {
|
||||
start = moment(date).startOf("week");
|
||||
end = moment(date).endOf("week");
|
||||
}
|
||||
//if view is month: from moment(date).startOf('month').subtract(7, 'days') to moment(date).endOf('month').add(7, 'days'); i do additional 7 days math because you can see adjacent weeks on month view (that is the way how i generate my recurrent events for the Big Calendar, but if you need only start-end of month - just remove that math);
|
||||
else if (view === "month") {
|
||||
start = moment(date).startOf("month").subtract(7, "days");
|
||||
end = moment(date).endOf("month").add(7, "days");
|
||||
}
|
||||
// if view is agenda: from moment(date).startOf('day') to moment(date).endOf('day').add(1, 'month');
|
||||
else if (view === "agenda") {
|
||||
start = moment(date).startOf("day");
|
||||
end = moment(date).endOf("day").add(1, "month");
|
||||
}
|
||||
|
||||
return { start, end };
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
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 DateCellWrapper from "../schedule-datecellwrapper/schedule-datecellwrapper.component";
|
||||
import Event from "../schedule-event/schedule-event.container";
|
||||
//import "react-big-calendar/lib/css/react-big-calendar.css";
|
||||
import "./schedule-calendar.styles.scss";
|
||||
@@ -14,6 +14,7 @@ export default function ScheduleCalendarWrapperComponent({
|
||||
data,
|
||||
refetch,
|
||||
defaultView,
|
||||
setDateRangeCallback,
|
||||
...otherProps
|
||||
}) {
|
||||
const search = queryString.parse(useLocation().search);
|
||||
@@ -22,12 +23,19 @@ export default function ScheduleCalendarWrapperComponent({
|
||||
return (
|
||||
<Calendar
|
||||
events={data}
|
||||
defaultView={defaultView}
|
||||
defaultView={search.view || defaultView || "week"}
|
||||
date={new Date(search.date || Date.now())}
|
||||
onNavigate={(date, view, action) => {
|
||||
search.date = date.toISOString().substr(0, 10);
|
||||
history.push({ search: queryString.stringify(search) });
|
||||
}}
|
||||
onRangeChange={(start, end) => {
|
||||
if (setDateRangeCallback) setDateRangeCallback({ start, end });
|
||||
}}
|
||||
onView={(view) => {
|
||||
search.view = view;
|
||||
history.push({ search: queryString.stringify(search) });
|
||||
}}
|
||||
step={30}
|
||||
showMultiDayTimes
|
||||
localizer={localizer}
|
||||
@@ -35,7 +43,15 @@ export default function ScheduleCalendarWrapperComponent({
|
||||
max={new Date("2020-01-01T20:00:00")}
|
||||
components={{
|
||||
event: (e) => Event({ event: e.event, refetch: refetch }),
|
||||
dateCellWrapper: DateCellWrapper,
|
||||
header: (props) => {
|
||||
return (
|
||||
<span>
|
||||
<div>{props.label}</div>
|
||||
<Progress style={{ flex: "1" }} percent={77} showInfo={false} />
|
||||
</span>
|
||||
);
|
||||
},
|
||||
//dateCellWrapper: DateCellWrapper,
|
||||
}}
|
||||
{...otherProps}
|
||||
/>
|
||||
|
||||
@@ -8,16 +8,15 @@ import { setModalContext } from "../../redux/modals/modals.actions";
|
||||
import ScheduleCalendarWrapperComponent from "../schedule-calendar-wrapper/scheduler-calendar-wrapper.component";
|
||||
import ScheduleModal from "../schedule-job-modal/schedule-job-modal.container";
|
||||
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
setScheduleContext: context =>
|
||||
dispatch(setModalContext({ context: context, modal: "schedule" }))
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
setScheduleContext: (context) =>
|
||||
dispatch(setModalContext({ context: context, modal: "schedule" })),
|
||||
});
|
||||
|
||||
export function ScheduleCalendarComponent({
|
||||
data,
|
||||
refetch,
|
||||
setScheduleContext
|
||||
setScheduleContext,
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -36,8 +35,8 @@ export function ScheduleCalendarComponent({
|
||||
setScheduleContext({
|
||||
actions: { refetch: refetch },
|
||||
context: {
|
||||
jobId: null
|
||||
}
|
||||
jobId: null,
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
@@ -46,11 +45,7 @@ export function ScheduleCalendarComponent({
|
||||
|
||||
<ScheduleModal />
|
||||
|
||||
<ScheduleCalendarWrapperComponent
|
||||
data={data}
|
||||
defaultView="week"
|
||||
refetch={refetch}
|
||||
/>
|
||||
<ScheduleCalendarWrapperComponent data={data} refetch={refetch} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,33 @@
|
||||
import { useQuery } from "@apollo/react-hooks";
|
||||
import queryString from "query-string";
|
||||
import React from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { QUERY_ALL_ACTIVE_APPOINTMENTS } from "../../graphql/appointments.queries";
|
||||
import AlertComponent from "../alert/alert.component";
|
||||
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
|
||||
import { getRange } from "../schedule-calendar-wrapper/schedule-calendar-util";
|
||||
import ScheduleCalendarComponent from "./schedule-calendar.component";
|
||||
import { calculateScheduleLoad } from "../../redux/application/application.actions";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
//currentUser: selectCurrentUser
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
calculateScheduleLoad: (endDate) => dispatch(calculateScheduleLoad(endDate)),
|
||||
});
|
||||
|
||||
export default function ScheduleCalendarContainer() {
|
||||
export function ScheduleCalendarContainer({ calculateScheduleLoad }) {
|
||||
const search = queryString.parse(useLocation().search);
|
||||
|
||||
const { date, view } = search;
|
||||
const range = getRange(date, view);
|
||||
const { loading, error, data, refetch } = useQuery(
|
||||
QUERY_ALL_ACTIVE_APPOINTMENTS
|
||||
QUERY_ALL_ACTIVE_APPOINTMENTS,
|
||||
{
|
||||
variables: { start: range.start.toDate(), end: range.end.toDate() },
|
||||
skip: !!!range.start || !!!range.end,
|
||||
}
|
||||
);
|
||||
|
||||
if (loading) return <LoadingSpinner />;
|
||||
@@ -22,10 +42,32 @@ export default function ScheduleCalendarContainer() {
|
||||
);
|
||||
});
|
||||
|
||||
console.log("ScheduleCalendarContainer -> normalizedData", normalizedData);
|
||||
normalizedData.push({
|
||||
id: 1,
|
||||
title: "All day event",
|
||||
allDay: true,
|
||||
isintake: false,
|
||||
start: new Date(),
|
||||
end: new Date(),
|
||||
});
|
||||
return (
|
||||
<ScheduleCalendarComponent
|
||||
refetch={refetch}
|
||||
data={data ? normalizedData : null}
|
||||
/>
|
||||
<span>
|
||||
<button
|
||||
onClick={() => {
|
||||
calculateScheduleLoad(range.end);
|
||||
}}
|
||||
>
|
||||
Calc Load
|
||||
</button>
|
||||
<ScheduleCalendarComponent
|
||||
refetch={refetch}
|
||||
data={data ? normalizedData : null}
|
||||
/>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(ScheduleCalendarContainer);
|
||||
|
||||
@@ -7,7 +7,7 @@ export default function ScheduleDateCellWrapper(dateCellWrapperProps) {
|
||||
display: "flex",
|
||||
flex: 1,
|
||||
borderLeft: "1px solid #DDD",
|
||||
backgroundColor: "#fff"
|
||||
backgroundColor: "#fff",
|
||||
};
|
||||
return (
|
||||
<div style={style}>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import { Popover, Button } from "antd";
|
||||
import { Popover, Button, Progress } from "antd";
|
||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||
import PhoneFormatter from "../../utils/PhoneFormatter";
|
||||
import { Link } from "react-router-dom";
|
||||
@@ -13,30 +13,30 @@ export default function ScheduleEventComponent({ event, handleCancel }) {
|
||||
<strong>{event.title}</strong>
|
||||
) : (
|
||||
<div>
|
||||
<strong>{`${(event.job && event.job.ownr_fn) || ""} ${(event.job &&
|
||||
event.job.ownr_ln) ||
|
||||
""}`}</strong>
|
||||
<strong>{`${(event.job && event.job.ownr_fn) || ""} ${
|
||||
(event.job && event.job.ownr_ln) || ""
|
||||
}`}</strong>
|
||||
<span style={{ margin: 4 }}>
|
||||
{`${(event.job && event.job.v_model_yr) ||
|
||||
""} ${(event.job && event.job.v_make_desc) ||
|
||||
""} ${(event.job && event.job.v_model_desc) || ""}`}
|
||||
{`${(event.job && event.job.v_model_yr) || ""} ${
|
||||
(event.job && event.job.v_make_desc) || ""
|
||||
} ${(event.job && event.job.v_model_desc) || ""}`}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{event.job ? (
|
||||
<div>
|
||||
<div>{`${t("jobs.fields.ro_number")}: ${(event.job &&
|
||||
event.job.ro_number) ||
|
||||
""}`}</div>
|
||||
<div>{`${t("jobs.fields.ro_number")}: ${
|
||||
(event.job && event.job.ro_number) || ""
|
||||
}`}</div>
|
||||
<div>
|
||||
{t("jobs.fields.clm_total")}:
|
||||
<CurrencyFormatter>
|
||||
{(event.job && event.job.clm_total) || ""}
|
||||
</CurrencyFormatter>
|
||||
</div>
|
||||
<div>{`${t("jobs.fields.clm_no")}: ${(event.job &&
|
||||
event.job.clm_no) ||
|
||||
""}`}</div>
|
||||
<div>{`${t("jobs.fields.clm_no")}: ${
|
||||
(event.job && event.job.clm_no) || ""
|
||||
}`}</div>
|
||||
<div>
|
||||
{t("jobs.fields.ownr_ea")}:{(event.job && event.job.ownr_ea) || ""}
|
||||
</div>
|
||||
@@ -76,26 +76,31 @@ export default function ScheduleEventComponent({ event, handleCancel }) {
|
||||
</div>
|
||||
);
|
||||
|
||||
const RegularEvent = event.isintake ? (
|
||||
<div>
|
||||
<strong>{`${(event.job && event.job.ownr_fn) || ""} ${
|
||||
(event.job && event.job.ownr_ln) || ""
|
||||
}`}</strong>
|
||||
<span style={{ margin: 4 }}>
|
||||
{`${(event.job && event.job.v_model_yr) || ""} ${
|
||||
(event.job && event.job.v_make_desc) || ""
|
||||
} ${(event.job && event.job.v_model_desc) || ""}`}
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<strong>{`${event.title || ""}`}</strong>
|
||||
</div>
|
||||
);
|
||||
|
||||
const Load = (
|
||||
<div className="load">
|
||||
<Progress percent={77} showInfo={false} />
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<Popover content={popoverContent}>
|
||||
<div>
|
||||
{event.isintake ? (
|
||||
<div>
|
||||
<strong>{`${(event.job && event.job.ownr_fn) || ""} ${(event.job &&
|
||||
event.job.ownr_ln) ||
|
||||
""}`}</strong>
|
||||
<span style={{ margin: 4 }}>
|
||||
{`${(event.job && event.job.v_model_yr) ||
|
||||
""} ${(event.job && event.job.v_make_desc) ||
|
||||
""} ${(event.job && event.job.v_model_desc) || ""}`}
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<strong>{`${event.title || ""}`}</strong>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div>{event.allDay ? Load : RegularEvent}</div>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useTranslation } from "react-i18next";
|
||||
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||
|
||||
export default function ScheduleExistingAppointmentsList({
|
||||
existingAppointments
|
||||
existingAppointments,
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
if (existingAppointments.loading) return <LoadingSpinner />;
|
||||
@@ -22,22 +22,26 @@ export default function ScheduleExistingAppointmentsList({
|
||||
<div>
|
||||
{t("appointments.labels.priorappointments")}
|
||||
<Timeline>
|
||||
{existingAppointments.data.appointments.map(item => {
|
||||
return (
|
||||
<Timeline.Item
|
||||
key={item.id}
|
||||
color={item.canceled ? "red" : item.arrived ? "green" : "blue"}
|
||||
>
|
||||
{item.canceled
|
||||
? t("appointments.labels.cancelledappointment")
|
||||
: item.arrived
|
||||
? t("appointments.labels.arrivedon")
|
||||
: t("appointments.labels.scheduledfor")}
|
||||
{existingAppointments.data
|
||||
? existingAppointments.data.appointments.map((item) => {
|
||||
return (
|
||||
<Timeline.Item
|
||||
key={item.id}
|
||||
color={
|
||||
item.canceled ? "red" : item.arrived ? "green" : "blue"
|
||||
}
|
||||
>
|
||||
{item.canceled
|
||||
? t("appointments.labels.cancelledappointment")
|
||||
: item.arrived
|
||||
? t("appointments.labels.arrivedon")
|
||||
: t("appointments.labels.scheduledfor")}
|
||||
|
||||
<DateTimeFormatter>{item.start}</DateTimeFormatter>
|
||||
</Timeline.Item>
|
||||
);
|
||||
})}
|
||||
<DateTimeFormatter>{item.start}</DateTimeFormatter>
|
||||
</Timeline.Item>
|
||||
);
|
||||
})
|
||||
: null}
|
||||
</Timeline>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -48,7 +48,7 @@ export function ScheduleJobModalContainer({
|
||||
const existingAppointments = useQuery(QUERY_APPOINTMENTS_BY_JOBID, {
|
||||
variables: { jobid: jobId },
|
||||
fetchPolicy: "network-only",
|
||||
skip: !visible,
|
||||
skip: !visible || !!!jobId,
|
||||
});
|
||||
|
||||
//TODO Customize the amount of minutes it will add.
|
||||
|
||||
Reference in New Issue
Block a user