diff --git a/SAS/TMSS/frontend/tmss_webapp/src/components/ViewTable.js b/SAS/TMSS/frontend/tmss_webapp/src/components/ViewTable.js index a9bd822854a2a0899fa51477c09df4873bc2bea2..1544f03d3077e8e1f3abbb4727b5cc15f39fe548 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/components/ViewTable.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/components/ViewTable.js @@ -1157,8 +1157,10 @@ function dateFilterFn(rows, id, filterValue) { function dateRangeFilterFn(rows, id, filterValue) { const filteredRows = _.filter(rows, function (row) { // If cell value is null or empty - if (!row.values[id]) { + if (filterValue.length>0 && !row.values[id]) { return false; + } else if (!row.values[id]) { + return true; } //Remove microsecond if value passed is UTC string in format "YYYY-MM-DDTHH:mm:ss.sssss" let rowValue = moment.utc(row.values[id].split('.')[0]); diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js index 9d081a10cc2562ee31f8a6ef4ce7089bada529c5..11256e2133f779db96941a9d0b682d6617baa41e 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js @@ -45,13 +45,23 @@ class SchedulingUnitList extends Component{ scheduling_set: {name: "Scheduling Set",}, observation_strategy_template_name: {name: "Template Name"}, observation_strategy_template_description: {name: "Template Description"}, - start_time:{ - name:"Start Time", + on_sky_start_time:{ + name:"Observation Start Time", filter:"flatpickrDateRange", format:UIConstants.CALENDAR_DATETIME_FORMAT }, - stop_time:{ - name:"End Time", + on_sky_stop_time:{ + name:"Observation End Time", + filter:"flatpickrDateRange", + format:UIConstants.CALENDAR_DATETIME_FORMAT + }, + process_start_time:{ + name:"Process Start Time", + filter:"flatpickrDateRange", + format:UIConstants.CALENDAR_DATETIME_FORMAT + }, + process_stop_time:{ + name:"Process End Time", filter:"flatpickrDateRange", format:UIConstants.CALENDAR_DATETIME_FORMAT }, @@ -95,8 +105,10 @@ class SchedulingUnitList extends Component{ "Template ID", "Template Name", "Template Description", - "Start Time", - "End Time", + "Observation Start Time", + "Observation End Time", + "Process Start Time", + "Process End Time", "Duration (HH:mm:ss)", "Prevent Autodeletion", "Stations (CS/RS/IS)", @@ -152,8 +164,10 @@ class SchedulingUnitList extends Component{ "Stations (CS/RS/IS)":"filter-input-50", "Tasks content (O/P/I)":"filter-input-50", "Number of SAPs in the target observation":"filter-input-50", - "Start Time":"filter-input-150", - "End Time":"filter-input-150", + "Observation Start Time":"filter-input-150", + "Observation End Time":"filter-input-150", + "Process Start Time":"filter-input-150", + "Process End Time":"filter-input-150", "Created_At":"filter-input-150", "Updated_At":"filter-input-150", "Template ID":"filter-input-75", @@ -369,8 +383,8 @@ class SchedulingUnitList extends Component{ * Get server side filter column details form API */ async getFilterColumns(type) { - const columnOrderToBeRemove = ['Status', 'Workflow Status', 'Start Time', 'End Time']; - const columnDefinitionToBeRemove = ['status', 'workflowStatus', 'start_time', 'stop_time']; + const columnOrderToBeRemove = ['Status', 'Workflow Status', 'Observation Start Time', 'Observation End Time', 'Process Start Time', 'Process End Time' ]; + const columnDefinitionToBeRemove = ['status', 'workflowStatus', 'on_sky_start_time', 'on_sky_stop_time', 'process_start_time', 'process_stop_time']; const suFilters = await ScheduleService.getSchedulingUnitFilterDefinition(type); this.columnMap = []; let tmpDefaulColumns = _.cloneDeep(this.state.defaultcolumns[0]); @@ -1142,21 +1156,37 @@ class SchedulingUnitList extends Component{ let filters = UtilService.localStore({ type: 'get', key: "scheduleunit_list_"+this.state.suType }); if(filters.length > 0 ) { for( const filter of filters) { - if (filter.id === 'Start Time') { + if (filter.id === 'Observation Start Time') { + const values = filter.value; + if (values[0]) { + this.filterQry += 'on_sky_start_time_after='+ moment(new Date(values[0])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; + } + if (values[1]) { + this.filterQry += 'on_sky_start_time_before='+moment(new Date(values[1])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; + } + } else if (filter.id === 'Observation End Time') { + const values = filter.value; + if (values[0]) { + this.filterQry += 'on_sky_stop_time_after='+ moment(new Date(values[0])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; + } + if (values[1]) { + this.filterQry += 'on_sky_stop_time_before='+moment(new Date(values[1])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; + } + } else if (filter.id === 'Process Start Time') { const values = filter.value; if (values[0]) { - this.filterQry += 'start_time_after='+ moment(new Date(values[0])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; + this.filterQry += 'process_start_time_after='+ moment(new Date(values[0])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; } if (values[1]) { - this.filterQry += 'start_time_before='+moment(new Date(values[1])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; + this.filterQry += 'process_start_time_before='+moment(new Date(values[1])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; } - } else if (filter.id === 'End Time') { + } else if (filter.id === 'Process End Time') { const values = filter.value; if (values[0]) { - this.filterQry += 'stop_time_after='+ moment(new Date(values[0])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; + this.filterQry += 'process_stop_time_after='+ moment(new Date(values[0])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; } if (values[1]) { - this.filterQry += 'stop_time_before='+moment(new Date(values[1])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; + this.filterQry += 'process_stop_time_before='+moment(new Date(values[1])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; } } else if ((filter.id === 'Scheduling Unit ID' || filter.id === 'Linked Draft ID') && filter.value != '') { let columnDetails = _.find(this.state.columnMap, {displayName:filter.id}); diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js index 481f1ec388c9ff1c0552d197cdb9563d909eae7e..92760509bd87567bd3e3c6894ee7bb5bc74ef898 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js @@ -61,8 +61,10 @@ class ViewSchedulingUnit extends Component { "Control ID", "Name", "Description", - "Start Time", - "End Time", + "Observation Start Time", + "Observation End Time", + "Process Start Time", + "Process End Time", "Duration (HH:mm:ss)", "Relative Start Time (HH:mm:ss)", "Relative End Time (HH:mm:ss)", @@ -78,7 +80,10 @@ class ViewSchedulingUnit extends Component { "Updated at" ], defaultcolumns: [{ - status_logs: "Status Logs", + status_logs: { + name: "Status Logs", + filter: 'none' + }, status: { name: "Status", filter: "select" @@ -91,15 +96,25 @@ class ViewSchedulingUnit extends Component { subTaskID: 'Control ID', name: "Name", description: "Description", - start_time: { - name: "Start Time", - filter: "date", - format: UIConstants.CALENDAR_DATETIME_FORMAT + on_sky_start_time: { + name: "Observation Start Time", + filter:"flatpickrDateRange", + format:UIConstants.CALENDAR_DATETIME_FORMAT }, - stop_time: { - name: "End Time", - filter: "date", - format: UIConstants.CALENDAR_DATETIME_FORMAT + on_sky_stop_time: { + name: "Observation End Time", + filter:"flatpickrDateRange", + format:UIConstants.CALENDAR_DATETIME_FORMAT + }, + process_start_time: { + name: "Process Start Time", + filter:"flatpickrDateRange", + format:UIConstants.CALENDAR_DATETIME_FORMAT + }, + process_stop_time: { + name: "Process End Time", + filter:"flatpickrDateRange", + format:UIConstants.CALENDAR_DATETIME_FORMAT }, duration: { name: "Duration (HH:mm:ss)", @@ -140,6 +155,10 @@ class ViewSchedulingUnit extends Component { "Cancelled": "filter-input-50", "Duration (HH:mm:ss)": "filter-input-75", "Template ID": "filter-input-50", + "Observation Start Time":"filter-input-150", + "Observation End Time":"filter-input-150", + "Process Start Time":"filter-input-150", + "Process End Time":"filter-input-150", // "BluePrint / Task Draft link": "filter-input-100", "Relative Start Time (HH:mm:ss)": "filter-input-75", "Relative End Time (HH:mm:ss)": "filter-input-75", @@ -253,7 +272,7 @@ class ViewSchedulingUnit extends Component { this.setToggleBySorting(); let schedule_id = this.props.match.params.id; let schedule_type = this.props.match.params.type; - const permissionById = await AuthUtil.getUserPermissionByModuleId(schedule_type === 'blueprint'? 'scheduling_unit_blueprint': 'scheduling_unit_draft', schedule_id); + const permissionById = await AuthUtil.getUserPermissionByModuleId(schedule_type === 'blueprint'? 'scheduling_unit_blueprint': 'scheduling_unit_draft', schedule_id) this.setState({userPermission: permission, permissionById: permissionById, schedule_id: schedule_id}); if (schedule_type && schedule_id) { this.stations = await ScheduleService.getStationGroup(); @@ -376,8 +395,8 @@ class ViewSchedulingUnit extends Component { } async getFilterColumns(type) { - const columnOrderToRemove = type === 'blueprint' ?[] :['Status', 'Status Logs', 'Start Time', 'End Time', 'Control ID','#Dataproducts', 'Data Size', 'Data Size on Disk', 'Subtask Content']; - const columnDefinitionToRemove = type === 'blueprint' ?['scheduling_unit_draft']:['scheduling_unit_blueprint', 'status', 'status_logs', 'start_time', 'stop_time', 'subTaskID','noOfOutputProducts','size','dataSizeOnDisk','subtaskContent']; + const columnOrderToRemove = type === 'blueprint' ?[] :['Status', 'Status Logs', 'Observation Start Time', 'Observation End Time', 'Process Start Time', 'Process End Time', 'Control ID','#Dataproducts', 'Data Size', 'Data Size on Disk', 'Subtask Content']; + const columnDefinitionToRemove = type === 'blueprint' ?['scheduling_unit_draft']:['scheduling_unit_blueprint', 'status', 'status_logs', 'on_sky_start_time', 'on_sky_stop_time', 'process_start_time', 'process_stop_time', 'subTaskID','noOfOutputProducts','size','dataSizeOnDisk','subtaskContent']; let tmpDefaulColumns = _.cloneDeep(this.state.defaultcolumns[0]); let tmpOptionalColumns = _.cloneDeep(this.state.optionalcolumns[0]); tmpOptionalColumns.blueprint_draft = this.props.match.params.type==="draft"?"Linked Blueprint": "Linked Draft" @@ -479,7 +498,7 @@ class ViewSchedulingUnit extends Component { async getFormattedTaskDrafts(schedulingUnit) { let scheduletasklist = []; // Common keys for Task and Blueprint - let commonkeys = ['id', 'created_at', 'description', 'name', 'tags', 'updated_at', 'url', 'do_cancel', 'relative_start_time', 'relative_stop_time', 'start_time', 'stop_time', 'duration', 'status']; + let commonkeys = ['id', 'created_at', 'description', 'name', 'tags', 'updated_at', 'url', 'do_cancel', 'relative_start_time', 'relative_stop_time', 'on_sky_start_time', 'on_sky_stop_time', 'process_start_time', 'process_stop_time', 'duration', 'status']; for (const task of schedulingUnit.task_drafts) { let scheduletask = {}; scheduletask['tasktype'] = 'Draft'; @@ -1317,12 +1336,13 @@ class ViewSchedulingUnit extends Component { <label className="col-lg-2 col-md-2 col-sm-12">Updated At</label> <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.created_at && moment(this.state.scheduleunit.updated_at, moment.ISO_8601).format(UIConstants.CALENDAR_DATETIME_FORMAT)}</span> </div> + {this.props.match.params.type === 'blueprint' && <div className="p-grid"> - <label className="col-lg-2 col-md-2 col-sm-12">Start Time</label> - <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.start_time && moment(this.state.scheduleunit.start_time).format(UIConstants.CALENDAR_DATETIME_FORMAT)}</span> - <label className="col-lg-2 col-md-2 col-sm-12">End Time</label> - <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.stop_time && moment(this.state.scheduleunit.stop_time).format(UIConstants.CALENDAR_DATETIME_FORMAT)}</span> - </div> + <label className="col-lg-2 col-md-2 col-sm-12">Observation Start Time</label> + <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.on_sky_start_time && moment(this.state.scheduleunit.on_sky_start_time).format(UIConstants.CALENDAR_DATETIME_FORMAT)}</span> + <label className="col-lg-2 col-md-2 col-sm-12">Observation End Time</label> + <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.on_sky_stop_time && moment(this.state.scheduleunit.on_sky_stop_time).format(UIConstants.CALENDAR_DATETIME_FORMAT)}</span> + </div>} <div className="p-grid"> <label className="col-lg-2 col-md-2 col-sm-12" >Duration (HH:mm:ss)</label> <span className="col-lg-4 col-md-4 col-sm-12">{moment.utc((this.state.scheduleunit.duration ? this.state.scheduleunit.duration : 0) * 1000).format(UIConstants.CALENDAR_TIME_FORMAT)}</span> @@ -1426,7 +1446,6 @@ class ViewSchedulingUnit extends Component { </span> </div> </div> - {this.state.isLoading ? <AppLoader /> : (this.state.schedulingUnitTasks.length > 0) ? <ViewTable data={this.state.schedulingUnitTasks} diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/list.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/list.js index 092c08eee35c1f03eb78fdffbd0ce6a8439f0521..1e3ddf44003f34118847dd2ac10637c27b6b0e34 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/list.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/list.js @@ -53,8 +53,10 @@ export class TaskList extends Component { "Control ID", "Name", "Description", - "Start Time", - "End Time", + "Observation Start Time", + "Observation End Time", + "Process Start Time", + "Process End Time", "Duration (HH:mm:ss)", "Relative Start Time (HH:mm:ss)", "Relative End Time (HH:mm:ss)", @@ -106,13 +108,23 @@ export class TaskList extends Component { description: { name:"Description" }, - start_time: { - name: "Start Time", + on_sky_start_time: { + name: "Observation Start Time", filter: "flatpickrDateRange", format: UIConstants.CALENDAR_DATETIME_FORMAT }, - stop_time: { - name: "End Time", + on_sky_stop_time: { + name: "Observation End Time", + filter: "flatpickrDateRange", + format: UIConstants.CALENDAR_DATETIME_FORMAT + }, + process_start_time: { + name: "Process Start Time", + filter: "flatpickrDateRange", + format: UIConstants.CALENDAR_DATETIME_FORMAT + }, + process_stop_time: { + name: "Process End Time", filter: "flatpickrDateRange", format: UIConstants.CALENDAR_DATETIME_FORMAT }, @@ -182,8 +194,10 @@ export class TaskList extends Component { "Linked Draft ID": "filter-input-75", "Relative Start Time (HH:mm:ss)": "filter-input-75", "Relative End Time (HH:mm:ss)": "filter-input-75", - "Start Time": "filter-input-150", - "End Time": "filter-input-150", + "Observation Start Time": "filter-input-150", + "Observation End Time": "filter-input-150", + "Process Start Time": "filter-input-150", + "Process End Time": "filter-input-150", "Status": "filter-input-125", "#Dataproducts": "filter-input-75", "Data size": "filter-input-50", @@ -265,7 +279,7 @@ export class TaskList extends Component { getFormattedTaskDrafts(tasks) { let scheduletasklist = []; // Common keys for Task and Blueprint - let commonkeys = ['id', 'created_at', 'description', 'name', 'tags', 'updated_at', 'url', 'do_cancel', 'relative_start_time', 'relative_stop_time', 'start_time', 'stop_time', 'duration', 'status']; + let commonkeys = ['id', 'created_at', 'description', 'name', 'tags', 'updated_at', 'url', 'do_cancel', 'relative_start_time', 'relative_stop_time', 'on_sky_start_time', 'on_sky_stop_time', 'process_start_time', 'process_stop_time', 'duration', 'status']; for (const task of tasks) { let scheduletask = {}; scheduletask['tasktype'] = 'Draft'; @@ -615,8 +629,8 @@ export class TaskList extends Component { */ async getFilterColumns(type) { const taskFilters = await TaskService.getTaskFilterDefinition(type); - const columnOrderToRemove = this.state.taskType === 'Blueprint' ?[] :['Status', 'Status Logs', 'Start Time', 'End Time', 'Control ID','#Dataproducts', 'Data Size', 'Data Size on Disk', 'Subtask Content']; - const columnDefinitionToRemove = this.state.taskType === 'Blueprint' ?['scheduling_unit_draft']:['scheduling_unit_blueprint', 'status', 'status_logs', 'start_time', 'stop_time', 'subTaskID','noOfOutputProducts','size','dataSizeOnDisk','subtaskContent']; + const columnOrderToRemove = this.state.taskType === 'Blueprint' ?[] :['Status', 'Status Logs', 'Observation Start Time', 'Observation End Time', 'Process Start Time', 'Process End Time', 'Control ID','#Dataproducts', 'Data Size', 'Data Size on Disk', 'Subtask Content']; + const columnDefinitionToRemove = this.state.taskType === 'Blueprint' ?['scheduling_unit_draft']:['scheduling_unit_blueprint', 'status', 'status_logs', 'on_sky_start_time', 'on_sky_stop_time', 'process_start_time', 'process_stop_time','subTaskID','noOfOutputProducts','size','dataSizeOnDisk','subtaskContent']; this.columnMap = []; let tmpDefaulColumns = _.cloneDeep(this.state.defaultcolumns[0]); let tmpOptionalColumns = _.cloneDeep(this.state.optionalcolumns[0]); @@ -784,21 +798,37 @@ export class TaskList extends Component { let filters = UtilService.localStore({ type: 'get', key: "su_task_list_"+this.state.taskType }); if(filters.length > 0 ) { for( const filter of filters) { - if (filter.id === 'Start Time') { + if (filter.id === 'Observation Start Time') { + const values = filter.value; + if (values[0]) { + this.filterQry += 'on_sky_start_time_after='+ moment(new Date(values[0])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; + } + if (values[1]) { + this.filterQry += 'on_sky_start_time_before='+moment(new Date(values[1])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; + } + } else if (filter.id === 'Observation End Time') { + const values = filter.value; + if (values[0]) { + this.filterQry += 'on_sky_stop_time_after='+ moment(new Date(values[0])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; + } + if (values[1]) { + this.filterQry += 'on_sky_stop_time_before='+moment(new Date(values[1])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; + } + } if (filter.id === 'Process Start Time') { const values = filter.value; if (values[0]) { - this.filterQry += 'start_time_after='+ moment(new Date(values[0])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; + this.filterQry += 'process_start_time_after='+ moment(new Date(values[0])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; } if (values[1]) { - this.filterQry += 'start_time_before='+moment(new Date(values[1])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; + this.filterQry += 'process_start_time_before='+moment(new Date(values[1])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; } - } else if (filter.id === 'End Time') { + } else if (filter.id === 'Process End Time') { const values = filter.value; if (values[0]) { - this.filterQry += 'stop_time_after='+ moment(new Date(values[0])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; + this.filterQry += 'process_stop_time_after='+ moment(new Date(values[0])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; } if (values[1]) { - this.filterQry += 'stop_time_before='+moment(new Date(values[1])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; + this.filterQry += 'process_stop_time_before='+moment(new Date(values[1])).format("YYYY-MM-DDTHH:mm:ss")+".000Z&"; } } else if (filter.id === 'Scheduling Unit Name') { if (this.state.taskType === 'Draft') { diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/summary.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/summary.js index 56b5ef83b03f165958e39229099cbba352e53b6f..270dca3aa1069184e1863b249dbbeef58f045e96 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/summary.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/summary.js @@ -58,7 +58,7 @@ export class TaskSummary extends Component { <label>Subtasks:</label> <ViewTable data={taskDetails.subtasks} - defaultcolumns={[{subtask_type: "Subtask Type", id: "Subtask ID", start_time:{name:"Start Time", format:UIConstants.CALENDAR_DATETIME_FORMAT}, stop_time:{name:"End Time", format:UIConstants.CALENDAR_DATETIME_FORMAT}, state_value: "Status"}]} + defaultcolumns={[{subtask_type: "Subtask Type", id: "Subtask ID", on_sky_start_time:{name:"Start Time", format:UIConstants.CALENDAR_DATETIME_FORMAT}, on_sky_stop_time:{name:"End Time", format:UIConstants.CALENDAR_DATETIME_FORMAT}, state_value: "Status"}]} optionalcolumns={[{actionpath: "actionpath"}]} columnclassname={[{"Subtask ID": "filter-input-50","Subtask Type":"filter-input-75", "Start Time": "filter-input-75", "End Time": "filter-input-75", "Status": "filter-input-75"}]} diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/view.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/view.js index 0190d3f5754533c374bc62055514ac8ec3e56957..47a04d5e6917b964d093ebda2efcfb996294f464 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/view.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/view.js @@ -52,16 +52,26 @@ export class TaskView extends Component { filter:"select", tooltip: 'Select Subtask status' }, - start_time: { + on_sky_start_time: { name: "Start Time", filter: "flatpickrDateRange", format:UIConstants.CALENDAR_DATETIME_FORMAT, }, - stop_time: { + on_sky_stop_time: { name: "End Time", filter: "flatpickrDateRange", format:UIConstants.CALENDAR_DATETIME_FORMAT }, + process_start_time: { + name: "Process Start Time", + filter: "flatpickrDateRange", + format:UIConstants.CALENDAR_DATETIME_FORMAT, + }, + process_stop_time: { + name: "Process End Time", + filter: "flatpickrDateRange", + format:UIConstants.CALENDAR_DATETIME_FORMAT + }, duration:{ name:"Duration (HH:mm:ss)", filter: "durationMinMax", @@ -69,6 +79,7 @@ export class TaskView extends Component { }, parset: { name: "Link to Parset", + filter: 'none', tooltip: 'Enter few characters' } }], @@ -171,7 +182,7 @@ export class TaskView extends Component { TaskService.getTaskDetails(taskType, taskId, this.fetchSubtask) .then(async(task) => { if (task) { - taskType === 'blueprint' && this.getSubtaskDetails(task.subtasks); + taskType === 'blueprint' && await this.getSubtaskDetails(task.subtasks); const suId = taskType==='draft'?task.scheduling_unit_draft_id:task.scheduling_unit_blueprint_id; let loadTasks = false; const taskTemplate = await TaskService.getTaskTemplate(task.specifications_template_id); @@ -209,10 +220,12 @@ export class TaskView extends Component { subtaskRow['type'] = subtask.subtask_type; subtaskRow['id'] = subtask.id; subtaskRow['status'] = subtask.state_value; - subtaskRow['start_time']= subtask.start_time; - subtaskRow['stop_time']= subtask.stop_time; + subtaskRow['on_sky_start_time']= subtask.on_sky_start_time; + subtaskRow['on_sky_stop_time']= subtask.on_sky_stop_time; + subtaskRow['process_start_time']= subtask.process_start_time; + subtaskRow['process_stop_time']= subtask.process_stop_time; subtaskRow['duration']= moment.utc((subtask.duration || 0) * 1000).format(UIConstants.CALENDAR_TIME_FORMAT); - subtaskRow['parset']= `https://proxy.lofar.eu/inspect/${subtask.id}/rtcp-${subtask.id}.parset`; + subtaskRow['parset']= `Parset`; subtaskRow['links'] = ['Link to Parset']; subtaskRow['linksURL'] = { 'Link to Parset': `https://proxy.lofar.eu/inspect/${subtask.id}/rtcp-${subtask.id}.parset` @@ -472,17 +485,28 @@ export class TaskView extends Component { <label className="col-lg-2 col-md-2 col-sm-12">Updated At</label> <span className="col-lg-4 col-md-4 col-sm-12">{moment.utc(this.state.task.updated_at).format(UIConstants.CALENDAR_DATETIME_FORMAT)}</span> </div> + {this.state.taskType === 'blueprint' && this.state.task.task_type === 'observation' && <div className="p-grid"> - <label className="col-lg-2 col-md-2 col-sm-12">Start Time</label> - <span className="col-lg-4 col-md-4 col-sm-12">{this.state.task.start_time?moment(this.state.task.start_time,moment.ISO_8601).format(UIConstants.CALENDAR_DATETIME_FORMAT):""}</span> - <label className="col-lg-2 col-md-2 col-sm-12">End Time</label> - <span className="col-lg-4 col-md-4 col-sm-12">{this.state.task.end_time?moment(this.state.task.end_time,moment.ISO_8601).format(UIConstants.CALENDAR_DATETIME_FORMAT):""}</span> - </div> + <label className="col-lg-2 col-md-2 col-sm-12">Observation Start Time</label> + <span className="col-lg-4 col-md-4 col-sm-12">{this.state.task.on_sky_start_time?moment(this.state.task.on_sky_start_time,moment.ISO_8601).format(UIConstants.CALENDAR_DATETIME_FORMAT):""}</span> + <label className="col-lg-2 col-md-2 col-sm-12">Observation End Time</label> + <span className="col-lg-4 col-md-4 col-sm-12">{this.state.task.on_sky_stop_time?moment(this.state.task.on_sky_stop_time,moment.ISO_8601).format(UIConstants.CALENDAR_DATETIME_FORMAT):""}</span> + </div>} + {this.state.taskType === 'blueprint' && + <div className="p-grid"> + <label className="col-lg-2 col-md-2 col-sm-12">Process Start Time</label> + <span className="col-lg-4 col-md-4 col-sm-12">{this.state.task.process_start_time?moment(this.state.task.process_start_time,moment.ISO_8601).format(UIConstants.CALENDAR_DATETIME_FORMAT):""}</span> + <label className="col-lg-2 col-md-2 col-sm-12">Process End Time</label> + <span className="col-lg-4 col-md-4 col-sm-12">{this.state.task.process_stop_time?moment(this.state.task.process_stop_time,moment.ISO_8601).format(UIConstants.CALENDAR_DATETIME_FORMAT):""}</span> + </div>} <div className="p-grid"> {/* <label className="col-lg-2 col-md-2 col-sm-12">Tags</label> <Chips className="col-lg-4 col-md-4 col-sm-12 chips-readonly" disabled value={this.state.task.tags}></Chips> */} - <label className="col-lg-2 col-md-2 col-sm-12">Status</label> - <span className="col-lg-4 col-md-4 col-sm-12">{this.state.task.status}</span> + {this.state.taskType === 'blueprint' && + <> + <label className="col-lg-2 col-md-2 col-sm-12">Status</label> + <span className="col-lg-4 col-md-4 col-sm-12">{this.state.task.status}</span> + </>} {this.state.schedulingUnit && <> <label className="col-lg-2 col-md-2 col-sm-12">Scheduling Unit</label> 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 8e709b1c4bc94a5c394a8f25f8637585988c77a9..72822aff42d8294eaee630d059494ca43767a725 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js @@ -99,7 +99,8 @@ export class TimelineView extends Component { unschedulableBlueprint: {}, datasetStartTime: null, datasetEndTime:null, showDialog: false, - popPosition: {display: 'none'} + popPosition: {display: 'none'}, + isOnSkyView: this.timelineUIAttributes.isOnSkyView || false, // Flag to show on sky view in normal timeline view } this.STATUS_BEFORE_SCHEDULED = ['defining', 'defined', 'schedulable']; // Statuses before scheduled to get station_group this.allStationsGroup = []; @@ -258,6 +259,17 @@ export class TimelineView extends Component { this.loadSUsAheadAndTrail(null, datasetEndTime, null, endTime); } } + // 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.stationView || this.state.isOnSkyView?su.on_sky_start_time:(su.process_start_time || su.on_sky_start_time); + su.stop_time = this.state.stationView || this.state.isOnSkyView?su.on_sky_stop_time:(su.process_stop_time || su.on_sky_stop_time); + _.map(su.task_blueprints, taskBp => { + taskBp.start_time = this.state.stationView || this.state.isOnSkyView?taskBp.on_sky_start_time:(taskBp.process_start_time || taskBp.on_sky_start_time); + taskBp.stop_time = this.state.stationView || this.state.isOnSkyView?taskBp.on_sky_stop_time:(taskBp.process_stop_time || taskBp.on_sky_stop_time); + return taskBp; + }); + return su; + }); // Returning the data for the timeline only or the existing data. return schedulingUnits; } @@ -1004,7 +1016,7 @@ export class TimelineView extends Component { return stations; } - setStationView(e) { + async setStationView(e) { this.closeSummaryPanel(); let selectedGroups = this.state.selectedStationGroup; // Store selected view and station group. Remove for default values. Default is all station groups. @@ -1020,7 +1032,15 @@ export class TimelineView extends Component { delete this.timelineUIAttributes["stationView"]; } this.timelineCommonUtils.storeUIAttributes(this.timelineUIAttributes); - this.setState({ stationView: e.value, selectedStationGroup: selectedGroups }); + await this.setState({ stationView: e.value, selectedStationGroup: selectedGroups }); + this.dateRangeCallback(this.state.currentStartTime, this.state.currentEndTime, false); + } + + async setOnSkyView(value) { + await this.setState({isOnSkyView: value}); + this.timelineUIAttributes['isOnSkyView'] = value; + this.timelineCommonUtils.storeUIAttributes(this.timelineUIAttributes); + this.dateRangeCallback(this.state.currentStartTime, this.state.currentEndTime, false); } showOptionMenu(event) { @@ -1385,10 +1405,21 @@ export class TimelineView extends Component { } </div> <div className={`timeline-view-toolbar p-grid ${this.state.stationView && 'alignTimeLineHeader'}`}> - <div className="sub-header col-lg-2"> + <div className={`sub-header ${this.state.stationView?"col-lg-2":"col-lg-1"}`}> <label >Station View</label> <InputSwitch checked={this.state.stationView} onChange={(e) => { this.setStationView(e) }} /> </div> + {!this.state.stationView && + <div className="sub-header col-lg-1"> + {/* <label >On Sky View</label> + <InputSwitch checked={this.state.isOnSkyView} onChange={(e) => { this.setOnSkyView(e.value)}} /> */} + <Button className="p-button-rounded toggle-btn" + tooltip={this.state.isOnSkyView?"Turn off On-Sky View":"Turn on On-Sky View"} + style={{minWidth: "50px", backgroundColor: this.state.isOnSkyView?"#007AD9":"#cccccc", color: this.state.isOnSkyView?"#ffffff":"#7e8286"}} + label="On-Sky View" + onClick={e => this.setOnSkyView(!this.state.isOnSkyView)} /> + </div> + } {this.state.stationView && <> <div className="sub-header col-lg-2"> 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 a8aca7e145674ffcb6bd3d5884c0ca4221700f08..a2ba1f2ed222b2acbd015e21d00f6b712b332473 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 @@ -24,6 +24,7 @@ import UIConstants from '../../utils/ui.constants'; import { TieredMenu } from 'primereact/tieredmenu'; import { InputSwitch } from 'primereact/inputswitch'; import { Dropdown } from 'primereact/dropdown'; +import { Button } from 'primereact/button'; import ReservationSummary from '../Reservation/reservation.summary'; import TimelineListTabs from './list.tabs'; import TimelineCommonUtils from './common.utils'; @@ -78,7 +79,8 @@ export class WeekTimelineView extends Component { datasetStartTime: null, datasetEndTime:null, showDialog: false, userrole: AuthStore.getState(), - popPosition: {display: 'none'} + popPosition: {display: 'none'}, + isOnSkyView: this.timelineUIAttributes.isOnSkyWeekView || false, // Flag to show on sky view in week view } this.STATUS_BEFORE_SCHEDULED = ['defining', 'defined', 'schedulable']; // Statuses before scheduled to get station_group this.reservations = []; @@ -204,6 +206,17 @@ export class WeekTimelineView extends Component { this.loadSUsAheadAndTrail(null, datasetEndTime, null, endTime); } } + // 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.stationView || this.state.isOnSkyView?su.on_sky_start_time:(su.process_start_time || su.on_sky_start_time); + su.stop_time = this.state.stationView || this.state.isOnSkyView?su.on_sky_stop_time:(su.process_stop_time || su.on_sky_stop_time); + _.map(su.task_blueprints, taskBp => { + taskBp.start_time = this.state.stationView || this.state.isOnSkyView?taskBp.on_sky_start_time:(taskBp.process_start_time || taskBp.on_sky_start_time); + taskBp.stop_time = this.state.stationView || this.state.isOnSkyView?taskBp.on_sky_stop_time:(taskBp.process_stop_time || taskBp.on_sky_stop_time); + return taskBp; + }); + return su; + }); // Returning the data for the timeline only or the existing data. return schedulingUnits; } @@ -375,7 +388,7 @@ export class WeekTimelineView extends Component { } else { const fetchDetails = !this.state.selectedItem || item.id !== this.state.selectedItem.id this.setState({ - selectedItem: item, isSUDetsVisible: true, + selectedItem: item, isSUDetsVisible: true, isReservDetsVisible: false, isSummaryLoading: fetchDetails, suTaskList: !fetchDetails ? this.state.suTaskList : [], canExtendSUList: false, canShrinkSUList: false @@ -825,6 +838,14 @@ export class WeekTimelineView extends Component { this.storeUIAttributes(); } + async setOnSkyView(value) { + await this.setState({isOnSkyView: value}); + this.timelineUIAttributes['isOnSkyWeekView'] = value; + let updatedItemGroupData = await this.dateRangeCallback(this.state.startTime, this.state.endTime, true); + this.timeline.updateTimeline(updatedItemGroupData); + this.storeUIAttributes(); + } + /** * Add Week Reservations during the visible timeline period * @param {Array} items @@ -1119,6 +1140,15 @@ export class WeekTimelineView extends Component { <InputSwitch checked={this.state.reservationEnabled} onChange={(e) => { this.showReservations(e) }} /> </div> + <div className="sub-header"> + {/* <label >On Sky View</label> + <InputSwitch checked={this.state.isOnSkyView} onChange={(e) => { this.setOnSkyView(e.value)}} /> */} + <Button className="p-button-rounded toggle-btn" + tooltip={this.state.isOnSkyView?"Turn off On-Sky View":"Turn on On-Sky View"} + style={{minWidth: "50px", backgroundColor: this.state.isOnSkyView?"#007AD9":"#cccccc", color: this.state.isOnSkyView?"#ffffff":"#7e8286"}} + label="On-Sky View" + onClick={e => this.setOnSkyView(!this.state.isOnSkyView)} /> + </div> {this.state.reservationEnabled && <div className="sub-header"> 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 86aac18f01bbd538adffca0ba491a8602d17928e..cfbb58bc0f5479a8c2e315f1fff2a96c435c60dd 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/services/schedule.service.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/services/schedule.service.js @@ -17,6 +17,9 @@ const SU_FETCH_FIELDS = [ "id", "do_cancel", "start_time", "stop_time", + "process_start_time", "process_stop_time", + "on_sky_start_time", "on_sky_stop_time", + "scheduled_on_sky_start_time", "scheduled_on_sky_stop_time", "duration", "priority_rank", "updated_at", @@ -32,6 +35,9 @@ const SU_FETCH_FIELDS = [ "id", "task_blueprints.status", "task_blueprints.start_time", "task_blueprints.stop_time", + "task_blueprints.process_start_time", "task_blueprints.process_stop_time", + "task_blueprints.on_sky_start_time", "task_blueprints.on_sky_stop_time", + "task_blueprints.scheduled_on_sky_start_time", "task_blueprints.scheduled_on_sky_stop_time", "task_blueprints.task_type", "task_blueprints.do_cancel", "task_blueprints.duration", @@ -137,7 +143,7 @@ const ScheduleService = { let blueprints = []; try { let url = `/api/scheduling_unit_blueprint/?ordering=name&expand=${SU_EXPAND_FIELDS.join()}&fields=${SU_FETCH_FIELDS.join()}`; - url = `${url}&start_time_before=${endTime || ''}&stop_time_after=${startTime || ''}`; + url = `${url}&scheduled_on_sky_start_time_before=${endTime || ''}&scheduled_on_sky_stop_time_after=${startTime || ''}`; let initialResponse = await axios.get(url); const totalCount = initialResponse.data.count; const initialCount = initialResponse.data.results.length @@ -147,6 +153,11 @@ const ScheduleService = { let secondResponse = await axios.get(url); blueprints = blueprints.concat(secondResponse.data.results); } + _.map(blueprints, su => { + su.start_time = su.scheduled_on_sky_start_time; + su.stop_time = su.scheduled_on_sky_stop_time; + return su; + }); } catch(error) { console.error('[schedule.services.getExpandedSUList]',error); }