From edd61dee0f3d4ef99673f6f016170bb827d65c54 Mon Sep 17 00:00:00 2001
From: Ramesh Kumar <r.kumar@redkarma.eu>
Date: Wed, 15 Jul 2020 12:36:58 +0530
Subject: [PATCH] TMSS-216:

Duration field in JSON editor customized
Temporarily grid columns size set
Not Found page added
Task page updated for mobile view
Task view route enabled with id and type parameter
---
 SAS/TMSS/frontend/tmss_webapp/package.json    |   2 +
 SAS/TMSS/frontend/tmss_webapp/src/App.css     |  10 ++
 .../src/components/JSONEditor/JEditor.js      |   8 +-
 SAS/TMSS/frontend/tmss_webapp/src/index.js    |   2 +-
 .../src/layout/components/NotFound.js         |  12 ++
 .../tmss_webapp/src/layout/sass/_content.scss |   2 +-
 .../tmss_webapp/src/routes/Task/edit.js       |  38 ++---
 .../tmss_webapp/src/routes/Task/view.js       | 153 ++++++++++++------
 .../frontend/tmss_webapp/src/routes/index.js  |   3 +
 .../tmss_webapp/src/services/task.services.js |  48 +++++-
 10 files changed, 203 insertions(+), 75 deletions(-)
 create mode 100644 SAS/TMSS/frontend/tmss_webapp/src/layout/components/NotFound.js

diff --git a/SAS/TMSS/frontend/tmss_webapp/package.json b/SAS/TMSS/frontend/tmss_webapp/package.json
index 6ee8b62dc27..e312fe079c2 100644
--- a/SAS/TMSS/frontend/tmss_webapp/package.json
+++ b/SAS/TMSS/frontend/tmss_webapp/package.json
@@ -10,6 +10,8 @@
     "@testing-library/user-event": "^7.1.2",
     "axios": "^0.19.2",
     "bootstrap": "^4.5.0",
+    "cleave.js": "^1.6.0",
+    "flatpickr": "^4.6.3",
     "font-awesome": "^4.7.0",
     "history": "^5.0.0",
     "lodash": "^4.17.19",
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/App.css b/SAS/TMSS/frontend/tmss_webapp/src/App.css
index c5efdaf30eb..8fb8be12caf 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/App.css
+++ b/SAS/TMSS/frontend/tmss_webapp/src/App.css
@@ -34,6 +34,16 @@ label {
   font-weight: 600;
   align-items: flex-start !important;
   color: #004B93;
+  margin-bottom: 10px;
+}
+
+.main-content span,a{
+  margin-bottom: 10px;
+  font-size: 14px;
+}
+
+#editor_holder {
+  padding: 0px 10px;
 }
 
 .chips-readonly > ul {
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 6ca2307f24e..db176a3dec5 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/components/JSONEditor/JEditor.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/components/JSONEditor/JEditor.js
@@ -19,7 +19,7 @@ function Jeditor(props) {
         let schema = {};
         Object.assign(schema, props.schema?props.schema:{});
         
-        // Customize the pointing property to capture angle1 and angle2 to in specified format
+        // Customize the pointing property to capture angle1 and angle2 to specified format
         for (const definitionKey in schema.definitions) {
             if (definitionKey === 'pointing') {
                 const defintion = schema.definitions[definitionKey];
@@ -281,10 +281,14 @@ function Jeditor(props) {
                 }   else if (propertyKey === 'QA' || propertyKey === 'beams') {
                     propertyValue.propertyOrder = 10000;
                 }
-                if (propertyKey === 'storage_cluster' || propertyKey === 'integration_time') {
+                if (propertyKey === 'storage_cluster' || propertyKey === 'integration_time' || propertyKey === 'storage_manager') {
                     let options = propertyValue.options?propertyValue.options:{};
                     options.grid_columns = 3;
                     propertyValue.options = options;
+                }   else if (propertyKey === 'flag') {
+                    let options = propertyValue.options?propertyValue.options:{};
+                    options.grid_columns = 9;
+                    propertyValue.options = options;
                 }
                 getCustomProperties(propertyValue);
             }
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/index.js b/SAS/TMSS/frontend/tmss_webapp/src/index.js
index f759ca8db08..3877566b95c 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/index.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/index.js
@@ -3,7 +3,7 @@ import ReactDOM from 'react-dom';
 import './index.css';
 import App from './App';
 import * as serviceWorker from './serviceWorker';
-import 'cleave.js/dist/cleave.js';
+import 'cleave.js/dist/cleave';
 
 ReactDOM.render(
   // <React.StrictMode>
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/layout/components/NotFound.js b/SAS/TMSS/frontend/tmss_webapp/src/layout/components/NotFound.js
new file mode 100644
index 00000000000..2d8784ebd74
--- /dev/null
+++ b/SAS/TMSS/frontend/tmss_webapp/src/layout/components/NotFound.js
@@ -0,0 +1,12 @@
+import React, { Component } from 'react';
+
+export class NotFound extends Component {
+
+    render() {
+        return  (
+            <h1>Not Found</h1>
+        );
+    }
+}
+
+export default NotFound;
\ No newline at end of file
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_content.scss b/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_content.scss
index 693a30ddbfb..5c49ad86c0d 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_content.scss
+++ b/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_content.scss
@@ -1,6 +1,6 @@
 .layout-main {
     @include transition(margin-left $transitionDuration);
-    padding: 60px 16px 16px 16px;
+    padding: 60px 16px 16px 25px;
     min-height: 95vh;
     background-color: white;
 }
\ No newline at end of file
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 11792bcb9a9..52c91365f5b 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/edit.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/edit.js
@@ -150,6 +150,8 @@ export class TaskEdit extends Component {
                 .then((taskTemplate) => {
                     this.setState({task: task, taskSchema: taskTemplate.schema});
                 });
+            }   else {
+                this.setState({redirect: "/not-found"});
             }
         });
     }
@@ -174,10 +176,10 @@ export class TaskEdit extends Component {
         return (
             <React.Fragment>
                 <div className="p-grid">
-                    <div className="p-col-2">
+                    <div className="p-col-10 p-lg-3 p-md-4">
                         <h2>Task - Edit</h2>
                     </div>
-                    <div className="p-col-1">
+                    <div className="p-col-2 p-lg-3 p-md-4">
                         <Link to={{ pathname: '/task', state: {id: this.state.task?this.state.task.id:''}}} tooltip="Close Edit" >
                             <i className="fa fa-window-close" style={{marginTop: "10px"}}></i>
                         </Link>
@@ -186,15 +188,15 @@ export class TaskEdit extends Component {
                 <div>
                     <div className="p-fluid">
                         <div className="p-field p-grid">
-                            <label htmlFor="taskName" className="p-col-2">Name <span style={{color:'red'}}>*</span></label>
-                            <div className="p-col-4">
+                            <label htmlFor="taskName" className="col-lg-2 col-md-2 col-sm-12">Name <span style={{color:'red'}}>*</span></label>
+                            <div className="col-lg-4 col-md-4 col-sm-12">
                                 <InputText className={this.state.errors.name ?'input-error':''} id="taskName" type="text" value={this.state.task.name} onChange={(e) => this.setTaskParams('name', e.target.value)}/>
                                 <label className="error">
                                     {this.state.errors.name ? this.state.errors.name : ""}
                                 </label>
                             </div>
-                            <label htmlFor="description" className="p-col-2">Description <span style={{color:'red'}}>*</span></label>
-                            <div className="p-col-4">
+                            <label htmlFor="description" className="col-lg-2 col-md-2 col-sm-12">Description <span style={{color:'red'}}>*</span></label>
+                            <div className="col-lg-4 col-md-4 col-sm-12">
                                 <InputTextarea className={this.state.errors.description ?'input-error':''} rows={3} cols={30} value={this.state.task.description} onChange={(e) => this.setTaskParams('description', e.target.value)}/>
                                 <label className="error">
                                     {this.state.errors.description ? this.state.errors.description : ""}
@@ -202,34 +204,34 @@ export class TaskEdit extends Component {
                             </div>
                         </div>
                         {/* <div className="p-field p-grid">
-                            <label htmlFor="createdAt" className="p-col-2">Created At</label>
-                            <div className="p-col-4">
+                            <label htmlFor="createdAt" className="col-lg-2 col-md-2 col-sm-12">Created At</label>
+                            <div className="col-lg-4 col-md-4 col-sm-12">
                                 <Calendar showTime={true} hourFormat="24" value={created_at} onChange={(e) => this.setState({date2: e.value})}></Calendar>
                             </div>
-                            <label htmlFor="updatedAt" className="p-col-2">Updated At</label>
-                            <div className="p-col-4">
+                            <label htmlFor="updatedAt" className="col-lg-2 col-md-2 col-sm-12">Updated At</label>
+                            <div className="col-lg-4 col-md-4 col-sm-12">
                                 <Calendar showTime={true} hourFormat="24" value={updated_at} onChange={(e) => this.setState({date2: e.value})}></Calendar>
                             </div>
                         </div> */}
                         <div className="p-field p-grid">
-                            <label htmlFor="tags" className="p-col-2">Tags</label>
-                            <div className="p-col-4">
+                            <label htmlFor="tags" className="col-lg-2 col-md-2 col-sm-12">Tags</label>
+                            <div className="col-lg-4 col-md-4 col-sm-12">
                                 <Chips value={this.state.task.tags?this.state.task.tags:[]} onChange={(e) => this.setTaskParams('tags', e.value)}></Chips>
                             </div>
-                            {/* <label htmlFor="doCancel" className="p-col-2">Do Cancel</label>
-                            <div className="p-col-4">
+                            {/* <label htmlFor="doCancel" className="col-lg-2 col-md-2 col-sm-12">Do Cancel</label>
+                            <div className="col-lg-4 col-md-4 col-sm-12">
                                 <Checkbox onChange={e => this.setTaskParams('do_cancel', e.checked)} checked={this.state.task.do_cancel}></Checkbox>
                             </div> */}
                             {this.state.schedulingUnit &&
                             <>
-                                <label className="p-col-2">Scheduling Unit</label>
-                                <Link className="p-col-4" to={ { pathname:'/schedulingunit/view', state: {id: this.state.schedulingUnit.id}}}>{this.state.schedulingUnit?this.state.schedulingUnit.name:''}</Link>
+                                <label className="col-lg-2 col-md-2 col-sm-12">Scheduling Unit</label>
+                                <Link className="col-lg-4 col-md-4 col-sm-12" to={ { pathname:'/schedulingunit/view', state: {id: this.state.schedulingUnit.id}}}>{this.state.schedulingUnit?this.state.schedulingUnit.name:''}</Link>
                             </>
                             }
                         </div>
                         <div className="p-field p-grid">
-                            <label htmlFor="tags" className="p-col-2">Template</label>
-                            <div className="p-col-4">
+                            <label htmlFor="tags" className="col-lg-2 col-md-2 col-sm-12">Template</label>
+                            <div className="col-lg-4 col-md-4 col-sm-12">
                                 <Dropdown optionLabel="name" optionValue="id" 
                                         value={this.state.task.specifications_template_id} 
                                         options={this.state.taskTemplates} 
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 6fd243298cc..e33bcdb5c59 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/view.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/view.js
@@ -1,5 +1,5 @@
 import React, {Component} from 'react';
-import {Link} from 'react-router-dom'
+import {Link, Redirect} from 'react-router-dom'
 import moment from 'moment';
 
 import Jeditor from '../../components/JSONEditor/JEditor';
@@ -13,55 +13,84 @@ export class TaskView extends Component {
         super(props);
         this.state = {
         };
+        this.setEditorFunction = this.setEditorFunction.bind(this);
+        if (this.props.match.params.id) {
+            this.state.taskId  = this.props.match.params.id;
+        }
+        if (this.props.match.params.type) {
+            this.state.taskType = this.props.match.params.type;
+        }
     }
 
     static getDerivedStateFromProps(nextProps, prevstate){
         if (prevstate.task && nextProps.location.state && 
-             nextProps.location.state.taskId === prevstate.task.id) {
-            return {taskId: prevstate.task.id}
+             (nextProps.location.state.taskId === prevstate.task.id ||
+             nextProps.location.state.taskType === prevstate.taskType)) {
+            return {taskId: prevstate.task.id, taskType: prevstate.taskType}
         }
         return null;
     }
 
     componentDidUpdate(prevProps, prevState) {
         if (this.state.task && this.props.location.state &&
-             this.state.task.id !== this.props.location.state.taskId) {
-             this.getTaskDetails(this.props.location.state.taskId);
+             (this.state.task.id !== this.props.location.state.taskId ||
+             this.state.taskType !== this.props.location.state.taskType)) {
+             this.getTaskDetails(this.props.location.state.taskId, this.props.location.state.taskType);
         }
     }
 
     componentDidMount() {
-        const taskId = this.props.location.state?this.props.location.state.id:1;
-        this.getTaskDetails(taskId);
+        const taskId = this.props.location.state?this.props.location.state.id:this.state.taskId;
+        let taskType = this.props.location.state?this.props.location.state.type:this.state.taskType;
+        taskType = taskType?taskType:'draft';
+        if (taskId && taskType) {
+            this.getTaskDetails(taskId, taskType);
+        }   else {
+            this.setState({redirect: "/not-found"});
+        }
+    }
+
+    /**
+     * JEditor's function that to be called when parent wants to trigger change in the JSON Editor
+     * @param {Function} editorFunction 
+     */
+    setEditorFunction(editorFunction) {
+        this.setState({editorFunction: editorFunction});
     }
 
     /**
      * To get the task details from the backend using the service
      * @param {number} taskId 
      */
-    getTaskDetails(taskId) {
+    getTaskDetails(taskId, taskType) {
         if (taskId) {
-            TaskService.getTaskDetails("draft", taskId)
+            taskType = taskType?taskType:'draft';
+            TaskService.getTaskDetails(taskType, taskId)
             .then((task) => {
                 if (task) {
-                TaskService.getSchedulingUnit("draft", task.scheduling_unit_draft_id)
-                    .then((schedulingUnit) => {
-                        this.setState({schedulingUnit: schedulingUnit});
-                    });
-                    TaskService.getTaskTemplate(task.specifications_template_id)
-                    .then((taskTemplate) => {
-                        if (this.state.editorFunc) {
-                            this.state.editorFunc();
-                        }
-                        this.setState({task: task, taskTemplate: taskTemplate});
-                    });
+                    TaskService.getSchedulingUnit(taskType, (taskType==='draft'?task.scheduling_unit_draft_id:task.scheduling_unit_blueprint_id))
+                        .then((schedulingUnit) => {
+                            this.setState({schedulingUnit: schedulingUnit});
+                        });
+                        TaskService.getTaskTemplate(task.specifications_template_id)
+                        .then((taskTemplate) => {
+                            if (this.state.editorFunction) {
+                                this.state.editorFunction();
+                            }
+                            this.setState({task: task, taskTemplate: taskTemplate, taskType: taskType});
+                        });
                     
+                }   else {
+                    this.setState({redirect: "/not-found"});
                 }
             });
         }
     }
 
     render() {
+        if (this.state.redirect) {
+            return <Redirect to={ {pathname: this.state.redirect} }></Redirect>
+        }
         let jeditor = null
         if (this.state.taskTemplate) {
             jeditor = React.createElement(Jeditor, {title: "Specification", 
@@ -69,76 +98,102 @@ export class TaskView extends Component {
                                                         initValue: this.state.task.specifications_doc,
                                                         disabled: true,
                                                         // callback: this.setEditorOutput,
-                                                        // parentFunction: this.setEditorFunction
+                                                        parentFunction: this.setEditorFunction
                                                     });
         }
 
         // Child component to render predecessors and successors list
         const TaskRelationList = ({ list }) => (
             <ul className="task-list">
-              {list.map(item => (
+            {list && list.map(item => (
                 <li key={item.id}>
-                    <Link to={ { pathname:'/task', state: {taskId: item.id}}}>{item.name}</Link>
+                    <Link to={ { pathname:'/task', state: {taskId: item.id, taskType: item.draft?'blueprint':'draft'}}}>{item.name}</Link>
                 </li>
-              ))}
+            ))}
             </ul>
           );
-
         return (
             <React.Fragment>
                 <div className="p-grid">
-                    <div className="p-col-3">
+                    <div className="p-col-10 p-lg-3 p-md-4">
                         <h2>Task - Details </h2>
                     </div>
-                    <div className="p-col-1">
-                        <Link to={{ pathname: '/task/edit', state: {taskId: this.state.task?this.state.task.id:''}}} tooltip="Edit Task" >
-                            <i className="fa fa-edit" style={{marginTop: "10px"}}></i>
-                        </Link>
+                    <div className="p-col-2 p-lg-3 p-md-4">
+                        {this.state.taskType === 'draft' &&
+                            <Link to={{ pathname: '/task/edit', state: {taskId: this.state.task?this.state.task.id:''}}} tooltip="Edit Task" >
+                                <i className="fa fa-edit" style={{marginTop: "10px"}}></i>
+                            </Link>
+                        }
+                        {this.state.taskType === 'blueprint' &&
+                            <i className="fa fa-lock" style={{marginTop: "10px"}}></i>
+                        }
                     </div>
                 </div>
                 { this.state.task &&
                     <React.Fragment>
+                        <div className="main-content">
+                        <div className="p-grid">
+                            <label className="col-lg-2 col-md-2 col-sm-12">Name</label>
+                            <span className="col-lg-4 col-md-4 col-sm-12">{this.state.task.name}</span>
+                            <label className="col-lg-2 col-md-2 col-sm-12">Description</label>
+                            <span className="col-lg-4 col-md-4 col-sm-12">{this.state.task.description}</span>
+                        </div>
                         <div className="p-grid">
-                            <label className="p-col-2">Name</label>
-                            <span className="p-col-4">{this.state.task.name}</span>
-                            <label className="p-col-2">Description</label>
-                            <span className="p-col-4">{this.state.task.description}</span>
+                            <label className="col-lg-2 col-md-2 col-sm-12">Created At</label>
+                            <span className="col-lg-4 col-md-4 col-sm-12">{moment.utc(this.state.task.created_at).format(this.DATE_FORMAT)}</span>
+                            <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(this.DATE_FORMAT)}</span>
                         </div>
                         <div className="p-grid">
-                            <label className="p-col-2">Created At</label>
-                            <span className="p-col-4">{moment.utc(this.state.task.created_at).format(this.DATE_FORMAT)}</span>
-                            <label className="p-col-2">Updated At</label>
-                            <span className="p-col-4">{moment.utc(this.state.task.updated_at).format(this.DATE_FORMAT)}</span>
+                            <label className="col-lg-2 col-md-2 col-sm-12">Copies</label>
+                            <span className="col-lg-4 col-md-4 col-sm-12">{this.state.taskType==='draft'?this.state.task.copies:this.state.task.draftObject.copies}</span>
+                            <label className="col-lg-2 col-md-2 col-sm-12">Copy Reason</label>
+                            <span className="col-lg-4 col-md-4 col-sm-12">{this.state.taskType==='draft'?this.state.task.copy_reason_value:this.state.task.draftObject.copy_reason_value}</span>
                         </div>
                         <div className="p-grid">
-                            <label className="p-col-2">Tags</label>
-                            <Chips className="p-col-4 chips-readonly" disabled value={this.state.task.tags}></Chips>
+                            <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?moment.utc(this.state.task.start).format(this.DATE_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?moment.utc(this.state.task.end).format(this.DATE_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>
                             {this.state.schedulingUnit &&
                             <>
-                                <label className="p-col-2">Scheduling Unit</label>
-                                <Link className="p-col-4" to={ { pathname:'/schedulingunit/view', state: {id: this.state.schedulingUnit.id}}}>{this.state.schedulingUnit?this.state.schedulingUnit.name:''}</Link>
+                                <label className="col-lg-2 col-md-2 col-sm-12">Scheduling Unit</label>
+                                <Link className="col-lg-4 col-md-4 col-sm-12" to={ { pathname:'/schedulingunit/view', state: {id: this.state.schedulingUnit.id}}}>{this.state.schedulingUnit?this.state.schedulingUnit.name:''}</Link>
                             </>}
                         </div>
                         <div className="p-grid">
-                            <label className="p-col-2">Predecessors</label>
-                            <div className="p-col-4">
+                            <label className="col-lg-2 col-md-2 col-sm-12">Predecessors</label>
+                            <div className="col-lg-4 col-md-4 col-sm-12">
                                 <TaskRelationList list={this.state.task.predecessors} />
                             </div>
-                            <label className="p-col-2">Successors</label>
-                            <div className="p-col-4">
+                            <label className="col-lg-2 col-md-2 col-sm-12">Successors</label>
+                            <div className="col-lg-4 col-md-4 col-sm-12">
                                 <TaskRelationList list={this.state.task.successors} />
                             </div>
                         </div>
                         <div className="p-grid">
-                            <label className="p-col-2">Template</label>
-                            <span className="p-col-4">{this.state.taskTemplate.name}</span>
-                            
+                            <label className="col-lg-2 col-md-2 col-sm-12">Template</label>
+                            <span className="col-lg-4 col-md-4 col-sm-12">{this.state.taskTemplate.name}</span>
+                            <label className="col-lg-2 col-md-2 col-sm-12">{this.state.taskType==='draft'?'Blueprints':'Draft'}</label>
+                            <div className="col-lg-4 col-md-4 col-sm-12">
+                                {this.state.taskType === 'draft' &&
+                                    <TaskRelationList list={this.state.task.blueprints} />
+                                }
+                                {this.state.taskType === 'blueprint' &&
+                                    <Link className="col-lg-4 col-md-4 col-sm-12" to={ { pathname:'/task', state: {taskId: this.state.task.draft_id, taskType: 'draft'}}}>{this.state.task.draftObject.name}</Link>
+                                }
+                            </div>
                         </div>
                         <div className="p-fluid">
                             <div className="p-grid"><div className="p-col-12">
                                 {this.state.taskTemplate?jeditor:""}
                             </div></div>
                         </div>
+                        </div>
                     </React.Fragment>
                 }
             </React.Fragment>
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/index.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/index.js
index af3090f1ef0..c2ed5db0bf2 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/index.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/index.js
@@ -5,6 +5,7 @@ import {
     Redirect
 } from 'react-router-dom';
 
+import {NotFound} from '../layout/components/NotFound';
 import {Dashboard} from './Dashboard';
 import {Scheduling} from './Scheduling';
 import {TaskEdit, TaskView} from './Task';
@@ -14,10 +15,12 @@ export const RoutedContent = () => {
     return (
         <Switch>
             <Redirect from="/" to="/" exact />
+            <Route path="/not-found" exact component= {NotFound} />
             <Route path="/dashboard" exact component={Dashboard} />
             <Route path="/scheduling" exact component={Scheduling} />
             <Route path="/task" exact component={TaskView} />
             <Route path="/task/view" exact component={TaskView} />
+            <Route path="/task/view/:type/:id" exact component={TaskView} />
             <Route path="/task/edit" exact component={TaskEdit} />
             <Route path="/schedulingunit/view" exact component={ViewSchedulingUnit} />
         </Switch>
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/services/task.services.js b/SAS/TMSS/frontend/tmss_webapp/src/services/task.services.js
index e41791aa60f..e55f34d594e 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/services/task.services.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/services/task.services.js
@@ -10,10 +10,20 @@ const TaskService = {
           const response = await axios.get(url + taskId);
           response.data.predecessors = [];
           response.data.successors = [];
-          return this.getTaskRelations('draft', response.data.id)
+          if (taskType === 'blueprint') {
+            response.data.blueprints = [];
+          } else {
+            response.data.draftName = null;
+          }
+          return this.getTaskRelationsByTask(taskType, response.data)
                   .then(relations => {
                     response.data.predecessors = relations.predecessors;
                     response.data.successors = relations.successors;
+                    if (taskType === 'draft') {
+                      response.data.blueprints = relations.blueprints;
+                    } else {
+                      response.data.draftObject = relations.draft;
+                    }
                     return response.data;
                   });
           
@@ -63,16 +73,28 @@ const TaskService = {
         console.error(error);
       }
     },
-    getTaskRelations: async function(type, id) {
+    getTaskRelationsByTask: async function(type, task) {
       try {
         let relations = {};
-        return this.getTaskPredecessors(type, id)
+        return this.getTaskPredecessors(type, task.id)
         .then( predecessors => {
           relations.predecessors = predecessors;
-          return this.getTaskSuccessors(type, id);
+          return this.getTaskSuccessors(type, task.id);
         })
         .then( successors => {
           relations.successors = successors;
+          if (type === 'draft') {
+            return this.getDraftsTaskBlueprints(task.id);
+          } else {
+            return this.getTaskdraft(task.draft_id);
+          }
+        })
+        .then( result => {
+          if (type === 'draft') {
+            relations.blueprints = result;
+          } else {
+            relations.draft = result;
+          }
           return relations;
         });
       } catch (error) {
@@ -96,6 +118,24 @@ const TaskService = {
       } catch (error) {
         console.error(error);
       }
+    },
+    getDraftsTaskBlueprints: async function(id) {
+      try {
+        const url = `/api/task_draft/${id}/task_blueprint`;
+        const response = await axios.get(url);
+        return response.data.results;
+      } catch (error) {
+        console.error(error);
+      }
+    },
+    getTaskdraft: async function(id) {
+      try {
+        const url = `/api/task_draft/${id}`;
+        const response = await axios.get(url);
+        return response.data;
+      } catch (error) {
+        console.error(error);
+      }
     }
     
 }
-- 
GitLab