From f0101e26610bd4b21b20f983b6489a2a8b6b0a8c Mon Sep 17 00:00:00 2001 From: Fanna Lautenbach <lautenbach@astron.nl> Date: Tue, 8 Aug 2023 10:52:54 +0200 Subject: [PATCH] minor refactoring: name change, style change, move to folder --- .../components/Timeline/CalendarTimeline.js | 78 +++++----- .../src/layout/sass/_timeline.scss | 2 +- .../{ => toolbar}/DateTimeNavigator.js | 30 ++-- .../{Toolbar.js => toolbar/Filters.js} | 146 ++++++++++++------ .../tmss_webapp/src/routes/Timeline/view.js | 114 +++++--------- .../src/routes/Timeline/week.view.js | 49 +++--- 6 files changed, 222 insertions(+), 197 deletions(-) rename SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/components/{ => toolbar}/DateTimeNavigator.js (91%) rename SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/components/{Toolbar.js => toolbar/Filters.js} (53%) diff --git a/SAS/TMSS/frontend/tmss_webapp/src/components/Timeline/CalendarTimeline.js b/SAS/TMSS/frontend/tmss_webapp/src/components/Timeline/CalendarTimeline.js index 0bb3fdc0837..2def44292ed 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/components/Timeline/CalendarTimeline.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/components/Timeline/CalendarTimeline.js @@ -6,29 +6,18 @@ import Timeline, { DateHeader, CustomMarker, CursorMarker, - // CustomHeader } from 'react-calendar-timeline'; import containerResizeDetector from 'react-calendar-timeline/lib/resize-detector/container'; import moment from 'moment'; import _ from 'lodash'; - -import { Button } from 'primereact/button'; -import { Dropdown } from 'primereact/dropdown'; - import UtilService from '../../services/util.service'; - import 'react-calendar-timeline/lib/Timeline.css'; import "flatpickr/dist/flatpickr.css"; -import { Checkbox } from 'primereact/checkbox'; -import { ProgressSpinner } from 'primereact/progressspinner'; -// import { CustomPageSpinner } from '../CustomPageSpinner'; -import Flatpickr from "react-flatpickr"; import confirmDatePlugin from "flatpickr/dist/plugins/confirmDate/confirmDate"; import shortcutButtonsPlugin from "shortcut-buttons-flatpickr"; import UIConstants from '../../utils/ui.constants'; -import DateTimeNavigator from "../../routes/Timeline/components/DateTimeNavigator"; -import Legendbar from "../../routes/Timeline/components/Legendbar"; -import Toolbar from "../../routes/Timeline/components/Toolbar"; +import DateTimeNavigator from "../../routes/Timeline/components/toolbar/DateTimeNavigator"; +import Filters from "../../routes/Timeline/components/toolbar/Filters"; // Label formats for day headers based on the interval label width const DAY_HEADER_FORMATS = [{ name: "longer", minWidth: 300, maxWidth: 50000, format: "DD dddd, MMMM YYYY"}, @@ -55,6 +44,7 @@ const ZOOM_LEVELS = [{name: '30 Minutes', value: 30 * 60}, {name: '2 Days', value: 2 * 24 * 60 * 60}, {name: '3 Days', value: 3 * 24 * 60 * 60}, {name: '5 Days', value: 5 * 24 * 60 * 60}, + {name: '5 Days', value: 5 * 24 * 60 * 60}, {name: '1 Week', value: 7 * 24 * 60 * 60}, {name: '2 Weeks', value: 14 * 24 * 60 * 60}, {name: '4 Weeks', value: 28 * 24 * 60 * 60}, @@ -135,9 +125,10 @@ export class CalendarTimeline extends Component { selectedStationGroup: props.selectedStationGroup, mainStationGroupOptions: props.mainStationGroupOptions, setSelectedStationGroup: props.setSelectedStationGroup, - showTimeLineItems: props.showTimelineItems, - showSUs: props.showSUs, - showTasks: props.showTasks, + suToggle: props.suToggle, + taskToggle: props.taskToggle, + setSUToggle: props.setSUToggle, + setTaskToggle: props.setTaskToggle, selectedTaskTypes: props.selectedTaskTypes, taskTypes: props.taskTypes, setSelectedTaskTypes: props.setSelectedTaskTypes, @@ -1548,7 +1539,7 @@ export class CalendarTimeline extends Component { let group = DEFAULT_GROUP.concat(props.group); if (!this.props.showSunTimings && this.state.viewType === UIConstants.timeline.types.NORMAL // && !this.loadingStationSunTimes - && props.stationView) { + && props.stationsViewToggle) { props.items = await this.addStationSunTimes(this.state.defaultStartTime, this.state.defaultEndTime, props.group, props.items); props.items = _.orderBy(props.items, ['type'], ['desc']); } else if(this.props.showSunTimings && this.state.viewType === UIConstants.timeline.types.NORMAL && !this.loadingNormalSuntimes) { @@ -1556,7 +1547,11 @@ export class CalendarTimeline extends Component { } else if (this.state.viewType === UIConstants.timeline.types.WEEKVIEW) { props.items = await this.addWeekSunTimes(this.state.defaultStartTime, this.state.defaultEndTime, group, props.items); } - this.setState({group: group, showSpinner: false, items: _.orderBy(props.items, ['type'], ['desc'])}); + this.setState({group: group, showSpinner: false, items: _.orderBy(props.items, ['type'], ['desc']), + onSkyViewToggle: props.onSkyViewToggle, stationsViewToggle: props.stationsViewToggle, selectedStationGroup: props.selectedStationGroup, + reservationsViewToggle: props.reservationsViewToggle, reservationFilter: props.reservationFilter, taskToggle: props.taskToggle, suToggle: props.suToggle, + selectedTaskTypes: props.selectedTaskTypes + }); } else { this.setState({mouseEvent: false}); } @@ -1574,30 +1569,33 @@ export class CalendarTimeline extends Component { this.setState({weekDay: value, showCustomDate: true, reset: false}); this.changeWeek(null, true); } + + // console.log("rendering: ", this.state.showTimelineItems) return ( <React.Fragment> <div className="timeline-tools"> - <Toolbar onSkyViewToggle={this.state.onSkyViewToggle} - setOnSkyViewToggle={this.state.setOnSkyViewToggle} - stationsViewToggle={this.state.stationsViewToggle} - setStationsViewToggle={this.state.setStationsViewToggle} - isStationTasksVisible={this.state.isStationTasksVisible} - changeViewBlocks={this.state.changeViewBlocks} - selectedStationGroup={this.state.selectedStationGroup} - mainStationGroupOptions={this.state.mainStationGroupOptions} - setSelectedStationGroup={this.state.setSelectedStationGroup} - showTimeLineItems={this.state.showTimelineItems} - showSUs={this.state.showSUs} - showTasks={this.state.showTasks} - selectedTaskTypes={this.state.selectedTaskTypes} - taskTypes={this.state.taskTypes} - setSelectedTaskTypes={this.state.setSelectedTaskTypes} - setGroupByProject={this.state.setGroupByProject} - isGroupedByProject={this.state.isGroupedByProject} - reservationsViewToggle={this.state.reservationsViewToggle} - setReservationsViewToggle={this.state.setReservationsViewToggle} - reservationFilter={this.state.reservationFilter} - setReservationFilter={this.state.setReservationFilter}/> + <Filters onSkyViewToggle={this.state.onSkyViewToggle} + setOnSkyViewToggle={this.state.setOnSkyViewToggle} + stationsViewToggle={this.state.stationsViewToggle} + setStationsViewToggle={this.state.setStationsViewToggle} + isStationTasksVisible={this.state.isStationTasksVisible} + changeViewBlocks={this.state.changeViewBlocks} + selectedStationGroup={this.state.selectedStationGroup} + mainStationGroupOptions={this.state.mainStationGroupOptions} + setSelectedStationGroup={this.state.setSelectedStationGroup} + suToggle={this.state.suToggle} + setSUToggle={this.state.setSUToggle} + taskToggle={this.state.taskToggle} + setTaskToggle={this.state.setTaskToggle} + selectedTaskTypes={this.state.selectedTaskTypes} + taskTypes={this.state.taskTypes} + setSelectedTaskTypes={this.state.setSelectedTaskTypes} + setGroupByProject={this.state.setGroupByProject} + isGroupedByProject={this.state.isGroupedByProject} + reservationsViewToggle={this.state.reservationsViewToggle} + setReservationsViewToggle={this.state.setReservationsViewToggle} + reservationFilter={this.state.reservationFilter} + setReservationFilter={this.state.setReservationFilter}/> <DateTimeNavigator currentUTC={this.state.currentUTC} allowLive={isRange} @@ -1648,7 +1646,7 @@ export class CalendarTimeline extends Component { <DateHeader unit={this.state.lstDateHeaderUnit} intervalRenderer={this.renderUTCDateHeader} ></DateHeader> {!this.state.isLSTDateHeaderLoading && // This method keeps updating the header labels, so that the LST values will be displayed after fetching from server - <DateHeader unit={this.state.lstDateHeaderUnit} + <DateHeader unit={this.state.lstDateHeaderUnit} intervalRenderer={({ getIntervalProps, intervalContext, data })=>{return this.renderLSTDateHeader({ getIntervalProps, intervalContext, data })}}> </DateHeader> // This method will render once but will not update the values after fetching from server diff --git a/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_timeline.scss b/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_timeline.scss index 13bac05b8df..f860f35ec93 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_timeline.scss +++ b/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_timeline.scss @@ -72,7 +72,7 @@ padding-right: 1rem; flex: 0 0 auto; - .disabled { + &.disabled { opacity: 50%; cursor: not-allowed; } diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/components/DateTimeNavigator.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/components/toolbar/DateTimeNavigator.js similarity index 91% rename from SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/components/DateTimeNavigator.js rename to SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/components/toolbar/DateTimeNavigator.js index 521a3fb3e1d..7c2882f2d50 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/components/DateTimeNavigator.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/components/toolbar/DateTimeNavigator.js @@ -1,11 +1,12 @@ -import UIConstants from "../../../utils/ui.constants"; +import UIConstants from "../../../../utils/ui.constants"; import {Checkbox} from "primereact/checkbox"; import Flatpickr from "react-flatpickr"; import {Button} from "primereact/button"; import {Dropdown} from "primereact/dropdown"; import React, {useEffect, useState} from "react"; -import UtilService from "../../../services/util.service"; +import UtilService from "../../../../services/util.service"; import moment from "moment/moment"; +import {Spinner} from "reactstrap"; function getDateTimeElement(title, time, formatter) { if (!time) { @@ -179,13 +180,14 @@ export default function DateTimeNavigator(props) { console.log("Cannot retrieve the UTC and thus cannot render the date time navigator: ", error) }); } - }, [currentUTC]) + }, [currentUTC, currentLST]) + const utcSeconds = moment.utc().seconds(); useEffect(() => { //update the LST date's seconds after initialization if (currentLST) { setCurrentLST(currentLST.add(1, 'second')) } - }, [moment.utc().seconds()]) + }, [utcSeconds]) useEffect(() => { @@ -196,24 +198,26 @@ export default function DateTimeNavigator(props) { }, [isLive]) if (!currentUTC || !currentLST) { - return null; + return <div className="p-grid timeline-datetime-navigator"> + <Spinner className="m-5" style={{color: "var(--primary-300)"}}/> + </div> } - return <div className="p-grid timeline-datetime-navigator"> - <div className="section"> - <div className="header">Navigation</div> - <div className="group"> + return <div className=" p-grid timeline-datetime-navigator"> + <div className=" section"> + <div className=" header">Navigation</div> + <div className=" group"> {getDateTimeInfo(currentUTC, currentLST)} - <div className="selector-container"> + <div className=" selector-container"> {getDateSelector(isRange, currentDateValue, onChangeDateCallback, onCloseDateCallback, onClickDateResetButtonCallback)} {getMoveWithTimeCheckbox(allowLive, isLive, setIsLive)} {getWeekChanger(isRange, onWeekChangeCallback)} </div> </div> </div> - <div className="section"> - <div className="header">Zoom</div> - <div className="group group--row"> + <div className=" section"> + <div className=" header">Zoom</div> + <div className=" group group--row"> {getZoomSelect(zoomLevel, allZoomLevels, onChangeZoomLevelCallback)} {getZoomAndMoveActions(moveLeftCallback, moveRightCallback, zoomOutCallback, zoomInCallback, zoomLevel)} {getResetButton(onClickTimeZoomResetButtonCallback)} diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/components/Toolbar.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/components/toolbar/Filters.js similarity index 53% rename from SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/components/Toolbar.js rename to SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/components/toolbar/Filters.js index 581b995b09e..ca850f5fc3b 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/components/Toolbar.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/components/toolbar/Filters.js @@ -1,8 +1,8 @@ import {InputSwitch} from "primereact/inputswitch"; import {MultiSelect} from "primereact/multiselect"; import React, {useEffect, useState} from "react"; -import UtilService from "../../../services/util.service"; -import {Tooltip} from "primereact/tooltip"; +import UtilService from "../../../../services/util.service"; +import {Spinner} from "reactstrap"; function fetchReservationReasons() { let reasons = [] @@ -18,15 +18,14 @@ function fetchReservationReasons() { return reasons; } -function getToggle(labelName, tooltipText, checkedValue, onChangeCallback) { - let isDisabled = false - if (!checkedValue || onChangeCallback === undefined) { - isDisabled = true +function getToggle(labelName, tooltipText, checkedValue, onChangeCallback, shouldDisable = false) { + if (checkedValue === undefined || onChangeCallback === undefined) { + return null } - return <div className={`toggle-container ${isDisabled ? "disabled" : ""}`}> + return <div className={`toggle-container ${shouldDisable ? "disabled" : ""}`}> <label>{labelName}</label> - <InputSwitch disabled={isDisabled} + <InputSwitch disabled={shouldDisable} checked={checkedValue} tooltip={tooltipText} onChange={(e) => onChangeCallback(e.value) @@ -36,14 +35,14 @@ function getToggle(labelName, tooltipText, checkedValue, onChangeCallback) { function getMultiSelectForToggle(dependentToggle, currentValue, allOptions, onChangeCallback, tooltip, placeHolder, optionLabel = "value", optionValue = "value") { - let isDisabled = false - if (!dependentToggle || currentValue === undefined || allOptions === undefined || onChangeCallback === undefined) { - isDisabled = true; + if (currentValue === undefined || onChangeCallback === undefined || allOptions === undefined) { + return null; } + return <div className="multiselect-container"> {<MultiSelect - className={isDisabled ? "disabled" : ""} - disabled={isDisabled} + className={!dependentToggle ? "disabled" : ""} + disabled={!dependentToggle} optionLabel={optionLabel} optionValue={optionValue} tooltip={tooltip} tooltipOptions={{position: 'left'}} @@ -59,18 +58,15 @@ function getMultiSelectForToggle(dependentToggle, currentValue, allOptions, onCh } function getRadioButtonsForToggle(dependentToggle, onChangeCallback, entries, title = "Show:") { - let isDisabled = false - - if (!dependentToggle || onChangeCallback === undefined || entries === undefined) { - console.log("isDisabled", dependentToggle, onChangeCallback, entries) - isDisabled = true + if (onChangeCallback === undefined || entries === undefined) { + return null } - return <div className={`radiobutton-container ${isDisabled ? "disabled" : ""}`}> + return <div className={`radiobutton-container ${!dependentToggle ? "disabled" : ""}`}> <fieldset> <label>{title}</label> {entries.map(entry => <> - <input disabled={isDisabled} type="radio" value={entry.value} name={entry.name} + <input disabled={!dependentToggle} type="radio" value={entry.value} name={entry.name} className="timeline-toolbar-radio" onClick={(e) => onChangeCallback(e.target.value)} checked={entry.checkedProperty}/> <label className="button-label" htmlFor={entry.name}>{entry.title}</label> @@ -79,7 +75,35 @@ function getRadioButtonsForToggle(dependentToggle, onChangeCallback, entries, ti </div>; } -export default function Toolbar(props) { +/** + * If the mainToggle is on, both toggles can be used and at least one is active + * when the mainToggle is off, exactly one toggle is active + * + * Example: + * when the station view is active, only SUs or tasks can be shown and not both. + * when toggling off the tasks, the SUs should become active and vice versa + * + * @param mainToggle this toggle steers the other two toggles + * @param toggle the toggle value that changed + * @param toggleToChangeValue this toggle is dependent on the toggle that changed + * @param toggleToChangeFunction + */ +function changeDependentToggle(mainToggle, toggle, toggleToChangeValue, toggleToChangeFunction) { + if (toggle === undefined || toggleToChangeValue === undefined || toggleToChangeFunction === undefined || mainToggle === undefined) { + return + } + if (toggle) { + if (mainToggle && toggleToChangeValue) { + toggleToChangeFunction(false) + } + } else { + if (!toggleToChangeValue) { + toggleToChangeFunction(true) + } + } +} + +export default function Filters(props) { const { onSkyViewToggle, setOnSkyViewToggle, @@ -95,11 +119,12 @@ export default function Toolbar(props) { selectedStationGroup, mainStationGroupOptions, //TODO: maybe refactor to here with useEffect setSelectedStationGroup, - showTimeLineItems, - showSUs, - showTasks, + suToggle, + setSUToggle, + taskToggle, + setTaskToggle, selectedTaskTypes, - taskTypes, //TODO: maybe refactor to here with useEffect + allTaskTypes, //TODO: maybe refactor to here with useEffect setSelectedTaskTypes, setGroupByProject, isGroupedByProject @@ -110,47 +135,78 @@ export default function Toolbar(props) { if (reservationReasons.length === 0) { setReservationReasons(fetchReservationReasons()) } - }, [reservationsViewToggle]) + }, [reservationsViewToggle, reservationReasons.length]) - //stations view and on sky view cannot be shown together - const shouldDefineOnSkyViewToggle = stationsViewToggle ? false : onSkyViewToggle + useEffect(() => { + if (taskToggle === undefined) { + return + } + changeDependentToggle(stationsViewToggle, taskToggle, suToggle, setSUToggle); + }, [taskToggle]) + + useEffect(() => { + if (suToggle === undefined) { + return + } + //if tasks were already not shown and SUs are toggled off, make sure to show the tasks again (at least one active constraint) + if (!taskToggle && !suToggle) { + setTaskToggle(true) + } + }, [suToggle]) + useEffect(() => { + if (stationsViewToggle === undefined) { + return + } + //if both tasks and SUs were shown and then stations view is turned on, show the SUs (in favor of the tasks) + if (taskToggle && suToggle) { + setSUToggle(false) + } + }, [stationsViewToggle]) + + console.log(onSkyViewToggle, reservationsViewToggle) + + if (onSkyViewToggle === undefined || reservationsViewToggle === undefined) { + return <div className="p-grid timeline-view-toolbar"> + <Spinner className="m-5" style={{color: "var(--primary-300)"}}/> + </div> + } + + const shouldDisableTaskToggle = stationsViewToggle ? !taskToggle : false + const shouldDisableSUToggle = stationsViewToggle ? !suToggle : false + + //stations view and on sky view cannot be shown together return <div className="p-grid timeline-view-toolbar"> <div className="section"> <div className="header">Filters</div> <div className="group"> - {getToggle("On Sky", "Show on-sky system durations", shouldDefineOnSkyViewToggle, setOnSkyViewToggle)} + {getToggle("On Sky", "Show on-sky system durations", onSkyViewToggle, setOnSkyViewToggle, stationsViewToggle)} + </div> + <div className={"group " + (stationsViewToggle === undefined ? "hide-element" : "")}> + {getToggle("Stations", "Show overview of all stations instead of SU's", stationsViewToggle, setStationsViewToggle, onSkyViewToggle)} + {getMultiSelectForToggle(stationsViewToggle, selectedStationGroup, mainStationGroupOptions, setSelectedStationGroup, + "Select Stations to show in the timeline", "Group")} </div> <div className="group"> {getToggle("Reservations", "Show station reservations", reservationsViewToggle, setReservationsViewToggle)} {getMultiSelectForToggle(reservationsViewToggle, reservationFilter, reservationReasons, setReservationFilter, "Select Reservation Reason(s)", "Reason", "name", "name")} </div> - <div className={"group " + (stationsViewToggle === undefined ? "hide-element" : "")}> - {getToggle("Stations", "Show overview of all stations instead of SU's", stationsViewToggle, setStationsViewToggle)} - {getMultiSelectForToggle(stationsViewToggle, selectedStationGroup, mainStationGroupOptions, setSelectedStationGroup, - "Select Stations to show in the timeline", "Group")} - </div> - <div className={"group " + (showTasks === undefined ? "hide-element" : "")}> - {getToggle("Tasks", "Show tasks", - shouldDefineOnSkyViewToggle ? !showSUs && showTasks : isStationTasksVisible, - shouldDefineOnSkyViewToggle ? showTimeLineItems : changeViewBlocks)} - {getMultiSelectForToggle(shouldDefineOnSkyViewToggle ? !showSUs && showTasks : isStationTasksVisible, - selectedTaskTypes, taskTypes, setSelectedTaskTypes, + <div className={"group " + (taskToggle === undefined ? "hide-element" : "")}> + {getToggle("Tasks", "Show tasks. In station view SUs and tasks cannot be shown together.", taskToggle, setTaskToggle, shouldDisableTaskToggle)} + {getMultiSelectForToggle(taskToggle, selectedTaskTypes, allTaskTypes, setSelectedTaskTypes, "Select Task with certain types to show in the timeline", "Task")} </div> - <div className={"group " + (showSUs === undefined ? "hide-element" : "")}> - {getToggle("SUs", "Show scheduling units", - shouldDefineOnSkyViewToggle ? showSUs && !showTasks : !isStationTasksVisible, - shouldDefineOnSkyViewToggle ? showTimeLineItems : changeViewBlocks)} + <div className={"group " + (suToggle === undefined ? "hide-element" : "")}> + {getToggle("SUs", "Show scheduling units. In station view SUs and tasks cannot be shown together.", suToggle, setSUToggle, shouldDisableSUToggle)} </div> </div> <div className={"section " + (setGroupByProject === undefined ? "hide-element" : "")}> <div className="header">Grouping</div> <div className="group"> - {getRadioButtonsForToggle(showSUs, setGroupByProject, [ + {getRadioButtonsForToggle(suToggle, setGroupByProject, [ {value: "su", name: "SU", title: "SU", checkedProperty: !isGroupedByProject}, {value: "project", name: "Project", title: "Project", checkedProperty: isGroupedByProject}, ], "Group by:")} diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js index 43f0bde2858..fd34e0be5c1 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js @@ -3,21 +3,15 @@ import { Redirect } from 'react-router-dom/cjs/react-router-dom.min'; import moment from 'moment'; import _ from 'lodash'; import Websocket from 'react-websocket'; - -// import SplitPane, { Pane } from 'react-split-pane'; -import { InputSwitch } from 'primereact/inputswitch'; - import AppLoader from '../../layout/components/AppLoader'; import PageHeader from '../../layout/components/PageHeader'; import { CustomDialog } from '../../layout/components/CustomDialog'; import Timeline from '../../components/Timeline'; - import ScheduleService from '../../services/schedule.service'; import UtilService from '../../services/util.service'; import UIConstants from '../../utils/ui.constants'; import TaskService from '../../services/task.service'; import ReservationService from '../../services/reservation.service'; - import UnitConverter from '../../utils/unit.converter'; import Validator from '../../utils/validator'; import SchedulingUnitSummary from '../Scheduling/summary'; @@ -33,9 +27,7 @@ import UnitConversion from '../../utils/unit.converter'; import { appGrowl } from '../../layout/components/AppGrowl'; import TopProgressBar from '../../layout/components/TopProgressBar'; import TimelineItemPopover from "./components/TimelineItemPopover"; -import Toolbar from "./components/Toolbar" import Legendbar from "./components/Legendbar"; -//import { TRUE } from 'node-sass'; // Color constant for SU status const SU_STATUS_COLORS = { @@ -91,13 +83,13 @@ export class TimelineView extends Component { missingStations: [], selectedStationGroup: [], //Station Group(core,international,remote) reservationFilter: [], - showSUs: this.timelineUIAttributes.showSUs===undefined?true:this.timelineUIAttributes.showSUs, - showTasks: this.timelineUIAttributes.showTasks || false, + suToggle: this.timelineUIAttributes.suToggle !== undefined? this.timelineUIAttributes.suToggle: false, + taskToggle: this.timelineUIAttributes.taskToggle !== undefined ? this.timelineUIAttributes.taskToggle : false, groupByProject: this.timelineUIAttributes.groupByProject || false, taskTypes: [], selectedTaskTypes: this.timelineUIAttributes["taskTypes"] || ['observation'], isStationTasksVisible: this.timelineUIAttributes.isStationTasksVisible===undefined?true:this.timelineUIAttributes.isStationTasksVisible, - showReservation: this.timelineUIAttributes.showReservation || false, // Flag to show reservations in normal timeline view + reservationsViewToggle: this.timelineUIAttributes.reservationsViewToggle !== undefined, // Flag to show reservations in normal timeline view userrole: AuthStore.getState(), suStatusList: [], taskStatusList: [], @@ -118,11 +110,8 @@ export class TimelineView extends Component { this.STATUS_BEFORE_SCHEDULED = ['defining', 'defined', 'schedulable']; // Statuses before scheduled to get station_group this.allStationsGroup = []; this.reservations = []; - this.reservationReasons = []; this.optionsMenu = React.createRef(); - // this.menuOptions = [{ label: 'Add Reservation', icon: "fa fa-", disabled: true , command: () => { this.selectOptionMenu('Add Reservation') } }, - // { label: 'Reservation List', icon: "fa fa-", command: () => { this.selectOptionMenu('Reservation List') } }, - // ]; + this.getSchedulingUnits = this.getSchedulingUnits.bind(this); this.loadSUsAheadAndTrail = this.loadSUsAheadAndTrail.bind(this); this.showOptionMenu = this.showOptionMenu.bind(this); @@ -149,7 +138,7 @@ export class TimelineView extends Component { this.getStationsByGroupName = this.getStationsByGroupName.bind(this); this.setGroupByProject = this.setGroupByProject.bind(this); this.changeViewBlocks = this.changeViewBlocks.bind(this); - this.showReservationBlocks = this.showReservationBlocks.bind(this); + this.setReservationsViewToggle = this.setReservationsViewToggle.bind(this); this.showDymanicSchedulerPopup = this.showDymanicSchedulerPopup.bind(this); this.onSaveChanges = this.onSaveChanges.bind(this); this.editConstraint = this.editConstraint.bind(this); @@ -159,10 +148,10 @@ export class TimelineView extends Component { this.updateDSStatus = this.updateDSStatus.bind(this); this.close = this.close.bind(this); this.setStationView = this.setStationView.bind(this); - this.showTimelineItems = this.showTimelineItems.bind(this); this.setSelectedTaskTypes = this.setSelectedTaskTypes.bind(this); this.setReservationFilter = this.setReservationFilter.bind(this); this.setOnSkyView = this.setOnSkyView.bind(this); + this.setToggle = this.setToggle.bind(this); } /* Cancel on Scheduling Constraint Popup onEdit */ @@ -348,15 +337,7 @@ export class TimelineView extends Component { ] this.setState({menuOptions: menuOptions, loader: true }); TaskService.getTaskTypes().then(results => {this.setState({taskTypes : results})}); - UtilService.getReservationTemplates().then(templates => { - this.reservationTemplate = templates.length > 0 ? templates[0] : null; - if (this.reservationTemplate) { - let reasons = this.reservationTemplate.ref_resolved_schema.properties.activity.properties.type.enum; - for (const reason of reasons) { - this.reservationReasons.push({ name: reason }); - } - } - }); + // Get all scheduling constraint templates ScheduleService.getSchedulingConstraintTemplates() .then(suConstraintTemplates => { @@ -653,7 +634,7 @@ export class TimelineView extends Component { } setSelectedStationGroup(value) { - // By default all stations groups are selected. + // By default all stations groups are selected. // In that case no need to store the selected group otherwise store the selected groups in local storage if (value.length === this.mainStationGroupOptions.length) { delete this.timelineUIAttributes["stationGroups"]; @@ -751,7 +732,7 @@ export class TimelineView extends Component { 'id': `${this.state.groupByProject ? suBlueprint.project : suBlueprint.id}_${this.state.groupByProject ? task.task_type : task.draft_id}`, parent: this.state.groupByProject ? suBlueprint.project : suBlueprint.id, start: start_time, - title: `${!this.state.showSUs ? (this.state.groupByProject ? suBlueprint.project : suBlueprint.name) : ""} -- ${this.state.groupByProject ? task.task_type : task.name}` + title: `${!this.state.suToggle ? (this.state.groupByProject ? suBlueprint.project : suBlueprint.name) : ""} -- ${this.state.groupByProject ? task.task_type : task.name}` }); } /* >>>>>> If all tasks should be shown in single row remove the above 2 lines and uncomment these lines @@ -964,7 +945,7 @@ export class TimelineView extends Component { moment.utc(suBlueprint.stop_time).isSameOrAfter(endTime))) { if (_.includes(filteredSUBs, suBlueprint.id)) { // Get timeline item for station view noramlly and in timeline view only if SU to be shown - let timelineItem = (this.state.showSUs || (this.state.stationView && !this.state.isStationTasksVisible)) ? this.getTimelineItem(suBlueprint) : null; + let timelineItem = (this.state.suToggle || (this.state.stationView && !this.state.isStationTasksVisible)) ? this.getTimelineItem(suBlueprint) : null; if (this.state.stationView) { this.getStationItemGroups(suBlueprint, timelineItem, this.allStationsGroup, items, this.filteredTaskData); } else { @@ -982,7 +963,7 @@ export class TimelineView extends Component { } } // Add task item only in timeline view and when show task is enabled - if (this.state.showTasks && !this.state.stationView) { + if (this.state.taskToggle && !this.state.stationView) { const taskItems = this.getTaskItems(suBlueprint, startTime, endTime, this.filteredTaskData); items = items.concat(taskItems.items); group = group.concat(taskItems.group); @@ -992,10 +973,10 @@ export class TimelineView extends Component { suBlueprintList.push(suBlueprint); } } - if (this.state.stationView || this.state.showReservation) { + if (this.state.stationView || this.state.reservationsViewToggle) { items = this.addStationReservations(items, startTime, endTime); } - if (this.state.showReservation) { + if (this.state.reservationsViewToggle) { let reservationGroup = [{id: "RESERVATION", parent: "RESERVATION", start: moment.utc("1900-01-01", "YYYY-MM-DD"), title: "RESERVATIONS"} @@ -1007,7 +988,7 @@ export class TimelineView extends Component { group = this.state.group; items = this.state.items; } - await this.setState({ + this.setState({ suBlueprints: suBlueprints, suBlueprintList: _.filter(suBlueprintList, (suBlueprint) => { return suBlueprint.start_time != null }), currentStartTime: startTime, currentEndTime: endTime, @@ -1154,8 +1135,8 @@ export class TimelineView extends Component { * Set reservation filter * @param {String} filter */ - async setReservationFilter(filter) { - await this.setState({ reservationFilter: filter }); + setReservationFilter(filter) { + this.setState({ reservationFilter: filter }); this.updateTimeline(); } @@ -1207,30 +1188,14 @@ export class TimelineView extends Component { return items; } - /** - * To enable displaying SU or Task or Both items in timeline. - * @param {String} value - */ - async showTimelineItems(value) { - // If previous selected option is stored, show the selected option else show the default. - // By default show only SUs. For default option remove from local storage. - const showSUs = value === 'su' || value === "suTask"; - const showTasks = value === 'task' || value === "suTask"; - if (showSUs) { - delete this.timelineUIAttributes["showSUs"]; + setToggle(element, value) { + if (value === undefined) { + delete this.timelineUIAttributes[element]; } else { - this.timelineUIAttributes["showSUs"] = showSUs; - } - if (showTasks) { - this.timelineUIAttributes["showTasks"] = showTasks; - } else { - delete this.timelineUIAttributes["showTasks"]; + this.timelineUIAttributes[element] = value; } this.timelineCommonUtils.storeUIAttributes(this.timelineUIAttributes); - await this.setState({ - showSUs: showSUs, - showTasks: showTasks - }); + this.setState({[element]: value}) this.updateTimeline(); } @@ -1311,7 +1276,7 @@ export class TimelineView extends Component { || moment.utc(suBlueprint.stop_time).isBetween(this.state.currentStartTime, this.state.currentEndTime) || (moment.utc(suBlueprint.start_time).isSameOrBefore(this.state.currentStartTime) && moment.utc(suBlueprint.stop_time).isSameOrAfter(this.state.currentEndTime)))) { - let timelineItem = (this.state.showSUs || this.state.stationView) ? this.getTimelineItem(suBlueprint) : null; + let timelineItem = (this.state.suToggle || this.state.stationView) ? this.getTimelineItem(suBlueprint) : null; if (this.state.stationView) { this.getStationItemGroups(suBlueprint, timelineItem, this.allStationsGroup, items, filteredTaskData); } else { @@ -1327,7 +1292,7 @@ export class TimelineView extends Component { }); } } - if (this.state.showTasks && !this.state.stationView) { + if (this.state.taskToggle && !this.state.stationView) { const taskItems = this.getTaskItems(suBlueprint, this.state.currentStartTime, this.state.currentEndTime, filteredTaskData); items = items.concat(taskItems.items); group = group.concat(taskItems.group); @@ -1335,10 +1300,10 @@ export class TimelineView extends Component { } } } - if (this.state.stationView || this.state.showReservation) { + if (this.state.stationView || this.state.reservationsViewToggle) { items = this.addStationReservations(items, this.state.currentStartTime, this.state.currentEndTime, filteredReservData); } - if (this.state.showReservation) { + if (this.state.reservationsViewToggle) { let reservationGroup = [{id: "RESERVATION", parent: "RESERVATION", start: moment.utc("1900-01-01", "YYYY-MM-DD"), title: "RESERVATIONS"} @@ -1361,7 +1326,7 @@ export class TimelineView extends Component { return stations; } - async setStationView(isChecked) { + setStationView(isChecked) { this.closeSummaryPanel(); let selectedGroups = this.state.selectedStationGroup; // Store selected view and station group. Remove for default values. Default is all station groups. @@ -1377,13 +1342,12 @@ export class TimelineView extends Component { delete this.timelineUIAttributes["stationView"]; } this.timelineCommonUtils.storeUIAttributes(this.timelineUIAttributes); - await this.setState({ stationView: isChecked, selectedStationGroup: selectedGroups }); + this.setState({ stationView: isChecked, selectedStationGroup: selectedGroups }); this.updateTimeline(); } - async setOnSkyView(value) { - console.log("setting it", value) - await this.setState({isOnSkyView: value}); + setOnSkyView(value) { + this.setState({isOnSkyView: value}); this.timelineUIAttributes['isOnSkyView'] = value; this.timelineCommonUtils.storeUIAttributes(this.timelineUIAttributes); this.updateTimeline(); @@ -1713,10 +1677,10 @@ export class TimelineView extends Component { /** * Function sets the flag to show or hide reservation blocks in normal timeline view and the options is remembered. */ - async showReservationBlocks() { - this.timelineUIAttributes["showReservation"] = !this.state.showReservation; + setReservationsViewToggle(value) { + this.timelineUIAttributes["reservationsViewToggle"] = value this.timelineCommonUtils.storeUIAttributes(this.timelineUIAttributes); - await this.setState({showReservation: !this.state.showReservation}); + this.setState({reservationsViewToggle: value}); this.updateTimeline(); } @@ -1918,7 +1882,7 @@ export class TimelineView extends Component { items={this.state.items} currentUTC={this.state.currentUTC} rowHeight={this.state.stationView ? 18 : 50} - sidebarWidth={!this.state.showSUs ? 250 : 200} + sidebarWidth={!this.state.suToggle ? 250 : 200} itemClickCallback={this.onItemClick} itemMouseOverCallback={this.onItemMouseOver} itemMouseOutCallback={this.onItemMouseOut} @@ -1929,6 +1893,7 @@ export class TimelineView extends Component { stackItems className="timeline-toolbar-margin-top-0" //Toolbar properties + onSkyViewToggle={this.state.isOnSkyView} setOnSkyViewToggle={this.setOnSkyView} stationsViewToggle={this.state.stationView} setStationsViewToggle={this.setStationView} @@ -1937,16 +1902,17 @@ export class TimelineView extends Component { selectedStationGroup={this.state.selectedStationGroup} mainStationGroupOptions={this.mainStationGroupOptions} setSelectedStationGroup={this.setSelectedStationGroup} - showTimeLineItems={this.showTimelineItems} - showSUs={this.state.showSUs} - showTasks={this.state.showTasks} + suToggle={this.state.suToggle} + setSUToggle={(value) => {this.setToggle("suToggle", value)}} + taskToggle={this.state.taskToggle} + setTaskToggle={(value) => {this.setToggle("taskToggle", value)}} selectedTaskTypes={this.state.selectedTaskTypes} taskTypes={this.state.taskTypes} setSelectedTaskTypes={this.setSelectedTaskTypes} setGroupByProject={this.setGroupByProject} isGroupedByProject={this.state.groupByProject} - reservationsViewToggle={this.state.showReservation} - setReservationsViewToggle={this.showReservationBlocks} + reservationsViewToggle={this.state.reservationsViewToggle} + setReservationsViewToggle={this.setReservationsViewToggle} reservationFilter={this.state.reservationFilter} setReservationFilter={this.setReservationFilter} ></Timeline> diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js index 9122fa7e8a1..c7049b9a460 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js @@ -31,7 +31,7 @@ import AuthStore from '../../authenticate/auth.store'; import TopProgressBar from '../../layout/components/TopProgressBar'; import {getTimelineItem} from "./week.view.helper"; import TimelineItemPopover from "./components/TimelineItemPopover"; -import Toolbar from "./components/Toolbar"; +import Filters from "./components/toolbar/Filters"; import Legendbar from "./components/Legendbar"; // Color constant for status @@ -77,7 +77,7 @@ export class WeekTimelineView extends Component { stationGroup: [], missingStations: [], reservationFilter: [], - reservationEnabled: this.timelineUIAttributes.reservationEnabled === undefined ? true : this.timelineUIAttributes.reservationEnabled, + reservationsViewToggle: this.timelineUIAttributes.reservationsViewToggle === undefined ? true : this.timelineUIAttributes.reservationsViewToggle, suStatusList: [], taskStatusList: [], taskTypeList: [], @@ -90,7 +90,7 @@ export class WeekTimelineView extends Component { dsStatus: false, // To show the Dynamic Scheduling status in timeline/week view page header fsStatus: false, subSystemStatus: false, - isOnSkyView: this.timelineUIAttributes.isOnSkyWeekView === undefined ? true : this.timelineUIAttributes.isOnSkyWeekView, + onSkyViewToggle: this.timelineUIAttributes.isOnSkyWeekView === undefined ? true : this.timelineUIAttributes.isOnSkyWeekView, } this.STATUS_BEFORE_SCHEDULED = ['defining', 'defined', 'schedulable']; // Statuses before scheduled to get station_group this.reservations = []; @@ -124,8 +124,8 @@ export class WeekTimelineView extends Component { this.close = this.close.bind(this); this.getDSStatus = this.getDSStatus.bind(this); this.updateDSStatus = this.updateDSStatus.bind(this); - this.setOnSkyView = this.setOnSkyView.bind(this); - this.showReservations = this.showReservations.bind(this); + this.setOnSkyViewToggle = this.setOnSkyViewToggle.bind(this); + this.setReservationsViewToggle = this.setReservationsViewToggle.bind(this); this.setReservationFilter = this.setReservationFilter.bind(this); } @@ -451,11 +451,11 @@ export class WeekTimelineView extends Component { schedulingUnits.formatted = _.uniqBy(suBlueprintList, 'id'); // Add dummy variables start_time and stop_time to minimize code changes and switch between different flavours _.map(schedulingUnits.original, su => { - su.start_time = this.state.isOnSkyView ? su.on_sky_start_time : (su.process_start_time || su.on_sky_start_time); - su.stop_time = this.state.isOnSkyView ? su.on_sky_stop_time : (su.process_stop_time || su.on_sky_stop_time); + su.start_time = this.state.onSkyViewToggle ? su.on_sky_start_time : (su.process_start_time || su.on_sky_start_time); + su.stop_time = this.state.onSkyViewToggle ? su.on_sky_stop_time : (su.process_stop_time || su.on_sky_stop_time); _.map(su.task_blueprints, taskBp => { - taskBp.start_time = this.state.isOnSkyView ? taskBp.on_sky_start_time : (taskBp.process_start_time || taskBp.on_sky_start_time); - taskBp.stop_time = this.state.isOnSkyView ? taskBp.on_sky_stop_time : (taskBp.process_stop_time || taskBp.on_sky_stop_time); + taskBp.start_time = this.state.onSkyViewToggle ? taskBp.on_sky_start_time : (taskBp.process_start_time || taskBp.on_sky_start_time); + taskBp.stop_time = this.state.onSkyViewToggle ? taskBp.on_sky_stop_time : (taskBp.process_stop_time || taskBp.on_sky_stop_time); return taskBp; }); return su; @@ -764,7 +764,7 @@ export class WeekTimelineView extends Component { } } } - if (this.state.reservationEnabled) { + if (this.state.reservationsViewToggle) { items = this.addWeekReservations(items, startTime, endTime, weekDay); } } else { @@ -891,7 +891,7 @@ export class WeekTimelineView extends Component { } } - if (this.state.reservationEnabled) { + if (this.state.reservationsViewToggle) { items = this.addWeekReservations(items, startTime, endTime, weekDay, filteredReservData); } if (this.timeline) { @@ -1155,11 +1155,11 @@ export class WeekTimelineView extends Component { // Get stations involved for this SUB let stations = this.timelineCommonUtils.getSUStations(suBlueprint); suBlueprint.stations = _.uniq(stations); - suBlueprint.start_time = this.state.isOnSkyView ? suBlueprint.on_sky_start_time : (suBlueprint.process_start_time || suBlueprint.on_sky_start_time); - suBlueprint.stop_time = this.state.isOnSkyView ? suBlueprint.on_sky_stop_time : (suBlueprint.process_stop_time || suBlueprint.on_sky_stop_time); + suBlueprint.start_time = this.state.onSkyViewToggle ? suBlueprint.on_sky_start_time : (suBlueprint.process_start_time || suBlueprint.on_sky_start_time); + suBlueprint.stop_time = this.state.onSkyViewToggle ? suBlueprint.on_sky_stop_time : (suBlueprint.process_stop_time || suBlueprint.on_sky_stop_time); _.map(suBlueprint.task_blueprints, taskBp => { - taskBp.start_time = this.state.isOnSkyView ? taskBp.on_sky_start_time : (taskBp.process_start_time || taskBp.on_sky_start_time); - taskBp.stop_time = this.state.isOnSkyView ? taskBp.on_sky_stop_time : (taskBp.process_stop_time || taskBp.on_sky_stop_time); + taskBp.start_time = this.state.onSkyViewToggle ? taskBp.on_sky_start_time : (taskBp.process_start_time || taskBp.on_sky_start_time); + taskBp.stop_time = this.state.onSkyViewToggle ? taskBp.on_sky_stop_time : (taskBp.process_stop_time || taskBp.on_sky_stop_time); return taskBp; }); // Remove the old SUB object from the existing list and add the newly fetched SUB @@ -1174,18 +1174,19 @@ export class WeekTimelineView extends Component { }); } - async showReservations(value) { - await this.setState({reservationEnabled: value}); + async setReservationsViewToggle(value) { + this.setState({reservationsViewToggle: value}); let updatedItemGroupData = await this.dateRangeCallback(this.state.startTime, this.state.endTime, true, this.state.weekDay); this.timeline.updateTimeline(updatedItemGroupData); - this.timelineUIAttributes.reservationEnabled = value; + this.timelineUIAttributes.reservationsViewToggle = value; this.storeUIAttributes(); } - async setOnSkyView(value) { - await this.setState({isOnSkyView: value}); + async setOnSkyViewToggle(value) { + this.setState({onSkyViewToggle: value}); this.timelineUIAttributes['isOnSkyWeekView'] = value; let updatedItemGroupData = await this.dateRangeCallback(this.state.startTime, this.state.endTime, true, this.state.weekDay); + updatedItemGroupData.onSkyViewToggle = value this.timeline.updateTimeline(updatedItemGroupData); this.storeUIAttributes(); } @@ -1569,10 +1570,10 @@ export class WeekTimelineView extends Component { viewType={UIConstants.timeline.types.WEEKVIEW} dateRangeCallback={this.dateRangeCallback} //Toolbar properties - onSkyViewToggle={this.state.isOnSkyView} - setOnSkyViewToggle={this.setOnSkyView} - reservationsViewToggle={this.state.reservationEnabled} - setReservationsViewToggle={this.showReservations} + onSkyViewToggle={this.state.onSkyViewToggle} + setOnSkyViewToggle={this.setOnSkyViewToggle} + reservationsViewToggle={this.state.reservationsViewToggle} + setReservationsViewToggle={this.setReservationsViewToggle} reservationFilter={this.state.reservationFilter} setReservationFilter={this.setReservationFilter} ></Timeline> -- GitLab