diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/WeekView.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/WeekView.js index 09a4690287d801c007e04a2e0c9cc6ec84c19281..de108252601e0bbe26016b8c741327ee6a7974d8 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/WeekView.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/WeekView.js @@ -366,7 +366,7 @@ export default function WeekView() { // websocket hook that opens and allows interaction via the wss connection // todo: there is probably a better way to access the component state from the hook? - useWeekViewWebSocket(data, setData, summaryItem, setSummaryItem, setShowSummary); + useWeekViewWebSocket(data, setData, summaryItem, setSummaryItem, setShowSummary, startTime, endTime); diff --git a/SAS/TMSS/frontend/tmss_webapp/src/utils/websocket.js b/SAS/TMSS/frontend/tmss_webapp/src/utils/websocket.js index 8fa2400394e9da0702b99a04ced3226bc4d11268..57ba6e0601fea2cbce9f86d494b7301548430a79 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/utils/websocket.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/utils/websocket.js @@ -4,11 +4,11 @@ import ReservationService from "../services/reservation.service"; import useWebSocket from 'react-use-websocket'; import { getStore } from "../services/store.helper"; import UIConstants from "../utils/ui.constants"; - +import moment from "moment"; const isDebugLoggingOn =false; -function useWeekViewWebSocket(data, setData, summaryItem, setSummaryItem, setShowSummary) { - +function useWeekViewWebSocket(data, setData, summaryItem, setSummaryItem, setShowSummary, startTime, endTime) { + /** * Function to call when websocket is connected */ @@ -32,9 +32,11 @@ function useWeekViewWebSocket(data, setData, summaryItem, setSummaryItem, setSho if (isDebugLoggingOn) console.log("WS Closed"); } - function fetchBlueprintAndAddToTimeline(id) { + function fetchBlueprintAndAddToTimeline(id, startTime, endTime) { // The websocket message only contains a subset of the details we need, so fetch the full set - ScheduleService.getTimelineSlimBlueprints(undefined, undefined, id) // todo: check time + const from = startTime.format(UIConstants.CALENDAR_DATETIME_FORMAT); + const until = endTime.format(UIConstants.CALENDAR_DATETIME_FORMAT); + ScheduleService.getTimelineSlimBlueprints(from, until, id) .then((response) => { setData(prevData => ({ ...prevData, @@ -45,10 +47,12 @@ function useWeekViewWebSocket(data, setData, summaryItem, setSummaryItem, setSho } - function fetchReservationAndAddToTimeline(id) { + function fetchReservationAndAddToTimeline(id, startTime, endTime) { const shouldFetchReservations = getStore(UIConstants.STORE_KEY_TIMELINE).reservationsToggle; + const from = startTime.format(UIConstants.CALENDAR_DATETIME_FORMAT); + const until = endTime.format(UIConstants.CALENDAR_DATETIME_FORMAT); if (shouldFetchReservations) { - ReservationService.getTimelineReservations(undefined, undefined, id) // todo: check time + ReservationService.getTimelineReservations(from, until, id) .then((response) => { setData(prevData => ({ ...prevData, @@ -59,6 +63,31 @@ function useWeekViewWebSocket(data, setData, summaryItem, setSummaryItem, setSho } } + function deleteBlueprintFromTimeline(id) { + const schedulingUnits = data.schedulingUnits + _.remove(schedulingUnits, function (su) { return su.id === id }); + setData(prevData => ({ + ...prevData, + schedulingUnits: schedulingUnits + })) + if (summaryItem?.id === id) { + setShowSummary(false); + } + } + + function deleteReservationFromTimeline(id) { + const reservations = data.reservations + _.remove(reservations, function (res) { return res.id === id }); + setData(prevData => ({ + ...prevData, + reservations: reservations + })) + if (summaryItem?.id === id) { + setShowSummary(false); + } + } + + /** * Handles the message received through websocket * @param {String} data - String of JSON data @@ -69,31 +98,36 @@ function useWeekViewWebSocket(data, setData, summaryItem, setSummaryItem, setSho case 'scheduling_unit_blueprint': { switch (jsonData.action) { case 'delete': { - const schedulingUnits = data.schedulingUnits - _.remove(schedulingUnits, function (su) { return su.id === jsonData.object_details.id }); - setData(prevData => ({ - ...prevData, - schedulingUnits: schedulingUnits - })) - if (summaryItem?.id === jsonData.object_details.id) { - setShowSummary(false); - } + deleteBlueprintFromTimeline(jsonData.object_details.id); break; } case 'update': { + let inScope = true; + if (jsonData?.object_details?.process_start_time) { + const unit_start_time = moment(jsonData.object_details.process_start_time, moment.ISO_8601); + const unit_stop_time = moment(jsonData.object_details.process_stop_time, moment.ISO_8601); + if ( (unit_stop_time < startTime) || (unit_start_time > endTime) ) { + inScope = false; + } + } if (data.schedulingUnits.some(unit => unit.id === jsonData.object_details.id)) { // usually we already have most details, so only update the relevant ones. - setData(prevData => ({ - ...prevData, - schedulingUnits: prevData.schedulingUnits.map( - unit => unit.id === jsonData.object_details.id ? { ...unit, ...jsonData.object_details } : unit - ) - })); - } else { + if (inScope === true) { + setData(prevData => ({ + ...prevData, + schedulingUnits: prevData.schedulingUnits.map( + unit => unit.id === jsonData.object_details.id ? { ...unit, ...jsonData.object_details } : unit + ) + })); + } else { + // object has been moved out of scope, so let's get rid of it + deleteBlueprintFromTimeline(jsonData.object_details.id); + } + } else if (inScope === true) { // ...but sometimes we don't have the details yet, e.g. because it at least used to be // outside the timelines time range, and we need to fetch all details so we don't miss // anything that e.g. got moved into scope. - fetchBlueprintAndAddToTimeline(jsonData.object_details.id); + fetchBlueprintAndAddToTimeline(jsonData.object_details.id, startTime, endTime); } if (summaryItem?.id === jsonData.object_details.id) { @@ -114,7 +148,7 @@ function useWeekViewWebSocket(data, setData, summaryItem, setSummaryItem, setSho } case 'create': { // The websocket message only contains a subset of the details we need, so fetch the full set - fetchBlueprintAndAddToTimeline(jsonData.object_details.id); + fetchBlueprintAndAddToTimeline(jsonData.object_details.id, startTime, endTime); break; } default: { break; } @@ -124,31 +158,36 @@ function useWeekViewWebSocket(data, setData, summaryItem, setSummaryItem, setSho case 'reservation': { switch (jsonData.action) { case 'delete': { - const reservations = data.reservations - _.remove(reservations, function (res) { return res.id === jsonData.object_details.id }); - setData(prevData => ({ - ...prevData, - reservations: reservations - })) - if (summaryItem?.id === jsonData.object_details.id) { - setShowSummary(false); - } + deleteReservationFromTimeline(jsonData.object_details.id); break; } case 'update': { + let inScope = true; + if (jsonData.object_details.start_time) { + const res_start_time = moment(jsonData.object_details.start_time, moment.ISO_8601); + const res_stop_time = moment(jsonData.object_details.stop_time, moment.ISO_8601); + if ( (res_stop_time < startTime) || (res_start_time > endTime) ) { + inScope = false; + } + } if (data.reservations.some(res => res.id === jsonData.object_details.id)) { - // usually we already have most details, so only update the relevant ones. - setData(prevData => ({ - ...prevData, - reservations: prevData.reservations.map( - res => res.id === jsonData.object_details.id ? { ...res, ...jsonData.object_details } : res - ), - })); - } else { + if (inScope === true) { + // usually we already have most details, so only update the relevant ones. + setData(prevData => ({ + ...prevData, + reservations: prevData.reservations.map( + res => res.id === jsonData.object_details.id ? { ...res, ...jsonData.object_details } : res + ), + })); + } else { + // object has been moved out of scope, so let's get rid of it + deleteReservationFromTimeline(jsonData.object_details.id); + } + } else if (inScope === true) { // ...but sometimes we don't have the details yet, e.g. because it at least used to be // outside the timelines time range, and we need to fetch all details so we don't miss // anything that e.g. got moved into scope. - fetchReservationAndAddToTimeline(jsonData.object_details.id); + fetchReservationAndAddToTimeline(jsonData.object_details.id, startTime, endTime); } if (summaryItem?.id === jsonData.object_details.id) { // Trigger a full refresh of the details panel @@ -158,7 +197,7 @@ function useWeekViewWebSocket(data, setData, summaryItem, setSummaryItem, setSho } case 'create': { // The websocket message only contains a subset of the details we need, so fetch the full set - fetchReservationAndAddToTimeline(jsonData.object_details.id); + fetchReservationAndAddToTimeline(jsonData.object_details.id, startTime, endTime); break; } default: { break; }