diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Simulator/index.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Simulator/index.js new file mode 100644 index 0000000000000000000000000000000000000000..48f5b5d985c7c7a4324a87e748cc3a2aa9a46cb0 --- /dev/null +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Simulator/index.js @@ -0,0 +1,65 @@ +import React, { Component } from 'react'; + +import SimulatorService from "../../services/simulator.service"; + +export class Simulator extends Component { + + constructor(props) { + super(props); + this.state = { + status: "Simulating...", + updateStatus: [] + } + } + + componentDidMount() { + this.simulate(this.props.match.params.id); + } + + async simulate(subId) { + const subStatus = await SimulatorService.simulateSUB(subId); + console.log(subStatus); + this.setState({status: "Simulation Completed", updateStatus: subStatus.taskStatus}); + } + + render() { + return ( + <div> + {this.state.status} + <h3 style={{marginTop: "10px"}}>Task Status Update Log</h3> + <div className="p-grid" style={{marginTop: "10px", border: "1px solid", backgroundColor: "lightgrey"}}> + <div className="p-col-2" style={{border: "1px solid"}}>Task Id</div> + <div className="p-col-2" style={{border: "1px solid"}}>Task Name</div> + <div className="p-col-8" style={{border: "1px solid"}}> + <div className="p-grid" style={{border: "1px solid"}}> + <div className="p-col-4" style={{border: "1px solid"}}>Subtask Id</div> + <div className="p-col-4" style={{border: "1px solid"}}>Subtask State</div> + <div className="p-col-4" style={{border: "1px solid"}}>Update Status</div> + </div> + </div> + </div> + {this.state.updateStatus.length>0 && this.state.updateStatus.map((task, index) => ( + <React.Fragment key={index+10}> + <div key={"task_" + index} className="p-grid" style={{border: "1px solid"}}> + <div key={"task_id_" + index} className="p-col-2" style={{border: "1px solid"}}>{task.id}</div> + <div key={"task_name_" + index} className="p-col-2" style={{border: "1px solid"}}>{task.name}</div> + <div key={"subtasks_" + index} className="p-col-8" style={{border: "1px solid"}}> + {task.subtaskStatus.length>0 && task.subtaskStatus.map((subtask, sindex) => ( + <React.Fragment key={index+"_"+sindex}> + <div key={"subtask_" + index + "_" + sindex} className="p-grid" style={{border: "1px solid"}}> + <div key={"subtask_id_" + index + "_" + sindex} className="p-col-4" style={{border: "1px solid"}}>{subtask.id}</div> + <div key={"subtask_state_" + index + "_" + sindex} className="p-col-4" style={{border: "1px solid"}}>{subtask.state}</div> + <div key={"subtask_status_" + index + "_" + sindex} className="p-col-4" style={{border: "1px solid"}}>{subtask.status}</div> + </div> + </React.Fragment> + ))} + </div> + </div> + </React.Fragment> + ))} + </div> + ); + } +} + +export default Simulator; \ No newline at end of file diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/index.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/index.js index 40f74503d596ad7393b9ee135b4303485f7bab0d..accbe4200666a30904d906aa298e9edaf7c037ec 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/index.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/index.js @@ -19,6 +19,7 @@ import { ReservationCreate, ReservationList, ReservationView, ReservationEdit } import { FindObjectResult } from './Search/' import SchedulingSetCreate from './Scheduling/excelview.schedulingset'; import Workflow from './Workflow'; +import Simulator from './Simulator/index'; import ReportHome from './Report'; import { Growl } from 'primereact/components/growl/Growl'; import { setAppGrowl } from '../layout/components/AppGrowl'; @@ -188,6 +189,12 @@ export const routes = [ name: 'Find Object', title: 'Find Object' }, + { + path: "/schedulingunit/simulate/:id", + component: Simulator, + name: 'Scheduling Unit Simulator', + title: 'Scheduling Unit Simulator' + }, { path: "/workflow", component: WorkflowList, diff --git a/SAS/TMSS/frontend/tmss_webapp/src/services/simulator.service.js b/SAS/TMSS/frontend/tmss_webapp/src/services/simulator.service.js new file mode 100644 index 0000000000000000000000000000000000000000..2313fe0d0475587d810e8e7a44d5afc4ab6943dd --- /dev/null +++ b/SAS/TMSS/frontend/tmss_webapp/src/services/simulator.service.js @@ -0,0 +1,77 @@ +import _ from 'lodash'; +import ScheduleService from './schedule.service'; +import TaskService from './task.service'; + +const axios = require('axios'); +const finalStatuses = ['finished', 'error', 'cancelled', 'unschedulable']; +const subtaskStatuses = ['defining', 'defined', 'scheduling', 'scheduled', + 'starting', 'started', 'finishing', 'finished']; + +const SimulatorService = { + simulateSUB: async function(id) { + let subStatus = {taskStatus: []}; + let suUpdateStatus = "success"; + try { + const suBlueprint = await ScheduleService.getSchedulingUnitExtended('blueprint', id, true); + if (suBlueprint && finalStatuses.indexOf(suBlueprint.status)<0) { + const subtaskStates = await this.getSubtaskStates(); + const taskBlueprints = _.sortBy(suBlueprint.task_blueprints, ['id']) + for (const taskBP of taskBlueprints) { + let taskBPStatus = {id: taskBP.id, name: taskBP.name, subtaskStatus:[]}; + const subtasks = _.sortBy(taskBP.subtasks, ['id']); + let taskUpdateStatus = "success"; + for (let subtask of subtasks) { + let subtaskUpdateStatus = "success"; + subtask = await TaskService.getSubtaskDetails(subtask.id); + taskBPStatus.subtaskStatus.push({id: subtask.id, state: subtask.state_value, status: "-"}); + while (finalStatuses.indexOf(subtask.state_value)<0) { + let subtaskStatus = {id: subtask.id, name: subtask.name}; + let statusIndex = subtaskStatuses.indexOf(subtask.state_value); + subtask.state_value = subtaskStatuses[statusIndex+1]; + const subtaskState = _.find(subtaskStates, ['value', subtask.state_value]); + subtask.state = subtaskState.url; + let currentUpdateStatus = await this.updateSubtask(subtask); + subtaskStatus.state = subtask.state_value; + subtaskStatus.status = currentUpdateStatus; + taskBPStatus.subtaskStatus.push(subtaskStatus); + subtaskUpdateStatus = currentUpdateStatus; + if (currentUpdateStatus === "failed") { + break; + } + } + taskUpdateStatus = subtaskUpdateStatus; + if (subtaskUpdateStatus === "failed") { + break; + } + } + subStatus.taskStatus.push(taskBPStatus); + if (taskUpdateStatus === "failed") { + break; + } + } + } + } catch (error) { + console.error(error); + } + return subStatus; + }, + updateSubtask: async(subtask) => { + try { + const response = await axios.put(`/api/subtask/${subtask.id}/`, subtask); + return "success"; + } catch (error) { + console.log(error); + return "failed"; + } + }, + getSubtaskStates: async() => { + try { + const response = await axios.get(`/api/subtask_state/`); + return response.data.results; + } catch (error) { + console.log(error); + } + } +} + +export default SimulatorService; \ No newline at end of file