From cd972f8b6ce98d4672fd501099f4322e11a0a23b Mon Sep 17 00:00:00 2001 From: Reinder Kraaij <kraaij@astron.nl> Date: Mon, 27 Nov 2023 00:39:46 +0000 Subject: [PATCH] Resolve TMSS-2294 "Part v" --- .../authenticate/permission.stack.handler.js | 41 +-- .../src/components/FormActionbar.js | 21 +- .../src/components/JSONEditor/JEditor.js | 9 +- .../src/layout/components/PageActionMenu.js | 26 +- .../src/layout/components/PageHeader.js | 2 +- .../src/layout/sass/_pageheader.scss | 8 + .../tmss_webapp/src/layout/sass/station.scss | 68 +++++ .../tmss_webapp/src/routes/Cycle/create.js | 2 +- .../src/routes/Cycle/create.test.js | 2 +- .../tmss_webapp/src/routes/Cycle/edit.js | 2 +- .../tmss_webapp/src/routes/Project/create.js | 2 +- .../tmss_webapp/src/routes/Project/edit.js | 2 +- .../routes/Reservation/reservation.create.js | 2 +- .../routes/Reservation/reservation.edit.js | 2 +- .../src/routes/Scheduling/create.js | 2 +- .../tmss_webapp/src/routes/Scheduling/edit.js | 2 +- .../excelview.schedulingset.test.js | 2 +- .../routes/Station/StationConstraintImage.js | 47 +++ .../routes/Station/StationConstraintView.js | 27 ++ .../routes/Station/StationConstraintsview.js | 0 .../src/routes/Station/StationGeoView.js | 4 +- .../src/routes/Station/StationView.js | 277 ++++++++++++------ .../routes/SystemEvent/system.event.create.js | 2 +- .../routes/SystemEvent/system.event.edit.js | 2 +- .../tmss_webapp/src/routes/Task/edit.js | 6 +- .../tmss_webapp/src/routes/Task/edit.test.js | 10 +- .../Timeline/helpers/week.view.helper.js | 54 +--- .../src/services/schedule.service.js | 31 ++ .../tmss_webapp/src/utils/externalurls.js | 11 +- .../src/utils/externalurls.test.js | 7 - .../src/utils/pageheaderactions.util.js | 46 +++ 31 files changed, 524 insertions(+), 195 deletions(-) create mode 100644 SAS/TMSS/frontend/tmss_webapp/src/routes/Station/StationConstraintImage.js create mode 100644 SAS/TMSS/frontend/tmss_webapp/src/routes/Station/StationConstraintView.js delete mode 100644 SAS/TMSS/frontend/tmss_webapp/src/routes/Station/StationConstraintsview.js create mode 100644 SAS/TMSS/frontend/tmss_webapp/src/utils/pageheaderactions.util.js diff --git a/SAS/TMSS/frontend/tmss_webapp/src/authenticate/permission.stack.handler.js b/SAS/TMSS/frontend/tmss_webapp/src/authenticate/permission.stack.handler.js index a99a197a0e5..3035ca5352e 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/authenticate/permission.stack.handler.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/authenticate/permission.stack.handler.js @@ -3,34 +3,37 @@ import AuthService from '../services/auth.service'; import _ from 'lodash'; import axios from 'axios'; +let isPermissionValidated = false const PermissionStackUtil = { + + /** * Get current user permission from API * @param {*} loadPermission * @returns */ getPermissions: async(loadPermission) => { - let permissionStack = {}; + console.log("getPermissions", isPermissionValidated) + let permissionStack = {} + permissionStack = localStorage.getItem("permissionStack"); + if (permissionStack) { + permissionStack = JSON.parse(permissionStack); + if (permissionStack?.token === axios.defaults.headers.common['Authorization']) + { + if(permissionStack?.token!==undefined) { + console.log("Returning with permissionstack",permissionStack) + loadPermission=false + } + } + } + if (loadPermission) { permissionStack = await PermissionStackUtil.getAPIBasedPermission(); - //Use this code if API role permission is not ready for demo - /* let user = Auth.getUser(); - user = user?user.name:""; - if (user === 'scientist' ) { - permissionStack['project'] = {create: true, edit: false, delete: true}; - permissionStack['scheduleunit'] = {create: true, edit: false, delete: true, createsub: false, autodeletion:false, - copysu:false, excelview:true, cleanuptask:false, cancelsu:false, viewworkflow:true,dataproduct: true,}; - } else if (user === 'operator' ) { - permissionStack['project'] = {create: true, edit: false, delete: false}; - permissionStack['scheduleunit'] = {create: true, edit: false, delete: false, createsub: false, autodeletion:true, - copysu:true, excelview:false, cleanuptask:true, cancelsu:false, viewworkflow:true,dataproduct: false,}; - } else { - permissionStack['project'] = {create: true, edit: false, delete: true}; - permissionStack['scheduleunit'] = {create: true, edit: false, delete: true, createsub: false, autodeletion:false, - copysu:false, excelview:true, cleanuptask:false, cancelsu:false, viewworkflow:true,dataproduct: true,}; - } */ - } - AuthStore.dispatch({ type: 'loadpermission', payload: permissionStack}); + console.log("permissionStack after retrieval",isPermissionValidated,permissionStack) + permissionStack.token = axios.defaults.headers.common['Authorization']; + localStorage.setItem("permissionStack", JSON.stringify(permissionStack)); + } + AuthStore.dispatch({ type: 'loadpermission', payload: permissionStack}); return permissionStack; }, async getAPIBasedPermission() { diff --git a/SAS/TMSS/frontend/tmss_webapp/src/components/FormActionbar.js b/SAS/TMSS/frontend/tmss_webapp/src/components/FormActionbar.js index 51da6a4d548..d8ab08210f9 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/components/FormActionbar.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/components/FormActionbar.js @@ -2,7 +2,7 @@ import { Component } from 'react'; import { Button } from 'primereact/button'; import { Checkbox } from 'primereact/checkbox'; import UIConstants from '../utils/ui.constants'; - +import PropTypes from 'prop-types'; export default class FormActionbar extends Component { constructor(props) { super(props); @@ -13,6 +13,18 @@ export default class FormActionbar extends Component { this.tooltipOptions = UIConstants.tooltipOptions; } + + + static propTypes = { + createAnother: PropTypes.bool, + submitTitle:PropTypes.string, + onSubmit:PropTypes.func, + disableSaveBtn:PropTypes.bool, // the enableSaveBtn was badly named, it was actually is written in the code as means disable save button hence a rename. + onCancel:PropTypes.func, + createAnotherCallBack:PropTypes.func, + tooltip:PropTypes.string, + } + /** * * @param {*} e @@ -23,7 +35,6 @@ export default class FormActionbar extends Component { render() { return ( - <> <div className='footer-short-div' > {this.props.createAnother !== undefined && <> @@ -35,10 +46,10 @@ export default class FormActionbar extends Component { <Button label="Save" className="p-button-primary p-button--small act-btn-save" id="save-btn" data-testid="save-btn" title={this.props.submitTitle} icon="pi pi-check" style={{marginRight: "1em", color: "white", marginTop: "5px", paddingBottom: "5px"}} - onClick={this.props.onSubmit} disabled={this.props.enableSaveBtn}/> + onClick={this.props.onSubmit} disabled={this.props.disableSaveBtn}/> <Button label="Cancel" className="p-button--small act-btn-cancel" icon="pi pi-times" onClick={this.props.onCancel}/> </div> - </> ); } -} \ No newline at end of file +} + diff --git a/SAS/TMSS/frontend/tmss_webapp/src/components/JSONEditor/JEditor.js b/SAS/TMSS/frontend/tmss_webapp/src/components/JSONEditor/JEditor.js index 1565cce1d0d..96f6f98a20c 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/components/JSONEditor/JEditor.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/components/JSONEditor/JEditor.js @@ -400,7 +400,14 @@ function Jeditor(props) { singlePulseSearch = (startVal['single_pulse_search'])?true:false; editorOptions.startval = updateInput(startVal); } - editor = new JSONEditor(element, editorOptions); + let editor + try { + editor = new JSONEditor(element, editorOptions); + } + catch (ex) { + console.info("Failure in Creating editor",ex); + } + // Remove loader div after editor intialization const loadingElement = document.getElementById(props.id?`${props.id}_loader`:'editor_holder_loader'); diff --git a/SAS/TMSS/frontend/tmss_webapp/src/layout/components/PageActionMenu.js b/SAS/TMSS/frontend/tmss_webapp/src/layout/components/PageActionMenu.js index 1f4b3c4c03a..3fa56ea0f3e 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/layout/components/PageActionMenu.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/layout/components/PageActionMenu.js @@ -2,6 +2,7 @@ import { Link } from "react-router-dom"; import { Button } from 'primereact/button'; import { Dropdown } from 'primereact/dropdown'; +import { Calendar } from 'primereact/calendar'; const PageActionMenu = ({ actions, className }) => { const onClickLink = (action) => { if (action.link) { @@ -39,7 +40,7 @@ const PageActionMenu = ({ actions, className }) => { return <div className={"page-action-menu " + className}> - {(actions || []).map((action) => { + {(actions || []).map((action,index) => { if (action.type === 'buttonv2') { return ( <Button key={action.title + '_page_header'} title={action.title || ''} @@ -66,14 +67,26 @@ const PageActionMenu = ({ actions, className }) => { </button> ); case 'divider': - return (<span className="action-divider" key={action.title}></span>); + return (<span className="action-divider" key={index}></span>); case 'element': return ( - <div key={`index`} className={action.classes} dangerouslySetInnerHTML={{ __html: action.element }} /> + <div key={index} className={action.classes} dangerouslySetInnerHTML={{ __html: action.element }} /> ) case 'dropdown': - return (<div className={action.classes} key={action.title}> <span className="dropdown-title">{action.title} </span><Dropdown value={action.selected} onChange={(e) => setSelected(e, action)} options={action.options} optionValue="value" optionLabel="label" className="w-full md:w-14rem" /></div>) + if (!action.options) { + return <div className={action.classes} key={action.title}> <span className="dropdown-title">{action.title} </span> <i className="pi pi-spin pi-hourglass"></i> </div> + } + + if (action.optionsvalue) { + return (<div className={action.classes} key={action.title}> <span className="dropdown-title">{action.title} </span><Dropdown value={action.selected} onChange={(e) => setSelected(e, action)} options={action.options} optionValue={action.optionvalue} optionLabel={action.optionlabel} className="w-full md:w-14rem" /></div>) + } + else { + return (<div className={action.classes} key={action.title}> <span className="dropdown-title">{action.title} </span><Dropdown value={action.selected} onChange={(e) => setSelected(e, action)} options={action.options} optionLabel={action.optionlabel} className="w-full md:w-14rem" placeholder={action.optionSelectionLabel}/></div>) + } + + case 'dropdownb': + case 'ext_link': return ( <a href={action.props.pathname} title={action.title || ''} key={action.title} @@ -89,7 +102,10 @@ const PageActionMenu = ({ actions, className }) => { <span key={action.title + '_page_header'} className={action.className} title={action.title || ''}>{action.content}</span> ); - + case 'calendar': + return ( + <div key={`index`}><span>{action.title}</span> <Calendar value={action.selected} onChange={(e) => setSelected(e, action)} dateFormat="yy-mm-dd" showIcon className={action.className} /> </div> + ) default: return ( diff --git a/SAS/TMSS/frontend/tmss_webapp/src/layout/components/PageHeader.js b/SAS/TMSS/frontend/tmss_webapp/src/layout/components/PageHeader.js index 3e6f9209caf..46f217f1ca1 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/layout/components/PageHeader.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/layout/components/PageHeader.js @@ -30,7 +30,7 @@ const PageHeader = ({title, subTitle, actions, className, ...props}) => { <h2 className="page-title">{title || page.title}</h2> {(page.subTitle || subTitle) && <h6 className="page-subtitle">{subTitle || page.subTitle}</h6>} </div> - <PageActionMenu actions={actions}/> + <PageActionMenu actions={actions} className={"page-actions" + className || ""} /> </div> ); } diff --git a/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_pageheader.scss b/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_pageheader.scss index 1fae2ac8ff9..8a43ae5b157 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_pageheader.scss +++ b/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_pageheader.scss @@ -27,6 +27,14 @@ margin-top: 5px; } +.page-actionsdefaultpageHeader{ + display: flex; + + button { + height: 30px; + } +} + .subsystem { font-size: 12px !important; padding: 0.3rem 0.5rem; diff --git a/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/station.scss b/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/station.scss index 9d328042a9d..d577a3dd70e 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/station.scss +++ b/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/station.scss @@ -4,9 +4,37 @@ .StationTable { } + + + .StationListWrap{ display: flex; } +.ConstraintsStart{ + width: 100%; + + justify-content: center; +} + +.Progress{ + margin-left: 10px; +} +.ConstraintsHeader { + display: flex; + flex-direction: row; + padding-bottom: 5px; + padding-left:25px; + border-bottom: 1px solid grey; + .p-calendar{ + + button { + margin-left: 0px; + } + } + +} + + .GeoMap { height:calc(#{$vh * 100} - 11.5em); @@ -53,6 +81,16 @@ } +.BluePrintLoading { + margin-left:25px; +} +.BoxLabel +{ + margin-left:25px; + margin-right: 5px; + line-height: 29px; +} + .custom-marker-icon { display: flex; flex-direction: column; @@ -74,3 +112,33 @@ background-color:rgba(255, 255, 255, 0.5); } + .station-blueprint-dropdown{ + display: flex; + float:left; + margin-right: 10px; + padding-right:5px; + height: 30px; + width:400px; + border-right: 1px solid var(--gray-200); + border-left : 1px solid var(--gray-200); + color:black; + .dropdown-title { + + padding-right: 5px; + padding-left: 5px; + font-size: 14px; + line-height: 28px; + min-width: 70px; + } + } + + .NoOverride + { + padding-left:5px !important; + button { + margin-left: 0px !important; + + } + } + + \ No newline at end of file diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/create.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/create.js index c67c1baa333..0d6e2ef64e7 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/create.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/create.js @@ -543,7 +543,7 @@ export class CycleCreate extends Component { <div className="p-breadcrumb footer-long-div actions" > <FormActionbar createAnotherCallBack={this.setCreateAnother} createAnother={this.state.createAnother} tooltip="Select checkbox to create another Cycle after saving this cycle" - onSubmit={this.saveCycle} enableSaveBtn={!this.state.validForm} onCancel={this.checkIsDirty} /> + onSubmit={this.saveCycle} disableSaveBtn={!this.state.validForm} onCancel={this.checkIsDirty} /> </div> </> } diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/create.test.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/create.test.js index 7f25455ed1a..74ea3bbcc50 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/create.test.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/create.test.js @@ -37,7 +37,7 @@ const setMockSpy = (() => { }); saveCycleSpy = jest.spyOn(CycleService, 'saveCycle'); - saveCycleSpy.mockImplementation((cycle, cycleQuota) => { + saveCycleSpy.mockImplementation((cycle ) => { cycle.url = `http://localhost:3000/api/cycle/${cycle.name}`; return Promise.resolve(cycle) }); diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/edit.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/edit.js index f68637fc3ec..03b37c334f7 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/edit.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/edit.js @@ -529,7 +529,7 @@ export class CycleEdit extends Component { </div> </div> <div className="p-breadcrumb footer-long-div actions" > - <FormActionbar onSubmit={this.saveCycle} enableSaveBtn={!this.state.validForm} onCancel={this.checkIsDirty} /> + <FormActionbar onSubmit={this.saveCycle} disableSaveBtn={!this.state.validForm} onCancel={this.checkIsDirty} /> </div> </> } diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/create.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/create.js index 21d84310dba..b2799559872 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/create.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/create.js @@ -653,7 +653,7 @@ export class ProjectCreate extends Component { <div className="p-breadcrumb footer-long-div actions"> <FormActionbar createAnotherCallBack={this.setCreateAnother} createAnother={this.state.createAnother} tooltip="Select checkbox to create another Project after saving this project" - onSubmit={this.saveProject} enableSaveBtn={!this.state.validForm} onCancel={this.checkIsDirty} /> + onSubmit={this.saveProject} disableSaveBtn={!this.state.validForm} onCancel={this.checkIsDirty} /> </div> </> } diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/edit.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/edit.js index ba3971421a6..d089246cdb0 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/edit.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/edit.js @@ -692,7 +692,7 @@ export class ProjectEdit extends Component { </div> </div> <div className="p-breadcrumb footer-long-div actions" > - <FormActionbar onSubmit={this.saveProject} enableSaveBtn={!this.state.validForm} onCancel={this.checkIsDirty} /> + <FormActionbar onSubmit={this.saveProject} disableSaveBtn={!this.state.validForm} onCancel={this.checkIsDirty} /> </div> </> } diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Reservation/reservation.create.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Reservation/reservation.create.js index 64a443d9421..ff6aa0153fc 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Reservation/reservation.create.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Reservation/reservation.create.js @@ -690,7 +690,7 @@ export class ReservationCreate extends Component { <div className="p-breadcrumb footer-long-div actions" > <FormActionbar createAnotherCallBack={this.setCreateAnother} createAnother={this.state.createAnother} tooltip="Select checkbox to create another reservation after saving this reservation" - onSubmit={this.saveReservation} enableSaveBtn={!this.state.validEditor || !this.state.validForm} onCancel={this.checkIsDirty} /> + onSubmit={this.saveReservation} disableSaveBtn={!this.state.validEditor || !this.state.validForm} onCancel={this.checkIsDirty} /> </div> </> } diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Reservation/reservation.edit.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Reservation/reservation.edit.js index 78633d5548f..ad6a95e1d3a 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Reservation/reservation.edit.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Reservation/reservation.edit.js @@ -619,7 +619,7 @@ export class ReservationEdit extends Component { </div> </div> <div className="p-breadcrumb footer-long-div actions" > - <FormActionbar onSubmit={this.saveReservation} enableSaveBtn={!this.state.validEditor || !this.state.validForm} onCancel={this.checkIsDirty} /> + <FormActionbar onSubmit={this.saveReservation} disableSaveBtn={!this.state.validEditor || !this.state.validForm} onCancel={this.checkIsDirty} /> </div> </div> </React.Fragment> diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/create.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/create.js index 3e37d2876bd..4eab0edb2c0 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/create.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/create.js @@ -1160,7 +1160,7 @@ export class SchedulingUnitCreate extends Component { tooltip="Select checkbox to create another Scheduling Unit after saving this Scheduling Unit" submitTitle={(!this.state.constraintValidEditor || !this.state.validEditor || !this.state.validForm || !this.state.validConstraints || !this.state.validSpecification) ? "" : "Save Scheduling Unit"} onSubmit={this.saveSchedulingUnit} - enableSaveBtn={!this.state.constraintValidEditor || !this.state.validEditor || !this.state.validForm || !this.state.validConstraints || !this.state.validSpecification} + disableSaveBtn={!this.state.constraintValidEditor || !this.state.validEditor || !this.state.validForm || !this.state.validConstraints || !this.state.validSpecification} onCancel={this.checkIsDirty}/> </div> <ReactTooltip id="reacttooltip" place={'left'} type={'dark'} effect={'solid'} multiline={true}/> diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/edit.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/edit.js index 6a335a1b574..168ecb0f615 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/edit.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/edit.js @@ -883,7 +883,7 @@ export class EditSchedulingUnit extends Component { <ReactTooltip id="reacttooltip" place={'left'} type={'dark'} effect={'solid'} multiline={true} /> <div className="p-breadcrumb footer-long-div actions" > <FormActionbar onSubmit={this.saveSchedulingUnit} - enableSaveBtn={!this.state.constraintValidEditor || !this.state.validEditor || !this.state.validForm || !this.state.validConstraints || !this.state.validSpecification} onCancel={this.checkIsDirty} /> + disableSaveBtn={!this.state.constraintValidEditor || !this.state.validEditor || !this.state.validForm || !this.state.validConstraints || !this.state.validSpecification} onCancel={this.checkIsDirty} /> </div> <div className="p-grid" data-testid="confirm_dialog"> diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/excelview.schedulingset.test.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/excelview.schedulingset.test.js index 944945c09f8..338bb3ea8d4 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/excelview.schedulingset.test.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/excelview.schedulingset.test.js @@ -21,7 +21,7 @@ let utcSpy; //Jest issue: https://github.com/jestjs/jest/issues/9709: Cannot be called in beforeXX test method const OBSERVATION_STRATEGY_TEMPLATES = SUServiceMock.getObservStrategies() -jest.setTimeout(120000); +jest.setTimeout(12000); removeReact18ConsoleErrors(); /** diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Station/StationConstraintImage.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Station/StationConstraintImage.js new file mode 100644 index 00000000000..719b1085d0c --- /dev/null +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Station/StationConstraintImage.js @@ -0,0 +1,47 @@ +import PropTypes from 'prop-types'; +import ScheduleService from "../../services/schedule.service"; +import { useEffect, useState } from "react"; +import { ProgressSpinner } from 'primereact/progressspinner'; +export default function StationConstraintImage(props) { + const { + station, + startTime, + blueprintId + } = props + + + const [constraintImage, setConstraintImage] = useState() + + const fetchImage = async () => { + setConstraintImage(null); + let constraintImage = await ScheduleService.getConstraintImgForStationAndSchedulingUnitOnDate(station, blueprintId, startTime); + + setConstraintImage(constraintImage); + }; + + + + + useEffect(() => { + fetchImage(); + }, [station, blueprintId, startTime]); + + + return ( + + <div> + {constraintImage === null ? ( + <ProgressSpinner /> + ) : ( + <img src={constraintImage} alt="Constraint" /> + )} + </div> + ) +} + + +StationConstraintImage.propTypes = { + station: PropTypes.string, + startTime: PropTypes.string, + blueprintId: PropTypes.string, +}; \ No newline at end of file diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Station/StationConstraintView.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Station/StationConstraintView.js new file mode 100644 index 00000000000..208fc9fd45f --- /dev/null +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Station/StationConstraintView.js @@ -0,0 +1,27 @@ +import PropTypes from 'prop-types'; + + +import StationConstraintImage from './StationConstraintImage' + +export default function StationConstraintView(props) { + const { + station, + selectedBluePrint, + selectedBluePrintId, + startTime + } = props + return <div className='ConstraintsStart'> + {selectedBluePrint ? ( + <StationConstraintImage blueprintId={selectedBluePrintId} station={station} startTime={startTime} ></StationConstraintImage>) + : (<div></div> + )} + </div> + +} + +StationConstraintView.propTypes = { + station: PropTypes.string, + selectedBluePrint: PropTypes.array, + selectedBluePrintId: PropTypes.string, + startTime: PropTypes.string +}; \ No newline at end of file diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Station/StationConstraintsview.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Station/StationConstraintsview.js deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Station/StationGeoView.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Station/StationGeoView.js index a8208728051..ee3e27f5e1a 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Station/StationGeoView.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Station/StationGeoView.js @@ -1,7 +1,7 @@ import 'leaflet/dist/leaflet.css' -import {MapContainer, Marker, Popup, TileLayer } from 'react-leaflet' +import {MapContainer, Marker, TileLayer } from 'react-leaflet' import L from 'leaflet' -import { useMap } from 'react-leaflet/hooks' +import { useMap } from 'react-leaflet' diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Station/StationView.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Station/StationView.js index b034c5032bd..1ee55748077 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Station/StationView.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Station/StationView.js @@ -1,102 +1,209 @@ -import { TabView,TabPanel } from "primereact/tabview"; +import { TabView, TabPanel } from "primereact/tabview"; import PropTypes from 'prop-types'; - +import PageHeader from "../../layout/components/PageHeader"; import UtilService from "../../services/util.service"; import { ListBox } from 'primereact/listbox'; -import {useEffect, useState} from "react"; -import StationGeoView from './StationGeoView' - +import { useEffect, useState } from "react"; +import StationGeoView from './StationGeoView' +import StationConstraintView from './StationConstraintView' +import moment from "moment"; +import ScheduleService from "../../services/schedule.service"; +import UIConstants from "../../utils/ui.constants"; +import PageHeaderActions from "../../utils/pageheaderactions.util.js"; -import PageHeader from '../../layout/components/PageHeader'; // see https://react-leaflet.js.org/docs/api-map/ -export default function StationView(props) { - const { - location - } = props +export default function StationView(props) { + const { + location + } = props - const [stations, setStations] = useState() - const [stationsGeo, setStationsGeo] = useState([]) - const [selectedStation, setSelectedStation] = useState() + const [stations, setStations] = useState() + const [stationsGeo, setStationsGeo] = useState([]) + const [selectedStation, setSelectedStation] = useState("CS002") + const [bluePrints, setBluePrints] = useState() + const [flatBluePrints, setFlatBluePrints] = useState() + const [selectedBluePrint, setSelectedBluePrint] = useState() + const [selectedBluePrintId, setSelectedBluePrintId] = useState() + const [startTime, setStartTime] = useState(moment().startOf('day').toDate() ) + const [endTime, setEndTime] = useState(moment().endOf('day').add(UIConstants.WEEKVIEW_SHOW_NUMBER_OF_DAYS, 'days').toDate()) + const [map, setMap] = useState() - const [map, setMap] = useState() + async function fetchStations() { + let stationlist = await UtilService.getStations(); + if (stationlist === null) return; + let flatstationList = Object.entries(stationlist) + setStations(flatstationList); + let geostations = MakeGeoJson(stationlist); + setStationsGeo(geostations); + } - async function fetchStations() { - let stationlist = await UtilService.getStations(); - let flatstationList = Object.entries(stationlist) - setStations(flatstationList); - let geostations = MakeGeoJson(stationlist); - setStationsGeo(geostations); + function GetFlatBluePrints() { + return flatBluePrints; + } + + function MakeLabel(prints) { + for (const element of prints) { + const print = element; + print[0] = print[1].name + " - " + print[1].id + " - " + print[1].status } - - - - function generateGeoJson(station, coordinates) { - let name = station; - let longitude = coordinates.longitude; - let latitude = coordinates.latitude; - - return { - type: "Feature", - properties: { - name: name - }, - "geometry": { - "type": "Point", - "coordinates": [ - longitude, - latitude - ] - }, - id: name - } + } + + useEffect(() => { + console.log("startTime", startTime, "endTime", endTime); + + }, [startTime, endTime]); + + + useEffect(() => { + if (selectedBluePrint?.[1]?.id) { + setSelectedBluePrintId("" + selectedBluePrint[1].id) } + }, [selectedBluePrint]); + + function SortBluePrints(prints) { + return prints.sort((a, b) => { + // Compare names + if (a.name < b.name) { + return -1; + } + if (a.name > b.name) { + return 1; + } + // Names are equal + return 0; + }); + + } + + async function fetchBluePrints() { + const from = moment(startTime).format(UIConstants.CALENDAR_DATETIME_FORMAT); + const until = moment(endTime).format(UIConstants.CALENDAR_DATETIME_FORMAT); + const schedulingUnits = await ScheduleService.getTimelineSlimBlueprints(from, until); + let sortedbluePrints = SortBluePrints(schedulingUnits); + setBluePrints(sortedbluePrints); + let flattedBluePrints = Object.entries(sortedbluePrints) + MakeLabel(flattedBluePrints); + setFlatBluePrints(flattedBluePrints); + + } + + function getBluePrintActions() { + return [ + PageHeaderActions.actionDropDownObject("Blue print ", GetFlatBluePrints(), + { callback: (blueprint) => setSelectedBluePrint(blueprint) }, + selectedBluePrint, "station-blueprint-dropdown", undefined, "0","select Blue print" + ), + ] + } + + function navigateToDay(addingDays) { + let newStartTime = new Date(startTime); + newStartTime.setDate(startTime.getDate() + addingDays); + let NewEndTime = new Date(endTime) + NewEndTime.setDate(endTime + addingDays); + setStartTime(newStartTime); + setEndTime(NewEndTime); + } + function getNavigationActions(AddDays) { + return [ + PageHeaderActions.actionButtonObject( + "previous day", + "pi pi-angle-left", + "", + { callback: () => AddDays(-1) } + ), + + PageHeaderActions.actionCalendarObject( + "", + { callback: (date) => setStartTime(date) }, + startTime, + "NoOverride" + ), + PageHeaderActions.actionButtonObject( + "next day", + "pi pi-angle-right", + "", + { callback: () => AddDays(1) } + ), + ]; + } + + + function generateGeoJson(station, coordinates) { + let name = station; + let longitude = coordinates.longitude; + let latitude = coordinates.latitude; - function MakeGeoJson(stations) { - let StationgeojsonArray = [] - for (let station in stations){ - const geostationJson = generateGeoJson(station,stations[station]); - StationgeojsonArray.push(geostationJson); - } - return StationgeojsonArray; - } - - - - function ZoomTo(station) { - let longitude = station[1].longitude; + return { + type: "Feature", + properties: { + name: name + }, + "geometry": { + "type": "Point", + "coordinates": [ + longitude, + latitude + ] + }, + id: name + } + } + + function MakeGeoJson(stations) { + let StationgeojsonArray = [] + for (let station in stations) { + const geostationJson = generateGeoJson(station, stations[station]); + StationgeojsonArray.push(geostationJson); + } + return StationgeojsonArray; + } + + + + function ZoomTo(station) { + let longitude = station[1].longitude; let latitude = station[1].latitude; - map?.setView([latitude,longitude],14); - } - useEffect ( () => { - fetchStations(); - }, []); - - - return <> - - <PageHeader location={location} title={'Stations - List '} - /> - - <TabView> - <TabPanel header="Station Geo Map" className="TabStation"> - <div className="StationListWrap" > - <ListBox options={stations} optionLabel="0" className="StationListbox" onChange={(e) => ZoomTo(e.value)}/> - <StationGeoView stations={stationsGeo } selected={selectedStation} mapRef={ setMap} ></StationGeoView > - </div> - </TabPanel> - <TabPanel header="Station Constraints Plot"> - <div className="StationListWrap" > - <ListBox options={stations} optionLabel="0" className="StationListbox" onChange={(e) => ZoomTo(e.value)}/> - <div> A Contraints view will be implemnted here soon. </div> - </div> - - </TabPanel> - </TabView> + map?.setView([latitude, longitude], 14); + } + + + useEffect(() => { + fetchStations(); + fetchBluePrints(); + }, []); + + + function constrainsSelect(station) { + console.log(station); + + setSelectedStation(...station) + } + + + return <> + + <PageHeader location={location} title={'Stations - List '} actions={getBluePrintActions().concat(getNavigationActions(navigateToDay))} className="defaultpageHeader" /> + <TabView> + <TabPanel header="Station Geo Map" className="TabStation"> + <div className="StationListWrap" > + <ListBox options={stations} optionLabel="0" className="StationListbox" onChange={(e) => ZoomTo(e.value)} /> + <StationGeoView stations={stationsGeo} selected={selectedStation} mapRef={setMap} ></StationGeoView > + </div> + </TabPanel> + <TabPanel header="Station Constraints Plot"> + <div className="StationListWrap" > + <ListBox options={stations} optionLabel="0" className="StationListbox" onChange={(e) => constrainsSelect(e.value)} selected={selectedStation} /> + <StationConstraintView station={selectedStation} stations={stations} selectedBluePrint={selectedBluePrint} selectedBluePrintId={selectedBluePrintId} startTime={moment(startTime).format(UIConstants.CALENDAR_DEFAULTDATE_FORMAT)} ></StationConstraintView> + </div> + + </TabPanel> + </TabView> </> } -StationView.propTypes = { - title: PropTypes.string, + StationView.propTypes = { + title: PropTypes.string, - }; \ No newline at end of file + } \ No newline at end of file diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/SystemEvent/system.event.create.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/SystemEvent/system.event.create.js index dfdf9439dc2..1c8e5d55499 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/SystemEvent/system.event.create.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/SystemEvent/system.event.create.js @@ -931,7 +931,7 @@ export class SystemEventCreate extends Component { <div className="p-breadcrumb footer-long-div actions" > <FormActionbar createAnotherCallBack={this.setCreateAnother} createAnother={this.state.createAnother} tooltip="Select checkbox to create another system event after saving this system event" - onSubmit={this.saveSystemEvent} enableSaveBtn={!this.state.validEditor || !this.state.validForm} onCancel={this.checkIsDirty} /> + onSubmit={this.saveSystemEvent} disableSaveBtn={!this.state.validEditor || !this.state.validForm} onCancel={this.checkIsDirty} /> </div> </> } diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/SystemEvent/system.event.edit.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/SystemEvent/system.event.edit.js index 98c9701c4e2..4bd37b2f0cc 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/SystemEvent/system.event.edit.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/SystemEvent/system.event.edit.js @@ -786,7 +786,7 @@ export class SystemEventEdit extends Component { </div> <div className="p-breadcrumb footer-long-div actions" > <FormActionbar onSubmit={this.updateSystemEvent} - enableSaveBtn={!this.state.validEditor || !this.state.validForm} onCancel={this.checkIsDirty} /> + disableSaveBtn={!this.state.validEditor || !this.state.validForm} onCancel={this.checkIsDirty} /> </div> </div> </React.Fragment> diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/edit.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/edit.js index f3e4c38fe43..29055b22682 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/edit.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/edit.js @@ -283,9 +283,11 @@ export class TaskEdit extends Component { }); } + + const isSaveDisabled = !this.state.validEditor || !this.state.validForm || !this.state.validDocument; return ( <React.Fragment> - {this.state.userrole[this.state.taskId] && this.state.userrole[this.state.taskId].edit ? + {this.state.userrole[this.state.taskId]?.edit ? <> <Toast ref={(el) => this.growl = el} /> <PageHeader location={this.props.location} title={'Task - Edit'} actions={[{ @@ -360,7 +362,7 @@ export class TaskEdit extends Component { </div> <div className="p-breadcrumb footer-long-div actions"> <FormActionbar onSubmit={this.saveTask} - enableSaveBtn={!this.state.validEditor || !this.state.validForm || !this.state.validDocument} onCancel={this.checkIsDirty} /> + disableSaveBtn={isSaveDisabled} onCancel={this.checkIsDirty} /> </div> <div className="p-grid" data-testid="confirm_dialog"> <CustomDialog type="confirmation" visible={this.state.showDialog} width="40vw" diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/edit.test.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/edit.test.js index 56100573a50..a3feb9fba1f 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/edit.test.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/edit.test.js @@ -6,7 +6,6 @@ import mockConsole from 'jest-mock-console' import _ from 'lodash'; import { TaskEdit } from './edit'; import TaskService from '../../services/task.service'; -import UtilService from '../../services/util.service'; import TaskServiceMock from '../../__mocks__/task.service.data'; import AuthService from '../../services/auth.service'; import AuthServiceMock from '../../__mocks__/auth.service.data'; @@ -63,11 +62,10 @@ const setMockSpy = ( () => { taskTemplateSpy = jest.spyOn(TaskService, 'getTaskTemplate'); taskTemplateSpy.mockImplementation((templateId) => { let template = _.find(TaskServiceMock.getTaskTemplates(), {"id":templateId}); - return Promise.resolve(template); - //let resolvedtemplate = UtilService.resolveSchema(template); + template.definitions = template.ref_resolved_schema.definitions; + template.properties = template.ref_resolved_schema?.properties; - //return resolvedtemplate - // + return Promise.resolve(template); }); taskTemplatesSpy = jest.spyOn(TaskService, 'getTaskTemplates'); @@ -76,7 +74,7 @@ const setMockSpy = ( () => { }); schedulingUnitSpy = jest.spyOn(TaskService, "getSchedulingUnit"); - schedulingUnitSpy.mockImplementation((type, id, loadTasks) => { + schedulingUnitSpy.mockImplementation((type, id ) => { if (type === "draft") { return Promise.resolve(_.find(TaskServiceMock.schedulingUnitDrafts, {"id": id})); } else { diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/helpers/week.view.helper.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/helpers/week.view.helper.js index e4e175cd86e..0b99eb87947 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/helpers/week.view.helper.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/helpers/week.view.helper.js @@ -3,6 +3,7 @@ import moment from "moment/moment"; import UtilService from "../../../services/util.service"; import { getTimelineGroups } from "../business/timelinegroupingbusiness.js"; import UIConstants from "../../../utils/ui.constants.js"; +import PageHeaderActions from "../../../utils/pageheaderactions.util.js"; import { fetchLSTStationShift } from "../data/week.view.data.js" @@ -28,57 +29,30 @@ export async function updateSchedulerStatuses(switchValue, status, setSchedulerS } } -const actionObject = (title, icon, classes, className, callbackProp, content, type, actOn, options, selected) => ({ - title: title, - icon: icon, - classes: classes, - className: className, - content: content, - type: type, - actOn: actOn, - props: callbackProp, - options: options, - selected: selected -}) - -const actionButtonObject = (title, icon, classes, callbackProp) => ( - actionObject(title, icon, classes, undefined, callbackProp, undefined, "buttonv2", "click", undefined, undefined) -) - -const actionTagObject = (title, content, className) => ( - actionObject(title, undefined, undefined, className, undefined, content, "tagv2", "click", undefined, undefined) -) - -const actionDropDownObject = (title, options, callbackProp, selected, classes) => ( - actionObject(title, undefined, classes, undefined, callbackProp, undefined, "dropdown", "select", options, selected) -) - -const actionDivider = (title) => ( - actionObject(title, undefined, undefined, undefined, undefined, undefined, "divider", undefined, undefined, undefined) -) + export function getHeaderActions(isLoading, setRefetchToggle, actionsMenuRef, isExpanded, setIsExpanded, isLegendVisible, setIsLegendVisable) { return [ - actionButtonObject( + PageHeaderActions.actionButtonObject( isLoading ? "System is already reloading the timeline data" : "Reload the timeline data", (isLoading ? "pi-spin pi-hourglass " : "pi-sync"), `subsystem subsystem--${isLoading ? "on" : "standard"}`, { callback: () => setRefetchToggle(prevState => !prevState) } ), - actionButtonObject( + PageHeaderActions.actionButtonObject( "Options", "pi-bars", "", { callback: (ev) => actionsMenuRef.current.toggle(ev) } ), - actionButtonObject( + PageHeaderActions.actionButtonObject( (isLegendVisible ? "Hide Legend" : "Show Legend"), (isLegendVisible ? "pi-bookmark" : "pi-bookmark-fill"), (isLegendVisible ? "" : "color:grey"), { callback: () => setIsLegendVisable(prevState => !prevState) } ), - actionButtonObject( + PageHeaderActions.actionButtonObject( (isExpanded ? "Hide Filters" : "Show Filter"), (isExpanded ? "pi-chevron-up" : "pi-chevron-down"), "", @@ -95,12 +69,12 @@ export function getHeaderActions(isLoading, setRefetchToggle, actionsMenuRef, is */ export function getGroupedByActions(selected, setGroupedBy) { return [ - actionDropDownObject( + PageHeaderActions.actionDropDownObject( "Group By", getTimelineGroups(), { callback: (groupingby) => setGroupedBy(groupingby) }, selected, - "timeline-header-dropdown" + "timeline-header-dropdown","value","label" ), ] @@ -108,36 +82,36 @@ export function getGroupedByActions(selected, setGroupedBy) { export function getNavigationActions(AddWeeks) { return [ - actionButtonObject( + PageHeaderActions.actionButtonObject( "previous 7 days", "pi pi-angle-double-left", "", { callback: () => AddWeeks(-1) } ), - actionButtonObject( + PageHeaderActions.actionButtonObject( "next 7 days", "pi pi-angle-double-right", "", { callback: () => AddWeeks(1) } ), - actionDivider("navigationbreaker") + PageHeaderActions.actionDivider("navigationbreaker") ]; } export function getSchedulerActions(schedulerSettings, setShowSchedulerSettingsDialog) { return [ - actionTagObject( + PageHeaderActions.actionTagObject( schedulerSettings.isDynamicSchedulerOn ? "Dynamic Scheduling is On" : "Dynamic Scheduling is Off", "D", "tag tag--" + (schedulerSettings.isDynamicSchedulerOn ? "on" : "off") ), - actionTagObject( + PageHeaderActions.actionTagObject( schedulerSettings.isFixedTimeSchedulerOn ? "Fixed time Scheduling is On" : "Fixed time Scheduling is Off", "F", "tag tag--" + (schedulerSettings.isFixedTimeSchedulerOn ? "on" : "off") ), - actionButtonObject( + PageHeaderActions.actionButtonObject( (schedulerSettings.isDynamicSchedulerActive ? "Dynamic Scheduler is Active" : (schedulerSettings.isDynamicSchedulerOn ? "Dynamic Scheduler is Idle" : "Dynamic Scheduler is stopped")) + ". Click to change the scheduler", "pi-" + (schedulerSettings.isDynamicSchedulerActive ? "play" : (schedulerSettings.isDynamicSchedulerOn ? "pause" : "stop")), diff --git a/SAS/TMSS/frontend/tmss_webapp/src/services/schedule.service.js b/SAS/TMSS/frontend/tmss_webapp/src/services/schedule.service.js index df3f61cfee1..4b49d2ac503 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/services/schedule.service.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/services/schedule.service.js @@ -65,6 +65,36 @@ const SU_FETCH_FIELDS = ["id", "task_blueprints.subtasks.primary"]; const ScheduleService = { + + + /** + * Function to give back a scheduling constraint url + * @param {string} station - The Station + * @param {string} schedulingUnit - the Unit we are looking at + * @param {string} onDate - 2023-02-14 formatedf formated of the date + * @returns string with the url + */ + getConstraintImgForStationAndSchedulingUnitOnDate : async function(station,schedulingUnit,onDate) { + + if (station===undefined) return; + if (schedulingUnit===undefined) return; + if (onDate===undefined) return; + try { + let imageurl = "/api/scheduling_unit_blueprint/" + schedulingUnit + "/scheduling_constraints_plot/" + station + "/" + onDate + const response = await axios.get( + imageurl, + { + responseType: "blob", + } + ); + // Convert the blob to a data URL + const dataUrl = URL.createObjectURL(response.data); + return dataUrl; + } catch (error) { + console.error("Error fetching image:", error); + } + + }, getExpandedSchedulingUnit: async function (type, id, expand, fields) { let schedulingUnit = null; try { @@ -1107,6 +1137,7 @@ const ScheduleService = { console.error(error); } }, + } export default ScheduleService; diff --git a/SAS/TMSS/frontend/tmss_webapp/src/utils/externalurls.js b/SAS/TMSS/frontend/tmss_webapp/src/utils/externalurls.js index f36ccd799e7..dad2b8e386e 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/utils/externalurls.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/utils/externalurls.js @@ -4,16 +4,7 @@ const ExternalUrlsUtils = { BaseLofarMonitorUrl : "https://proxy.lofar.eu/lofmonitor/station_overview?station=", - /** - * Function to give back a scheduling constraint url - * @param {string} Station - The Station - * @param {string} schedulingUnit - the Unit we are looking at - * @param {string} onDate - 2023-02-14 formatedf formated of the date - * @returns string with the url - */ - getUserRolePermissionForStationAndSchedulingUnitOnDate(station,schedulingUnit,onDate) { - return "/api/scheduling_unit_blueprint/" + schedulingUnit + "/scheduling_constraints_plot/" + station + "/" + onDate - }, + /** * Function to give back the Lofar Monitoring Url diff --git a/SAS/TMSS/frontend/tmss_webapp/src/utils/externalurls.test.js b/SAS/TMSS/frontend/tmss_webapp/src/utils/externalurls.test.js index 356d6d89fe3..b0ef3d9f1f4 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/utils/externalurls.test.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/utils/externalurls.test.js @@ -7,10 +7,3 @@ describe('getLofarMontitorUrlForStation', () => { }) }); -describe('getUserRolePermissionForStationAndSchedulingUnitOnDate', () => { - it('should return the correct url', () => { - const subbandString = externalUrls.getUserRolePermissionForStationAndSchedulingUnitOnDate("CS003", 21, "1976-08-06") - expect(subbandString).toEqual("/api/scheduling_unit_blueprint/21/scheduling_constraints_plot/CS003/1976-08-06") - - }) -}); \ No newline at end of file diff --git a/SAS/TMSS/frontend/tmss_webapp/src/utils/pageheaderactions.util.js b/SAS/TMSS/frontend/tmss_webapp/src/utils/pageheaderactions.util.js new file mode 100644 index 00000000000..0aa516fbe33 --- /dev/null +++ b/SAS/TMSS/frontend/tmss_webapp/src/utils/pageheaderactions.util.js @@ -0,0 +1,46 @@ +const PageHeaderActions = { + actionObject(title, icon, classes, className, callbackProp, content, type, actOn, options, selected,optionvalue,optionlabel,optionSelectionLabel) { + return { + title: title, + icon: icon, + classes: classes, + className: className, + content: content, + type: type, + actOn: actOn, + props: callbackProp, + options: options, + selected: selected, + optionvalue: optionvalue, + optionlabel:optionlabel, + optionSelectionLabel:optionSelectionLabel + } + }, + + +actionButtonObject(title, icon, classes, callbackProp) { + return this.actionObject(title, icon, classes, undefined, callbackProp, undefined, "buttonv2", "click", undefined, undefined,undefined,undefined); +}, + + +actionTagObject(title, content, className) { + return this.actionObject(title, undefined, undefined, className, undefined, content, "tagv2", "click", undefined, undefined,undefined,undefined); +}, + + +actionDropDownObject(title, options, callbackProp, selected, classes,optionvalue ,optionlabel ,optionSelectionLabel) { + + + return this.actionObject(title, undefined, classes, undefined, callbackProp, undefined, "dropdown", "select", options, selected,optionvalue,optionlabel,optionSelectionLabel); +}, + +actionCalendarObject(title, callbackProp, selected, classes) { + return this.actionObject(title, undefined, classes, classes, callbackProp, undefined, "calendar", "select", undefined, selected,undefined,undefined); +}, +actionDivider(title) { + return this.actionObject(title, undefined, undefined, undefined, undefined, undefined, "divider", undefined, undefined, undefined,undefined,undefined); +} + +}; + +export default PageHeaderActions; \ No newline at end of file -- GitLab