diff --git a/Docker/lofar-ci/Dockerfile_ci_sas b/Docker/lofar-ci/Dockerfile_ci_sas
index 106829eb48987c05e2cb8015386d5ddb1e600a0d..2a6990ac03b2521f124c19f0395314feb9a8ae70 100644
--- a/Docker/lofar-ci/Dockerfile_ci_sas
+++ b/Docker/lofar-ci/Dockerfile_ci_sas
@@ -16,7 +16,7 @@ RUN yum erase -y postgresql postgresql-server postgresql-devel && \
     cd /bin && ln -s /usr/pgsql-9.6/bin/initdb && ln -s /usr/pgsql-9.6/bin/postgres
 ENV PATH /usr/pgsql-9.6/bin:$PATH 
 
-RUN pip3 install cython kombu lxml requests pygcn xmljson mysql-connector-python python-dateutil Django==3.0.9 djangorestframework djangorestframework-xml ldap==1.0.2 flask fabric coverage python-qpid-proton PyGreSQL numpy h5py psycopg2 testing.postgresql Flask-Testing scipy Markdown django-filter python-ldap python-ldap-test ldap3 djangorestframework django-jsonforms django-json-widget django-jsoneditor drf-yasg flex swagger-spec-validator django-auth-ldap mozilla-django-oidc jsonschema comet pyxb==1.2.5 graphviz isodate
+RUN pip3 install cython kombu lxml requests pygcn xmljson mysql-connector-python python-dateutil Django==3.0.9 djangorestframework djangorestframework-xml ldap==1.0.2 flask fabric coverage python-qpid-proton PyGreSQL numpy h5py psycopg2 testing.postgresql Flask-Testing scipy Markdown django-filter python-ldap python-ldap-test ldap3 djangorestframework django-jsonforms django-json-widget django-jsoneditor drf-yasg flex swagger-spec-validator django-auth-ldap mozilla-django-oidc jsonschema comet pyxb==1.2.5 graphviz isodate astropy
 
 # Note: nodejs now comes with npm, do not install the npm package separately, since that will be taken from the epel repo and is conflicting.
 RUN echo "Installing Nodejs packages..." && \
diff --git a/LTA/sip/lib/CMakeLists.txt b/LTA/sip/lib/CMakeLists.txt
index a9851a135a5f82c62c0110b5d802d191a95a2fe0..7cfd5468d9f8430570aeea7bb77a6e4c52b0495e 100644
--- a/LTA/sip/lib/CMakeLists.txt
+++ b/LTA/sip/lib/CMakeLists.txt
@@ -14,6 +14,7 @@ set(_py_files
   constants.py
   visualizer.py
   query.py
+  station_coordinates.py
 )
 
 
@@ -25,6 +26,7 @@ set(resource_files
 python_install(${_py_files}
                DESTINATION lofar/lta/sip)
 
+
 install(FILES ${resource_files}
   DESTINATION ${PYTHON_INSTALL_DIR}/lofar/lta/sip
   COMPONENT ${lower_package_name})
diff --git a/LTA/sip/lib/siplib.py b/LTA/sip/lib/siplib.py
index bb3c6238a14a19117ee2d5379f838ddb6b04f66c..4f89a4fe91f5552972e9b43c0cc4afe903d9d9fc 100644
--- a/LTA/sip/lib/siplib.py
+++ b/LTA/sip/lib/siplib.py
@@ -28,6 +28,7 @@
 from . import ltasip
 import pyxb
 from . import constants
+from . import station_coordinates
 import os
 import uuid
 import xml.dom.minidom
@@ -38,8 +39,6 @@ import logging
 logger = logging.getLogger(__name__)
 
 VERSION = "SIPlib 0.4"
-d = os.path.dirname(os.path.realpath(__file__))
-STATION_CONFIG_PATH = d+'/station_coordinates.conf'
 ltasip.Namespace.setPrefix('sip')
 
 # todo: create docstrings for everything.
@@ -144,30 +143,28 @@ class Station():
 
         __afield1=None
         __afield2=None
-        with open(STATION_CONFIG_PATH, 'r') as f:
-            for line in f.readlines():
-                if line.strip():
-                  field_coords = eval("dict("+line+")")  # literal_eval does not accept dict definition via constructor. Make sure config file is not writable to prevent code execution!
-                  for type in antennafieldtypes:
-                    if field_coords["name"] == name+"_"+type:
-                        __afield=AntennafieldXYZ(
-                            type=type,
+        station_coords = station_coordinates.parse_station_coordinates()
+        for atype in antennafieldtypes:
+            if name+"_"+atype in station_coords.keys():
+                field_coords = station_coords[name+"_"+atype]
+                __afield=AntennafieldXYZ(
+                            type=atype,
                             coordinate_system=field_coords["coordinate_system"],
                             coordinate_unit=constants.LENGTHUNIT_M, # Does this make sense? I have to give a lenght unit accoridng to the XSD, but ICRF should be decimal degrees?!
                             coordinate_x=field_coords["x"],
                             coordinate_y=field_coords["y"],
                             coordinate_z=field_coords["z"])
-                        if not __afield1:
-                            __afield1=__afield
-                        elif not __afield2:
-                            __afield2=__afield
+                if not __afield1:
+                    __afield1=__afield
+                elif not __afield2:
+                    __afield2=__afield
 
         if not __afield1:
-            raise Exception("no matching coordinates found for station:", name,"and fields",str(antennafieldtypes))
+            raise Exception("no matching coordinates found for station:", name, "and fields", str(antennafieldtypes))
 
-        if name.startswith( 'CS' ):
+        if name.startswith('CS'):
             sttype = "Core"
-        elif name.startswith( "RS" ):
+        elif name.startswith("RS"):
             sttype = "Remote"
         else:
             sttype = "International"
diff --git a/LTA/sip/lib/station_coordinates.conf b/LTA/sip/lib/station_coordinates.conf
index 07e488f9a72ccf960c6e6f30c9bc39823e3c7613..741cd1395f2a6a362e70335b7c97d0ac383eb746 100644
--- a/LTA/sip/lib/station_coordinates.conf
+++ b/LTA/sip/lib/station_coordinates.conf
@@ -154,3 +154,9 @@ coordinate_system='ITRF2005', x='3850973.9872', y='1439061.04111', z='4860478.99
 coordinate_system='ITRF2005', x='3850980.8812', y='1438994.87911', z='4860498.993'  , name='PL611_HBA'
 coordinate_system='ITRF2005', x='3551478.64311', y='1334128.4928', z='5110179.160'  , name='PL612_LBA'
 coordinate_system='ITRF2005', x='3551481.8171', y='1334203.5728', z='5110157.410'  , name='PL612_HBA'
+
+coordinate_system='ITRF2005', x='3801633.528060000', y='-529021.899396000', z='5076997.185' , name='IE613_LBA'
+coordinate_system='ITRF2005', x='3801691.943300000', y='-528983.966429000', z='5076957.924'  , name='IE613_HBA'
+
+coordinate_system='ITRF2005', x='3183318.032280000', y='1276777.654760000', z='5359435.077'   , name='LV614_LBA'
+coordinate_system='ITRF2005', x='3183249.285620000', y='1276801.742170000', z='5359469.949'     , name='LV614_HBA'
\ No newline at end of file
diff --git a/LTA/sip/lib/station_coordinates.py b/LTA/sip/lib/station_coordinates.py
new file mode 100644
index 0000000000000000000000000000000000000000..f2952a203d2af5ee5578342eac1af1706c41662c
--- /dev/null
+++ b/LTA/sip/lib/station_coordinates.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python3
+
+# This module provides functions for easy creation of a Lofar LTA SIP document.
+# It builds upon a Pyxb-generated API from the schema definition, which is very clever but hard to use, since
+# the arguments in class constructors and functions definitions are not verbose and there is no intuitive way
+# to determine the mandatory and optional elements to create a valid SIP document. This module is designed to
+# provide easy-to-use functions that bridges this shortcoming of the Pyxb API.
+#
+# Usage: Import module. Create an instance of Sip.
+#        Add elements through the Sip.add_X functions. Many require instances of other classes of the module.
+#        call getprettyxml() and e.g. save to disk.
+#
+# Note on validation: From construction through every addition, the SIP should remain valid (or throw an error
+# that clearly points out where e.g. a given value does not meet the restrictions of the SIP schema.
+#
+# Note on code structure: This has to be seen as a compromise between elegant and maintainable code with well-
+# structured inheritance close to the schema definition on the one hand, and something more straightforward to use,
+# with flatter hierarchies on the other hand.
+#
+# Note on parameter maps:  The ...Map objects are helper objects to create dictionaries for the commonly used
+# constructor arguments of several other objects. This could alternatively also be implemented via inheritance from
+# a supertype, and indeed is solved like this in the pyxb code. However, this then requires the use of an argument
+# list pointer, which hides the list of required and optional arguments from the user. Alternatively, all arguments
+# have to be mapped in all constructors repeatedly, creating lots of boilerplate code. This is the nicest approach
+# I could think of that keeps the whole thing reasonably maintainable AND usable.
+
+import os
+d = os.path.dirname(os.path.realpath(__file__))
+STATION_CONFIG_PATH = d+'/station_coordinates.conf'
+
+
+def parse_station_coordinates() -> dict:
+    """
+    :return: a dict mapping station field name, e.g. "CS002_LBA", to a dict containing ITRF coordinates
+    """
+    station_coordinates = {}
+    with open(STATION_CONFIG_PATH, 'r') as f:
+        for line in f.readlines():
+            if line.strip():
+                field_coords = eval("dict(" + line + ")")  # literal_eval does not accept dict definition via constructor. Make sure config file is not writable to prevent code execution!
+                station_coordinates[field_coords.pop("name")] = field_coords
+    return station_coordinates
+
+
diff --git a/SAS/TMSS/frontend/tmss_webapp/package.json b/SAS/TMSS/frontend/tmss_webapp/package.json
index b8a53534056c2171aa2bddc4e885529473f5ef16..11b49d269318768f1595a2d1e95c4354b6b66544 100644
--- a/SAS/TMSS/frontend/tmss_webapp/package.json
+++ b/SAS/TMSS/frontend/tmss_webapp/package.json
@@ -3,6 +3,7 @@
   "version": "0.1.0",
   "private": true,
   "dependencies": {
+    "@apidevtools/json-schema-ref-parser": "^9.0.6",
     "@fortawesome/fontawesome-free": "^5.13.1",
     "@json-editor/json-editor": "^2.3.0",
     "@testing-library/jest-dom": "^4.2.4",
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/App.css b/SAS/TMSS/frontend/tmss_webapp/src/App.css
index 766fff47baad6747a35c03a164125f8d181f5956..d19517b7d6d383cb7d804784960ec03a8c68dc2f 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/App.css
+++ b/SAS/TMSS/frontend/tmss_webapp/src/App.css
@@ -53,6 +53,10 @@ a{
   margin-bottom: 10px;
 }
 
+.main-content {
+  margin-top:20px;
+}
+
 .main-content span,a{
   font-size: 14px;
 }
@@ -90,6 +94,18 @@ p {
   margin-bottom: 5px;
 }
 
+.main-content .p-grid span {
+  margin-bottom: 10px;
+}
+
+.p-chips-token,.p-inputnumber span {
+  margin-bottom: 0px;
+}
+
+.p-chips-token .p-chips-token-label {
+  margin-bottom: 0px !important;
+}
+
 .p-field {
   margin-bottom: 0.5rem;
 }
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/App.js b/SAS/TMSS/frontend/tmss_webapp/src/App.js
index af0b8d760c3c17348d38f349362ee983a10dbc1b..9342bcab807245624c5b5fa4c081e95ca81bea5d 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/App.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/App.js
@@ -23,6 +23,7 @@ class App extends Component {
 	  layoutMode: 'static',
       currentMenu: '',
       currentPath: '/',
+      PageTitle:'',
 	  staticMenuInactive: false,
             overlayMenuActive: false,
             mobileMenuActive: false,
@@ -31,6 +32,7 @@ class App extends Component {
         this.onToggleMenu = this.onToggleMenu.bind(this);
         this.onSidebarClick = this.onSidebarClick.bind(this);
         this.onMenuItemClick = this.onMenuItemClick.bind(this);
+        this.setPageTitle = this.setPageTitle.bind(this);
   
       this.menu = [
       {label: 'Dashboard', icon: 'pi pi-fw pi-home', to:'/dashboard'},
@@ -90,6 +92,12 @@ class App extends Component {
 	isDesktop() {
         return window.innerWidth > 1024;
     }
+
+    setPageTitle(PageTitle) {
+        if (PageTitle !== this.state.PageTitle) {
+            this.setState({ PageTitle })
+        }
+    } 
 	
   render() {
 			const wrapperClass = classNames('layout-wrapper', {
@@ -99,7 +107,8 @@ class App extends Component {
             'layout-overlay-sidebar-active': this.state.overlayMenuActive && this.state.layoutMode === 'overlay',
             'layout-mobile-sidebar-active': this.state.mobileMenuActive			
 		});
-		const AppBreadCrumbWithRouter = withRouter(AppBreadcrumb);
+        const AppBreadCrumbWithRouter = withRouter(AppBreadcrumb);
+       
 		
      return (
       <React.Fragment>
@@ -108,10 +117,10 @@ class App extends Component {
            <div className={wrapperClass}>
             <AppTopbar onToggleMenu={this.onToggleMenu}></AppTopbar>
             <Router basename={ this.state.currentPath }>
-			  <AppMenu model={this.menu} onMenuItemClick={this.onMenuItemClick} />
+              <AppMenu model={this.menu} onMenuItemClick={this.onMenuItemClick} />
               <div className="layout-main">
-			  <AppBreadCrumbWithRouter/>
-			  <RoutedContent />
+			  <AppBreadCrumbWithRouter setPageTitle={this.setPageTitle} />
+              <RoutedContent />
               </div>
             </Router>
             <AppFooter></AppFooter>
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/__mocks__/project.service.data.js b/SAS/TMSS/frontend/tmss_webapp/src/__mocks__/project.service.data.js
index 066fd339758c56e64cc51a2ae81142eb978a583d..ab49f92eec7585581a21305ed884ead2f8c929a9 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/__mocks__/project.service.data.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/__mocks__/project.service.data.js
@@ -7,180 +7,90 @@ const ProjectServiceMock= {
         "url": "http://localhost:3000/api/resource_type/LOFAR%20Observing%20Time/",
         "created_at": "2020-07-29T07:31:21.708296",
         "description": "LOFAR Observing Time",
-        "resource_unit": "http://localhost:3000/api/resource_unit/second/",
-        "resource_unit_id": "second",
         "tags": [
         ],
         "updated_at": "2020-07-29T07:31:21.708316",
-        "resourceUnit": {
-            "name": "second",
-            "url": "http://localhost:3000/api/resource_unit/second/",
-            "created_at": "2020-07-29T07:31:21.070088",
-            "description": "Unit of time or duration",
-            "tags": [
-            ],
-            "updated_at": "2020-07-29T07:31:21.070114"
-        }
+        "quantity_value": "time"
     },
     {
         "name": "LOFAR Observing Time prio A",
         "url": "http://localhost:3000/api/resource_type/LOFAR%20Observing%20Time%20prio%20A/",
         "created_at": "2020-07-29T07:31:21.827537",
         "description": "LOFAR Observing Time prio A",
-        "resource_unit": "http://localhost:3000/api/resource_unit/second/",
-        "resource_unit_id": "second",
         "tags": [
         ],
         "updated_at": "2020-07-29T07:31:21.827675",
-        "resourceUnit": {
-            "name": "second",
-            "url": "http://localhost:3000/api/resource_unit/second/",
-            "created_at": "2020-07-29T07:31:21.070088",
-            "description": "Unit of time or duration",
-            "tags": [
-            ],
-            "updated_at": "2020-07-29T07:31:21.070114"
-        }
+        "quantity_value": "time"
     },
     {
         "name": "LOFAR Observing Time prio B",
         "url": "http://localhost:3000/api/resource_type/LOFAR%20Observing%20Time%20prio%20B/",
         "created_at": "2020-07-29T07:31:21.950948",
         "description": "LOFAR Observing Time prio B",
-        "resource_unit": "http://localhost:3000/api/resource_unit/second/",
-        "resource_unit_id": "second",
         "tags": [
         ],
         "updated_at": "2020-07-29T07:31:21.950968",
-        "resourceUnit": {
-            "name": "second",
-            "url": "http://localhost:3000/api/resource_unit/second/",
-            "created_at": "2020-07-29T07:31:21.070088",
-            "description": "Unit of time or duration",
-            "tags": [
-            ],
-            "updated_at": "2020-07-29T07:31:21.070114"
-        }
+        "quantity_value": "time"
     },
     {
         "name": "CEP Processing Time",
         "url": "http://localhost:3000/api/resource_type/CEP%20Processing%20Time/",
         "created_at": "2020-07-29T07:31:22.097916",
         "description": "CEP Processing Time",
-        "resource_unit": "http://localhost:3000/api/resource_unit/second/",
-        "resource_unit_id": "second",
         "tags": [
         ],
         "updated_at": "2020-07-29T07:31:22.097941",
-        "resourceUnit": {
-            "name": "second",
-            "url": "http://localhost:3000/api/resource_unit/second/",
-            "created_at": "2020-07-29T07:31:21.070088",
-            "description": "Unit of time or duration",
-            "tags": [
-            ],
-            "updated_at": "2020-07-29T07:31:21.070114"
-        }
+        "quantity_value": "time"
     },
     {
         "name": "LTA Storage",
         "url": "http://localhost:3000/api/resource_type/LTA%20Storage/",
         "created_at": "2020-07-29T07:31:22.210071",
         "description": "LTA Storage",
-        "resource_unit": "http://localhost:3000/api/resource_unit/byte/",
-        "resource_unit_id": "byte",
         "tags": [
         ],
         "updated_at": "2020-07-29T07:31:22.210091",
-        "resourceUnit": {
-            "name": "byte",
-            "url": "http://localhost:3000/api/resource_unit/byte/",
-            "created_at": "2020-07-29T07:31:21.500997",
-            "description": "Unit of data storage",
-            "tags": [
-            ],
-            "updated_at": "2020-07-29T07:31:21.501028"
-        }
+        "quantity_value": "bytes"
     },
     {
         "name": "Number of triggers",
         "url": "http://localhost:3000/api/resource_type/Number%20of%20triggers/",
         "created_at": "2020-07-29T07:31:22.317313",
         "description": "Number of triggers",
-        "resource_unit": "http://localhost:3000/api/resource_unit/number/",
-        "resource_unit_id": "number",
         "tags": [
         ],
         "updated_at": "2020-07-29T07:31:22.317341",
-        "resourceUnit": {
-            "name": "number",
-            "url": "http://localhost:3000/api/resource_unit/number/",
-            "created_at": "2020-07-29T07:31:21.596364",
-            "description": "Unit of count",
-            "tags": [
-            ],
-            "updated_at": "2020-07-29T07:31:21.596385"
-        }
+        "quantity_value": "number"
     },
     {
         "name": "LOFAR Support Time",
         "url": "http://localhost:3000/api/resource_type/LOFAR%20Support%20Time/",
         "created_at": "2020-07-29T07:31:22.437945",
         "description": "LOFAR Support Time",
-        "resource_unit": "http://localhost:3000/api/resource_unit/second/",
-        "resource_unit_id": "second",
         "tags": [
         ],
         "updated_at": "2020-07-29T07:31:22.437964",
-        "resourceUnit": {
-            "name": "second",
-            "url": "http://localhost:3000/api/resource_unit/second/",
-            "created_at": "2020-07-29T07:31:21.070088",
-            "description": "Unit of time or duration",
-            "tags": [
-            ],
-            "updated_at": "2020-07-29T07:31:21.070114"
-        }
+        "quantity_value": "time"
     },
     {
         "name": "LOFAR Support hours",
         "url": "http://localhost:3000/api/resource_type/LOFAR%20Support%20hours/",
         "created_at": "2020-07-29T07:31:22.571850",
         "description": "LOFAR Support hours",
-        "resource_unit": "http://localhost:3000/api/resource_unit/second/",
-        "resource_unit_id": "second",
         "tags": [
         ],
         "updated_at": "2020-07-29T07:31:22.571869",
-        "resourceUnit": {
-            "name": "second",
-            "url": "http://localhost:3000/api/resource_unit/second/",
-            "created_at": "2020-07-29T07:31:21.070088",
-            "description": "Unit of time or duration",
-            "tags": [
-            ],
-            "updated_at": "2020-07-29T07:31:21.070114"
-        }
+        "quantity_value": "time"
     },
     {
         "name": "Support hours",
         "url": "http://localhost:3000/api/resource_type/Support%20hours/",
         "created_at": "2020-07-29T07:31:22.694438",
         "description": "Support hours",
-        "resource_unit": "http://localhost:3000/api/resource_unit/second/",
-        "resource_unit_id": "second",
         "tags": [
         ],
         "updated_at": "2020-07-29T07:31:22.694514",
-        "resourceUnit": {
-            "name": "second",
-            "url": "http://localhost:3000/api/resource_unit/second/",
-            "created_at": "2020-07-29T07:31:21.070088",
-            "description": "Unit of time or duration",
-            "tags": [
-            ],
-            "updated_at": "2020-07-29T07:31:21.070114"
-        }
+        "quantity_value": "time"
     }
     ],
     projectResourceDefaults: {
@@ -212,7 +122,7 @@ const ProjectServiceMock= {
         "private_data": true,
         "project_category": "Regular",
         "project_category_value": "Regular",
-        "project_quota": [
+        "quota": [
           "http://192.168.99.100:8008/api/project_quota/70/",
           "http://192.168.99.100:8008/api/project_quota/71/",
           "http://192.168.99.100:8008/api/project_quota/72/",
@@ -222,7 +132,7 @@ const ProjectServiceMock= {
           "http://192.168.99.100:8008/api/project_quota/76/",
           "http://192.168.99.100:8008/api/project_quota/77/"
         ],
-        "project_quota_ids": [
+        "quota_ids": [
           70,
           71,
           72,
@@ -307,9 +217,117 @@ const ProjectServiceMock= {
           "project_id": "OSR-11",
           "resource_type": "http://192.168.99.100:8008/api/resource_type/Support%20hours/",
           "resource_type_id": "Support hours",
-          "value": 8
+          "value": 32400
         }
-      ]
+      ],
+    projectList: [
+      {
+        "name": "OSR-01",
+        "url": "http://192.168.99.100:8008/api/project/OSR-01",
+        "can_trigger": false,
+        "created_at": "2020-08-25T14:29:04.881620",
+        "cycles": [
+          "http://192.168.99.100:8008/api/cycle/Cycle%2014"
+        ],
+        "cycles_ids": [
+          "Cycle 14"
+        ],
+        "description": "OSR-01",
+        "expert": false,
+        "filler": false,
+        "period_category": "http://192.168.99.100:8008/api/period_category/single_cycle",
+        "period_category_value": "single_cycle",
+        "priority_rank": 1,
+        "private_data": true,
+        "project_category": "http://192.168.99.100:8008/api/project_category/regular",
+        "project_category_value": "regular",
+        "quota": [
+          "http://192.168.99.100:8008/api/project_quota/1",
+          "http://192.168.99.100:8008/api/project_quota/2",
+          "http://192.168.99.100:8008/api/project_quota/3",
+          "http://192.168.99.100:8008/api/project_quota/4",
+          "http://192.168.99.100:8008/api/project_quota/5",
+          "http://192.168.99.100:8008/api/project_quota/6",
+          "http://192.168.99.100:8008/api/project_quota/7"
+        ],
+        "quota_ids": [
+          1,
+          2,
+          3,
+          4,
+          5,
+          6,
+          7
+        ],
+        "tags": [],
+        "trigger_priority": 1000,
+        "updated_at": "2020-08-25T14:29:04.881640"
+      },
+      {
+        "name": "OSR-02",
+        "url": "http://192.168.99.100:8008/api/project/OSR-02",
+        "can_trigger": false,
+        "created_at": "2020-08-28T07:52:07.411136",
+        "cycles": [],
+        "cycles_ids": [],
+        "description": "OSR-02",
+        "expert": false,
+        "filler": false,
+        "period_category": null,
+        "period_category_value": null,
+        "priority_rank": 1,
+        "private_data": true,
+        "project_category": null,
+        "project_category_value": null,
+        "quota": [
+          "http://192.168.99.100:8008/api/project_quota/8",
+          "http://192.168.99.100:8008/api/project_quota/9",
+          "http://192.168.99.100:8008/api/project_quota/10",
+          "http://192.168.99.100:8008/api/project_quota/11",
+          "http://192.168.99.100:8008/api/project_quota/12",
+          "http://192.168.99.100:8008/api/project_quota/13",
+          "http://192.168.99.100:8008/api/project_quota/14"
+        ],
+        "quota_ids": [
+          8,
+          9,
+          10,
+          11,
+          12,
+          13,
+          14
+        ],
+        "tags": [],
+        "trigger_priority": 1000,
+        "updated_at": "2020-08-28T07:52:07.411167"
+      },
+      {
+        "name": "TMSS-Commissioning",
+        "url": "http://192.168.99.100:8008/api/project/TMSS-Commissioning",
+        "can_trigger": false,
+        "created_at": "2020-08-25T13:28:34.760707",
+        "cycles": [
+          "http://192.168.99.100:8008/api/cycle/Cycle%2014"
+        ],
+        "cycles_ids": [
+          "Cycle 14"
+        ],
+        "description": "Project for all TMSS tests and commissioning",
+        "expert": true,
+        "filler": false,
+        "period_category": null,
+        "period_category_value": null,
+        "priority_rank": 1,
+        "private_data": true,
+        "project_category": null,
+        "project_category_value": null,
+        "quota": [],
+        "quota_ids": [],
+        "tags": [],
+        "trigger_priority": 1000,
+        "updated_at": "2020-08-25T13:28:34.760729"
+      }
+    ]
 }
 
 export default ProjectServiceMock;
\ No newline at end of file
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/__mocks__/scheduleunit.service.data.js b/SAS/TMSS/frontend/tmss_webapp/src/__mocks__/scheduleunit.service.data.js
new file mode 100644
index 0000000000000000000000000000000000000000..3dc1484cf61fa7e7f68250f0e986cbc794defd8f
--- /dev/null
+++ b/SAS/TMSS/frontend/tmss_webapp/src/__mocks__/scheduleunit.service.data.js
@@ -0,0 +1,753 @@
+const SUServiceMock= {
+    scheduleSetList: [
+        {
+          "id": 1,
+          "url": "http://192.168.99.100:8008/api/scheduling_set/1",
+          "created_at": "2020-08-25T13:28:42.045214",
+          "description": "",
+          "generator_doc": {},
+          "generator_source": null,
+          "generator_source_id": null,
+          "generator_template": "http://192.168.99.100:8008/api/generator_template/1",
+          "generator_template_id": 1,
+          "name": "Test Scheduling Set UC1 example 0",
+          "project": "http://192.168.99.100:8008/api/project/TMSS-Commissioning",
+          "project_id": "TMSS-Commissioning",
+          "scheduling_unit_drafts": [
+            "http://192.168.99.100:8008/api/scheduling_unit_draft/2",
+            "http://192.168.99.100:8008/api/scheduling_unit_draft/1"
+          ],
+          "scheduling_unit_drafts_ids": [
+            2,
+            1
+          ],
+          "tags": [
+            "TEST",
+            "UC1"
+          ],
+          "updated_at": "2020-08-25T13:28:42.047512"
+        },
+        {
+          "id": 2,
+          "url": "http://192.168.99.100:8008/api/scheduling_set/2",
+          "created_at": "2020-08-25T13:28:49.545042",
+          "description": "",
+          "generator_doc": {},
+          "generator_source": null,
+          "generator_source_id": null,
+          "generator_template": "http://192.168.99.100:8008/api/generator_template/2",
+          "generator_template_id": 2,
+          "name": "Test Scheduling Set UC1 example 1",
+          "project": "http://192.168.99.100:8008/api/project/TMSS-Commissioning",
+          "project_id": "TMSS-Commissioning",
+          "scheduling_unit_drafts": [
+            "http://192.168.99.100:8008/api/scheduling_unit_draft/4",
+            "http://192.168.99.100:8008/api/scheduling_unit_draft/3"
+          ],
+          "scheduling_unit_drafts_ids": [
+            4,
+            3
+          ],
+          "tags": [
+            "TEST",
+            "UC1"
+          ],
+          "updated_at": "2020-08-25T13:28:49.546151"
+        },
+        {
+          "id": 3,
+          "url": "http://192.168.99.100:8008/api/scheduling_set/3",
+          "created_at": "2020-08-25T13:28:57.025339",
+          "description": "",
+          "generator_doc": {},
+          "generator_source": null,
+          "generator_source_id": null,
+          "generator_template": "http://192.168.99.100:8008/api/generator_template/3",
+          "generator_template_id": 3,
+          "name": "Test Scheduling Set UC1 example 2",
+          "project": "http://192.168.99.100:8008/api/project/TMSS-Commissioning",
+          "project_id": "TMSS-Commissioning",
+          "scheduling_unit_drafts": [
+            "http://192.168.99.100:8008/api/scheduling_unit_draft/6",
+            "http://192.168.99.100:8008/api/scheduling_unit_draft/5"
+          ],
+          "scheduling_unit_drafts_ids": [
+            6,
+            5
+          ],
+          "tags": [
+            "TEST",
+            "UC1"
+          ],
+          "updated_at": "2020-08-25T13:28:57.026492"
+        }
+      ],
+    observStrategies: [
+        {
+          "id": 1,
+          "url": "http://192.168.99.100:8008/api/scheduling_unit_observing_strategy_template/1",
+          "created_at": "2020-08-25T13:28:33.974187",
+          "description": "UC1 observation strategy template",
+          "name": "UC1 observation strategy template",
+          "scheduling_unit_template": "http://192.168.99.100:8008/api/scheduling_unit_template/1",
+          "scheduling_unit_template_id": 1,
+          "tags": [
+            "UC1"
+          ],
+          "template": {
+            "tasks": {
+              "Pipeline 1": {
+                "tags": [],
+                "description": "Preprocessing Pipeline for Calibrator Observation 1",
+                "specifications_doc": {
+                  "flag": {
+                    "rfi_strategy": "auto",
+                    "outerchannels": true,
+                    "autocorrelations": true
+                  },
+                  "demix": {
+                    "sources": {},
+                    "time_steps": 10,
+                    "ignore_target": false,
+                    "frequency_steps": 64
+                  },
+                  "average": {
+                    "time_steps": 1,
+                    "frequency_steps": 4
+                  },
+                  "storagemanager": "dysco"
+                },
+                "specifications_template": "preprocessing schema"
+              },
+              "Pipeline 2": {
+                "tags": [],
+                "description": "Preprocessing Pipeline for Calibrator Observation 2",
+                "specifications_doc": {
+                  "flag": {
+                    "rfi_strategy": "auto",
+                    "outerchannels": true,
+                    "autocorrelations": true
+                  },
+                  "demix": {
+                    "sources": {},
+                    "time_steps": 10,
+                    "ignore_target": false,
+                    "frequency_steps": 64
+                  },
+                  "average": {
+                    "time_steps": 1,
+                    "frequency_steps": 4
+                  },
+                  "storagemanager": "dysco"
+                },
+                "specifications_template": "preprocessing schema"
+              },
+              "Pipeline SAP0": {
+                "tags": [],
+                "description": "Preprocessing Pipeline for Target Observation SAP0",
+                "specifications_doc": {
+                  "flag": {
+                    "rfi_strategy": "auto",
+                    "outerchannels": true,
+                    "autocorrelations": true
+                  },
+                  "demix": {
+                    "sources": {},
+                    "time_steps": 10,
+                    "ignore_target": false,
+                    "frequency_steps": 64
+                  },
+                  "average": {
+                    "time_steps": 1,
+                    "frequency_steps": 4
+                  },
+                  "storagemanager": "dysco"
+                },
+                "specifications_template": "preprocessing schema"
+              },
+              "Pipeline SAP1": {
+                "tags": [],
+                "description": "Preprocessing Pipeline for Target Observation SAP1",
+                "specifications_doc": {
+                  "flag": {
+                    "rfi_strategy": "auto",
+                    "outerchannels": true,
+                    "autocorrelations": true
+                  },
+                  "demix": {
+                    "sources": {},
+                    "time_steps": 10,
+                    "ignore_target": false,
+                    "frequency_steps": 64
+                  },
+                  "average": {
+                    "time_steps": 1,
+                    "frequency_steps": 4
+                  },
+                  "storagemanager": "dysco"
+                },
+                "specifications_template": "preprocessing schema"
+              },
+              "Target Observation": {
+                "tags": [],
+                "description": "Target Observation for UC1 HBA scheduling unit",
+                "specifications_doc": {
+                  "QA": {
+                    "plots": {
+                      "enabled": true,
+                      "autocorrelation": true,
+                      "crosscorrelation": true
+                    },
+                    "file_conversion": {
+                      "enabled": true,
+                      "nr_of_subbands": -1,
+                      "nr_of_timestamps": 256
+                    }
+                  },
+                  "SAPs": [
+                    {
+                      "name": "target0",
+                      "subbands": [
+                        349,
+                        372
+                      ],
+                      "digital_pointing": {
+                        "angle1": 3.9935314947195253,       
+                        "angle2": 0.5324708659626034,       
+                        "angle3": 24,
+                        "direction_type": "J2000"
+                      }
+                    },
+                    {
+                      "name": "target1",
+                      "subbands": [
+                        349,
+                        372
+                      ],
+                      "digital_pointing": {
+                        "angle1": 3.9935314947195253,       
+                        "angle2": 0.5324708659626034,       
+                        "angle3": 24,
+                        "direction_type": "J2000"
+                      }
+                    }
+                  ],
+                  "filter": "HBA_110_190",
+                  "duration": 28800,
+                  "stations": [
+                    {
+                      "group": "ALL",
+                      "min_stations": 1
+                    }
+                  ],
+                  "tile_beam": {
+                    "angle1": 5.324708659626033,        
+                    "angle2": 0.7099611546168045,       
+                    "angle3": 42,
+                    "direction_type": "J2000"
+                  },
+                  "correlator": {
+                    "storage_cluster": "CEP4",
+                    "integration_time": 1,
+                    "channels_per_subband": 64
+                  },
+                  "antenna_set": "HBA_DUAL_INNER"
+                },
+                "specifications_template": "observation schema"
+              },
+              "Calibrator Observation 1": {
+                "tags": [],
+                "description": "Calibrator Observation for UC1 HBA scheduling unit",
+                "specifications_doc": {
+                  "duration": 600,
+                  "pointing": {
+                    "angle1": 0,
+                    "angle2": 0,
+                    "angle3": 0,
+                    "direction_type": "J2000"
+                  },
+                  "autoselect": false
+                },
+                "specifications_template": "calibrator schema"
+              },
+              "Calibrator Observation 2": {
+                "tags": [],
+                "description": "Calibrator Observation for UC1 HBA scheduling unit",
+                "specifications_doc": {
+                  "duration": 600,
+                  "pointing": {
+                    "angle1": 0,
+                    "angle2": 0,
+                    "angle3": 0,
+                    "direction_type": "J2000"
+                  },
+                  "autoselect": false
+                },
+                "specifications_template": "calibrator schema"
+              }
+            },
+            "parameters": [
+              {
+                "name": "Target Pointing 0",
+                "refs": [
+                  "#/tasks/Target Observation/specifications_doc/SAPs/0/digital_pointing"
+                ]
+              },
+              {
+                "name": "Target Pointing 1",
+                "refs": [
+                  "#/tasks/Target Observation/specifications_doc/SAPs/1/digital_pointing"
+                ]
+              },
+              {
+                "name": "Tile Beam",
+                "refs": [
+                  "#/tasks/Target Observation/specifications_doc/tile_beam"
+                ]
+              }
+            ],
+            "task_relations": [
+              {
+                "tags": [],
+                "input": {
+                  "role": "input",
+                  "datatype": "visibilities"
+                },
+                "output": {
+                  "role": "correlator",
+                  "datatype": "visibilities"
+                },
+                "consumer": "Pipeline 1",
+                "producer": "Calibrator Observation 1",
+                "dataformat": "MeasurementSet",
+                "selection_doc": {},
+                "selection_template": "All"
+              },
+              {
+                "tags": [],
+                "input": {
+                  "role": "input",
+                  "datatype": "visibilities"
+                },
+                "output": {
+                  "role": "correlator",
+                  "datatype": "visibilities"
+                },
+                "consumer": "Pipeline 2",
+                "producer": "Calibrator Observation 2",
+                "dataformat": "MeasurementSet",
+                "selection_doc": {},
+                "selection_template": "All"
+              },
+              {
+                "tags": [],
+                "input": {
+                  "role": "input",
+                  "datatype": "visibilities"
+                },
+                "output": {
+                  "role": "correlator",
+                  "datatype": "visibilities"
+                },
+                "consumer": "Pipeline SAP0",
+                "producer": "Target Observation",
+                "dataformat": "MeasurementSet",
+                "selection_doc": {
+                  "sap": [
+                    0
+                  ]
+                },
+                "selection_template": "SAP"
+              },
+              {
+                "tags": [],
+                "input": {
+                  "role": "input",
+                  "datatype": "visibilities"
+                },
+                "output": {
+                  "role": "correlator",
+                  "datatype": "visibilities"
+                },
+                "consumer": "Pipeline SAP1",
+                "producer": "Target Observation",
+                "dataformat": "MeasurementSet",
+                "selection_doc": {
+                  "sap": [
+                    1
+                  ]
+                },
+                "selection_template": "SAP"
+              }
+            ],
+            "task_scheduling_relations": [
+              {
+                "first": "Calibrator Observation 1",
+                "second": "Target Observation",
+                "placement": "before",
+                "time_offset": 60
+              },
+              {
+                "first": "Calibrator Observation 2",
+                "second": "Target Observation",
+                "placement": "after",
+                "time_offset": 60
+              }
+            ]
+          },
+          "updated_at": "2020-08-25T13:28:33.974209",
+          "version": "0.1"
+        }
+      ],
+    schedulingUnitFromObservStrategy: {
+        "id": 1,
+        "url": "http://192.168.99.100:8008/api/scheduling_unit_draft/1",
+        "copies": null,
+        "copies_id": null,
+        "copy_reason": null,
+        "copy_reason_value": null,
+        "created_at": "2020-08-25T13:28:42.092602",
+        "description": "",
+        "duration": 30120,
+        "generator_instance_doc": null,
+        "name": "UC1 test scheduling unit 1.1",
+        "observation_strategy_template": "http://192.168.99.100:8008/api/scheduling_unit_observing_strategy_template/1",
+        "observation_strategy_template_id": 1,
+        "requirements_doc": {
+          "tasks": {
+            "Pipeline 1": {
+              "tags": [],
+              "description": "Preprocessing Pipeline for Calibrator Observation 1",
+              "specifications_doc": {
+                "flag": {
+                  "rfi_strategy": "auto",
+                  "outerchannels": true,
+                  "autocorrelations": true
+                },
+                "demix": {
+                  "sources": {},
+                  "time_steps": 10,
+                  "ignore_target": false,
+                  "frequency_steps": 64
+                },
+                "average": {
+                  "time_steps": 1,
+                  "frequency_steps": 4
+                },
+                "storagemanager": "dysco"
+              },
+              "specifications_template": "preprocessing schema"
+            },
+            "Pipeline 2": {
+              "tags": [],
+              "description": "Preprocessing Pipeline for Calibrator Observation 2",
+              "specifications_doc": {
+                "flag": {
+                  "rfi_strategy": "auto",
+                  "outerchannels": true,
+                  "autocorrelations": true
+                },
+                "demix": {
+                  "sources": {},
+                  "time_steps": 10,
+                  "ignore_target": false,
+                  "frequency_steps": 64
+                },
+                "average": {
+                  "time_steps": 1,
+                  "frequency_steps": 4
+                },
+                "storagemanager": "dysco"
+              },
+              "specifications_template": "preprocessing schema"
+            },
+            "Pipeline SAP0": {
+              "tags": [],
+              "description": "Preprocessing Pipeline for Target Observation SAP0",
+              "specifications_doc": {
+                "flag": {
+                  "rfi_strategy": "auto",
+                  "outerchannels": true,
+                  "autocorrelations": true
+                },
+                "demix": {
+                  "sources": {},
+                  "time_steps": 10,
+                  "ignore_target": false,
+                  "frequency_steps": 64
+                },
+                "average": {
+                  "time_steps": 1,
+                  "frequency_steps": 4
+                },
+                "storagemanager": "dysco"
+              },
+              "specifications_template": "preprocessing schema"
+            },
+            "Pipeline SAP1": {
+              "tags": [],
+              "description": "Preprocessing Pipeline for Target Observation SAP1",
+              "specifications_doc": {
+                "flag": {
+                  "rfi_strategy": "auto",
+                  "outerchannels": true,
+                  "autocorrelations": true
+                },
+                "demix": {
+                  "sources": {},
+                  "time_steps": 10,
+                  "ignore_target": false,
+                  "frequency_steps": 64
+                },
+                "average": {
+                  "time_steps": 1,
+                  "frequency_steps": 4
+                },
+                "storagemanager": "dysco"
+              },
+              "specifications_template": "preprocessing schema"
+            },
+            "Target Observation": {
+              "tags": [],
+              "description": "Target Observation for UC1 HBA scheduling unit",
+              "specifications_doc": {
+                "QA": {
+                  "plots": {
+                    "enabled": true,
+                    "autocorrelation": true,
+                    "crosscorrelation": true
+                  },
+                  "file_conversion": {
+                    "enabled": true,
+                    "nr_of_subbands": -1,
+                    "nr_of_timestamps": 256
+                  }
+                },
+                "SAPs": [
+                  {
+                    "name": "target0",
+                    "subbands": [
+                      349,
+                      372
+                    ],
+                    "digital_pointing": {
+                      "angle1": 3.9935314947195253,
+                      "angle2": 0.5324708659626034,
+                      "angle3": 24,
+                      "direction_type": "J2000"
+                    }
+                  },
+                  {
+                    "name": "target1",
+                    "subbands": [
+                      349,
+                      372
+                    ],
+                    "digital_pointing": {
+                      "angle1": 3.9935314947195253,
+                      "angle2": 0.5324708659626034,
+                      "angle3": 24,
+                      "direction_type": "J2000"
+                    }
+                  }
+                ],
+                "filter": "HBA_110_190",
+                "duration": 28800,
+                "stations": [
+                  {
+                    "group": "ALL",
+                    "min_stations": 1
+                  }
+                ],
+                "tile_beam": {
+                  "angle1": 5.324708659626033,
+                  "angle2": 0.7099611546168045,
+                  "angle3": 42,
+                  "direction_type": "J2000"
+                },
+                "correlator": {
+                  "storage_cluster": "CEP4",
+                  "integration_time": 1,
+                  "channels_per_subband": 64
+                },
+                "antenna_set": "HBA_DUAL_INNER"
+              },
+              "specifications_template": "observation schema"
+            },
+            "Calibrator Observation 1": {
+              "tags": [],
+              "description": "Calibrator Observation for UC1 HBA scheduling unit",
+              "specifications_doc": {
+                "duration": 600,
+                "pointing": {
+                  "angle1": 0,
+                  "angle2": 0,
+                  "angle3": 0,
+                  "direction_type": "J2000"
+                },
+                "autoselect": false
+              },
+              "specifications_template": "calibrator schema"
+            },
+            "Calibrator Observation 2": {
+              "tags": [],
+              "description": "Calibrator Observation for UC1 HBA scheduling unit",
+              "specifications_doc": {
+                "duration": 600,
+                "pointing": {
+                  "angle1": 0,
+                  "angle2": 0,
+                  "angle3": 0,
+                  "direction_type": "J2000"
+                },
+                "autoselect": false
+              },
+              "specifications_template": "calibrator schema"
+            }
+          },
+          "parameters": [
+            {
+              "name": "Target Pointing 0",
+              "refs": [
+                "#/tasks/Target Observation/specifications_doc/SAPs/0/digital_pointing"
+              ]
+            },
+            {
+              "name": "Target Pointing 1",
+              "refs": [
+                "#/tasks/Target Observation/specifications_doc/SAPs/1/digital_pointing"
+              ]
+            },
+            {
+              "name": "Tile Beam",
+              "refs": [
+                "#/tasks/Target Observation/specifications_doc/tile_beam"
+              ]
+            }
+          ],
+          "task_relations": [
+            {
+              "tags": [],
+              "input": {
+                "role": "input",
+                "datatype": "visibilities"
+              },
+              "output": {
+                "role": "correlator",
+                "datatype": "visibilities"
+              },
+              "consumer": "Pipeline 1",
+              "producer": "Calibrator Observation 1",
+              "dataformat": "MeasurementSet",
+              "selection_doc": {},
+              "selection_template": "All"
+            },
+            {
+              "tags": [],
+              "input": {
+                "role": "input",
+                "datatype": "visibilities"
+              },
+              "output": {
+                "role": "correlator",
+                "datatype": "visibilities"
+              },
+              "consumer": "Pipeline 2",
+              "producer": "Calibrator Observation 2",
+              "dataformat": "MeasurementSet",
+              "selection_doc": {},
+              "selection_template": "All"
+            },
+            {
+              "tags": [],
+              "input": {
+                "role": "input",
+                "datatype": "visibilities"
+              },
+              "output": {
+                "role": "correlator",
+                "datatype": "visibilities"
+              },
+              "consumer": "Pipeline SAP0",
+              "producer": "Target Observation",
+              "dataformat": "MeasurementSet",
+              "selection_doc": {
+                "sap": [
+                  0
+                ]
+              },
+              "selection_template": "SAP"
+            },
+            {
+              "tags": [],
+              "input": {
+                "role": "input",
+                "datatype": "visibilities"
+              },
+              "output": {
+                "role": "correlator",
+                "datatype": "visibilities"
+              },
+              "consumer": "Pipeline SAP1",
+              "producer": "Target Observation",
+              "dataformat": "MeasurementSet",
+              "selection_doc": {
+                "sap": [
+                  1
+                ]
+              },
+              "selection_template": "SAP"
+            }
+          ],
+          "task_scheduling_relations": [
+            {
+              "first": "Calibrator Observation 1",
+              "second": "Target Observation",
+              "placement": "before",
+              "time_offset": 60
+            },
+            {
+              "first": "Calibrator Observation 2",
+              "second": "Target Observation",
+              "placement": "after",
+              "time_offset": 60
+            }
+          ]
+        },
+        "requirements_template": "http://192.168.99.100:8008/api/scheduling_unit_template/1",
+        "requirements_template_id": 1,
+        "scheduling_set": "http://192.168.99.100:8008/api/scheduling_set/1",
+        "scheduling_set_id": 1,
+        "scheduling_unit_blueprints": [
+          "http://192.168.99.100:8008/api/scheduling_unit_blueprint/1"
+        ],
+        "scheduling_unit_blueprints_ids": [
+          1
+        ],
+        "tags": [
+          "TEST",
+          "UC1"
+        ],
+        "task_drafts": [
+          "http://192.168.99.100:8008/api/task_draft/5",
+          "http://192.168.99.100:8008/api/task_draft/7",
+          "http://192.168.99.100:8008/api/task_draft/6",
+          "http://192.168.99.100:8008/api/task_draft/4",
+          "http://192.168.99.100:8008/api/task_draft/3",
+          "http://192.168.99.100:8008/api/task_draft/2",
+          "http://192.168.99.100:8008/api/task_draft/1"
+        ],
+        "task_drafts_ids": [
+          5,
+          7,
+          6,
+          4,
+          3,
+          2,
+          1
+        ],
+        "updated_at": "2020-08-25T13:28:42.119417"
+      }
+};
+
+export default SUServiceMock;
\ No newline at end of file
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/__mocks__/task.service.data.js b/SAS/TMSS/frontend/tmss_webapp/src/__mocks__/task.service.data.js
new file mode 100644
index 0000000000000000000000000000000000000000..6b7abd1e336416472b6360461fdbd23345871d7e
--- /dev/null
+++ b/SAS/TMSS/frontend/tmss_webapp/src/__mocks__/task.service.data.js
@@ -0,0 +1,676 @@
+const TaskServiceMock= {
+    taskTemplates: [
+        {
+          "id": 1,
+          "url": "http://192.168.99.100:8008/api/task_template/1",
+          "created_at": "2020-08-25T13:28:33.979487",
+          "description": "preprocessing settings",
+          "name": "preprocessing schema",
+          "schema": {
+            "$id": "http://example.com/example.json",
+            "type": "object",
+            "$schema": "http://json-schema.org/draft-06/schema#",
+            "required": [
+              "storagemanager"
+            ],
+            "properties": {
+              "flag": {
+                "type": "object",
+                "title": "Flagging",
+                "default": {},
+                "required": [
+                  "outerchannels",
+                  "autocorrelations",
+                  "rfi_strategy"
+                ],
+                "properties": {
+                  "rfi_strategy": {
+                    "enum": [
+                      "none",
+                      "auto",
+                      "HBAdefault",
+                      "LBAdefault"
+                    ],
+                    "type": "string",
+                    "title": "RFI flagging strategy",
+                    "default": "auto"
+                  },
+                  "outerchannels": {
+                    "type": "boolean",
+                    "title": "Flag outer channels",
+                    "default": true
+                  },
+                  "autocorrelations": {
+                    "type": "boolean",
+                    "title": "Flag auto correlations",
+                    "default": true
+                  }
+                },
+                "additionalProperties": false
+              },
+              "demix": {
+                "type": "object",
+                "title": "Demixing",
+                "default": {},
+                "options": {
+                  "dependencies": {
+                    "demix": true
+                  }
+                },
+                "required": [
+                  "frequency_steps",
+                  "time_steps",
+                  "ignore_target",
+                  "sources"
+                ],
+                "properties": {
+                  "sources": {
+                    "type": "object",
+                    "title": "Sources",
+                    "default": {},
+                    "properties": {
+                      "CasA": {
+                        "$ref": "#/definitions/demix_strategy",
+                        "title": "CasA"
+                      },
+                      "CygA": {
+                        "$ref": "#/definitions/demix_strategy",
+                        "title": "CygA"
+                      },
+                      "HerA": {
+                        "$ref": "#/definitions/demix_strategy",
+                        "title": "HerA"
+                      },
+                      "TauA": {
+                        "$ref": "#/definitions/demix_strategy",
+                        "title": "TauA"
+                      },
+                      "VirA": {
+                        "$ref": "#/definitions/demix_strategy",
+                        "title": "VirA"
+                      },
+                      "HydraA": {
+                        "$ref": "#/definitions/demix_strategy",
+                        "title": "HyrdraA"
+                      }
+                    },
+                    "additionalProperties": false
+                  },
+                  "time_steps": {
+                    "type": "integer",
+                    "title": "Time steps",
+                    "default": 10,
+                    "minimum": 1,
+                    "description": "Must be a multiple of the averaging time steps"
+                  },
+                  "ignore_target": {
+                    "type": "boolean",
+                    "title": "Ignore target",
+                    "default": false
+                  },
+                  "frequency_steps": {
+                    "type": "integer",
+                    "title": "Frequency steps",
+                    "default": 64,
+                    "minimum": 1,
+                    "description": "Must be a multiple of the averaging frequency steps"
+                  }
+                },
+                "additionalProperties": false
+              },
+              "average": {
+                "type": "object",
+                "title": "Averaging",
+                "default": {},
+                "required": [
+                  "frequency_steps",
+                  "time_steps"
+                ],
+                "properties": {
+                  "time_steps": {
+                    "type": "integer",
+                    "title": "Time steps",
+                    "default": 1,
+                    "minimum": 1
+                  },
+                  "frequency_steps": {
+                    "type": "integer",
+                    "title": "Frequency steps",
+                    "default": 4,
+                    "minimum": 1
+                  }
+                },
+                "additionalProperties": false
+              },
+              "storagemanager": {
+                "enum": [
+                  "basic",
+                  "dysco"
+                ],
+                "type": "string",
+                "title": "Storage Manager",
+                "default": "dysco"
+              }
+            },
+            "definitions": {
+              "demix_strategy": {
+                "enum": [
+                  "auto",
+                  "yes",
+                  "no"
+                ],
+                "type": "string",
+                "default": "auto"
+              }
+            },
+            "additionalProperties": false
+          },
+          "tags": [],
+          "type": "http://192.168.99.100:8008/api/task_type/pipeline",
+          "type_value": "pipeline",
+          "updated_at": "2020-08-25T13:28:33.979514",
+          "validation_code_js": "",
+          "version": "0.1"
+        },
+        {
+          "id": 2,
+          "url": "http://192.168.99.100:8008/api/task_template/2",
+          "created_at": "2020-08-25T13:28:33.983945",
+          "description": "schema for observations",
+          "name": "observation schema",
+          "schema": {
+            "$id": "http://example.com/example.json",
+            "type": "object",
+            "$schema": "http://json-schema.org/draft-06/schema#",
+            "required": [
+              "stations",
+              "antenna_set",
+              "filter",
+              "SAPs",
+              "duration",
+              "correlator"
+            ],
+            "properties": {
+              "QA": {
+                "type": "object",
+                "title": "Quality Assurance",
+                "default": {},
+                "properties": {
+                  "plots": {
+                    "type": "object",
+                    "title": "Plots",
+                    "default": {},
+                    "properties": {
+                      "enabled": {
+                        "type": "boolean",
+                        "title": "enabled",
+                        "default": true,
+                        "description": "Do/Don't create plots from the QA file from the observation"
+                      },
+                      "autocorrelation": {
+                        "type": "boolean",
+                        "title": "autocorrelation",
+                        "default": true,
+                        "description": "Create autocorrelation plots for all stations"
+                      },
+                      "crosscorrelation": {
+                        "type": "boolean",
+                        "title": "crosscorrelation",
+                        "default": true,
+                        "description": "Create crosscorrelation plots for all baselines"
+                      }
+                    },
+                    "description": "Create dynamic spectrum plots",
+                    "additionalProperties": false
+                  },
+                  "file_conversion": {
+                    "type": "object",
+                    "title": "File Conversion",
+                    "default": {},
+                    "properties": {
+                      "enabled": {
+                        "type": "boolean",
+                        "title": "enabled",
+                        "default": true,
+                        "description": "Do/Don't create a QA file for the observation"
+                      },
+                      "nr_of_subbands": {
+                        "type": "integer",
+                        "title": "#subbands",
+                        "default": -1,
+                        "description": "Keep this number of subbands from the observation in the QA file, or all if -1"
+                      },
+                      "nr_of_timestamps": {
+                        "type": "integer",
+                        "title": "#timestamps",
+                        "default": 256,
+                        "minimum": 1,
+                        "description": "Extract this number of timestamps from the observation in the QA file (equidistantanly sampled, no averaging/interpolation)"
+                      }
+                    },
+                    "description": "Create a QA file for the observation",
+                    "additionalProperties": false
+                  }
+                },
+                "description": "Specify Quality Assurance steps for this observation",
+                "additionalProperties": false
+              },
+              "SAPs": {
+                "type": "array",
+                "items": {
+                  "type": "object",
+                  "title": "SAP",
+                  "default": {},
+                  "required": [
+                    "digital_pointing",
+                    "subbands"
+                  ],
+                  "properties": {
+                    "name": {
+                      "type": "string",
+                      "title": "Name/target",
+                      "default": "",
+                      "description": "Identifier for this beam"
+                    },
+                    "subbands": {
+                      "type": "array",
+                      "items": {
+                        "type": "integer",
+                        "title": "Subband",
+                        "maximum": 511,
+                        "minimum": 0
+                      },
+                      "title": "Subband list",
+                      "default": [],
+                      "additionalItems": false
+                    },
+                    "digital_pointing": {
+                      "$ref": "#/definitions/pointing",
+                      "title": "Digital pointing",
+                      "default": {}
+                    }
+                  },
+                  "headerTemplate": "{{ i0 }} - {{ self.name }}",
+                  "additionalProperties": false
+                },
+                "title": "SAPs",
+                "default": [
+                  {}
+                ],
+                "description": "Station beams",
+                "additionalItems": false
+              },
+              "filter": {
+                "enum": [
+                  "LBA_10_70",
+                  "LBA_30_70",
+                  "LBA_10_90",
+                  "LBA_30_90",
+                  "HBA_110_190",
+                  "HBA_210_250"
+                ],
+                "type": "string",
+                "title": "Band-pass filter",
+                "default": "HBA_110_190",
+                "description": "Must match antenna type"
+              },
+              "duration": {
+                "type": "number",
+                "title": "Duration (seconds)",
+                "default": 300,
+                "minimum": 1,
+                "description": "Duration of this observation"
+              },
+              "stations": {
+                "oneOf": [
+                  {
+                    "type": "array",
+                    "items": {
+                      "enum": [
+                        "CS001",
+                        "CS002",
+                        "CS003",
+                        "CS004",
+                        "CS005",
+                        "CS006",
+                        "CS007",
+                        "CS011",
+                        "CS013",
+                        "CS017",
+                        "CS021",
+                        "CS024",
+                        "CS026",
+                        "CS028",
+                        "CS030",
+                        "CS031",
+                        "CS032",
+                        "CS101",
+                        "CS103",
+                        "CS201",
+                        "CS301",
+                        "CS302",
+                        "CS401",
+                        "CS501",
+                        "RS104",
+                        "RS106",
+                        "RS205",
+                        "RS208",
+                        "RS210",
+                        "RS305",
+                        "RS306",
+                        "RS307",
+                        "RS310",
+                        "RS406",
+                        "RS407",
+                        "RS409",
+                        "RS410",
+                        "RS503",
+                        "RS508",
+                        "RS509",
+                        "DE601",
+                        "DE602",
+                        "DE603",
+                        "DE604",
+                        "DE605",
+                        "FR606",
+                        "SE607",
+                        "UK608",
+                        "DE609",
+                        "PL610",
+                        "PL611",
+                        "PL612",
+                        "IE613",
+                        "LV614"
+                      ],
+                      "type": "string",
+                      "title": "Station",
+                      "description": ""
+                    },
+                    "title": "Fixed list",
+                    "default": [
+                      "CS001"
+                    ],
+                    "minItems": 1,
+                    "uniqueItems": true,
+                    "additionalItems": false,
+                    "additionalProperties": false
+                  },
+                  {
+                    "type": "array",
+                    "items": {
+                      "type": "object",
+                      "title": "Station set",
+                      "required": [
+                        "group",
+                        "min_stations"
+                      ],
+                      "properties": {
+                        "group": {
+                          "enum": [
+                            "ALL",
+                            "SUPERTERP",
+                            "CORE",
+                            "REMOTE",
+                            "DUTCH",
+                            "INTERNATIONAL"
+                          ],
+                          "type": "string",
+                          "title": "Group/station",
+                          "default": "ALL",
+                          "description": "Which (group of) station(s) to select from"
+                        },
+                        "min_stations": {
+                          "type": "integer",
+                          "title": "Minimum nr of stations",
+                          "default": 1,
+                          "minimum": 0,
+                          "description": "Number of stations to use within group/station"
+                        }
+                      },
+                      "headerTemplate": "{{ self.group }}",
+                      "additionalProperties": false
+                    },
+                    "title": "Dynamic list",
+                    "default": [
+                      {}
+                    ],
+                    "additionalItems": false
+                  }
+                ],
+                "title": "Station list",
+                "default": [
+                  "CS001"
+                ]
+              },
+              "tile_beam": {
+                "$ref": "#/definitions/pointing",
+                "title": "Tile beam",
+                "description": "HBA only"
+              },
+              "correlator": {
+                "type": "object",
+                "title": "Correlator Settings",
+                "default": {},
+                "required": [
+                  "channels_per_subband",
+                  "integration_time",
+                  "storage_cluster"
+                ],
+                "properties": {
+                  "storage_cluster": {
+                    "enum": [
+                      "CEP4",
+                      "DragNet"
+                    ],
+                    "type": "string",
+                    "title": "Storage cluster",
+                    "default": "CEP4",
+                    "description": "Cluster to write output to"
+                  },
+                  "integration_time": {
+                    "type": "number",
+                    "title": "Integration time (seconds)",
+                    "default": 1,
+                    "minimum": 0.1,
+                    "description": "Desired integration period"
+                  },
+                  "channels_per_subband": {
+                    "enum": [
+                      8,
+                      16,
+                      32,
+                      64,
+                      128,
+                      256,
+                      512,
+                      1024
+                    ],
+                    "type": "integer",
+                    "title": "Channels/subband",
+                    "default": 64,
+                    "minimum": 8,
+                    "description": "Number of frequency bands per subband"
+                  }
+                },
+                "additionalProperties": false
+              },
+              "antenna_set": {
+                "enum": [
+                  "HBA_DUAL",
+                  "HBA_DUAL_INNER",
+                  "HBA_ONE",
+                  "HBA_ONE_INNER",
+                  "HBA_ZERO",
+                  "HBA_ZERO_INNER",
+                  "LBA_INNER",
+                  "LBA_OUTER",
+                  "LBA_SPARSE_EVEN",
+                  "LBA_SPARSE_ODD",
+                  "LBA_ALL"
+                ],
+                "type": "string",
+                "title": "Antenna set",
+                "default": "HBA_DUAL",
+                "description": "Fields & antennas to use"
+              }
+            },
+            "definitions": {
+              "pointing": {
+                "type": "object",
+                "required": [
+                  "angle1",
+                  "angle2"
+                ],
+                "properties": {
+                  "angle1": {
+                    "type": "number",
+                    "title": "Angle 1",
+                    "default": 0,
+                    "description": "First angle (e.g. RA)"
+                  },
+                  "angle2": {
+                    "type": "number",
+                    "title": "Angle 2",
+                    "default": 0,
+                    "description": "Second angle (e.g. DEC)"
+                  },
+                  "angle3": {
+                    "type": "number",
+                    "title": "Angle 3",
+                    "default": 0,
+                    "description": "Third angle (e.g. N in LMN)"
+                  },
+                  "direction_type": {
+                    "enum": [
+                      "J2000",
+                      "AZELGEO",
+                      "LMN",
+                      "SUN",
+                      "MOON",
+                      "MERCURY",
+                      "VENUS",
+                      "MARS",
+                      "JUPITER",
+                      "SATURN",
+                      "URANUS",
+                      "NEPTUNE",
+                      "PLUTO"
+                    ],
+                    "type": "string",
+                    "title": "Reference frame",
+                    "default": "J2000",
+                    "description": ""
+                  }
+                },
+                "additionalProperties": false
+              }
+            },
+            "additionalProperties": false
+          },
+          "tags": [],
+          "type": "http://192.168.99.100:8008/api/task_type/observation",
+          "type_value": "observation",
+          "updated_at": "2020-08-25T13:28:33.983964",
+          "validation_code_js": "",
+          "version": "0.1"
+        },
+        {
+          "id": 3,
+          "url": "http://192.168.99.100:8008/api/task_template/3",
+          "created_at": "2020-08-25T13:28:33.988294",
+          "description": "addon schema for calibrator observations",
+          "name": "calibrator schema",
+          "schema": {
+            "$id": "http://example.com/example.json",
+            "type": "object",
+            "$schema": "http://json-schema.org/draft-06/schema#",
+            "required": [
+              "autoselect",
+              "duration",
+              "pointing"
+            ],
+            "properties": {
+              "duration": {
+                "type": "number",
+                "title": "Duration (seconds)",
+                "default": 600,
+                "minimum": 1,
+                "description": "Duration of this observation"
+              },
+              "pointing": {
+                "$ref": "#/definitions/pointing",
+                "title": "Digital pointing",
+                "default": {},
+                "description": "Manually selected calibrator"
+              },
+              "autoselect": {
+                "type": "boolean",
+                "title": "Auto-select",
+                "default": true,
+                "description": "Auto-select calibrator based on elevation"
+              }
+            },
+            "definitions": {
+              "pointing": {
+                "type": "object",
+                "required": [
+                  "angle1",
+                  "angle2"
+                ],
+                "properties": {
+                  "angle1": {
+                    "type": "number",
+                    "title": "Angle 1",
+                    "default": 0,
+                    "description": "First angle [rad] (e.g. RA)"
+                  },
+                  "angle2": {
+                    "type": "number",
+                    "title": "Angle 2",
+                    "default": 0,
+                    "description": "Second angle [rad] (e.g. DEC)"
+                  },
+                  "angle3": {
+                    "type": "number",
+                    "title": "Angle 3",
+                    "default": 0,
+                    "description": "Third angle [rad] (e.g. N in LMN)"
+                  },
+                  "direction_type": {
+                    "enum": [
+                      "J2000",
+                      "AZELGEO",
+                      "LMN",
+                      "SUN",
+                      "MOON",
+                      "MERCURY",
+                      "VENUS",
+                      "MARS",
+                      "JUPITER",
+                      "SATURN",
+                      "URANUS",
+                      "NEPTUNE",
+                      "PLUTO"
+                    ],
+                    "type": "string",
+                    "title": "Reference frame",
+                    "default": "J2000",
+                    "description": ""
+                  }
+                },
+                "additionalProperties": false
+              }
+            },
+            "additionalProperties": false
+          },
+          "tags": [],
+          "type": "http://192.168.99.100:8008/api/task_type/observation",
+          "type_value": "observation",
+          "updated_at": "2020-08-25T13:28:33.988312",
+          "validation_code_js": "",
+          "version": "0.1"
+        }
+      ]
+};
+
+export default TaskServiceMock;
\ No newline at end of file
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/layout/_overrides.scss b/SAS/TMSS/frontend/tmss_webapp/src/layout/_overrides.scss
index ddf77d3e4b228914fd7fc97e74cb11820d821755..0fd0c0c45c82a891cf3f768fdaa0e1850baa130d 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/layout/_overrides.scss
+++ b/SAS/TMSS/frontend/tmss_webapp/src/layout/_overrides.scss
@@ -22,4 +22,4 @@
    .layout-sidebar-dark .layout-menu li a    {
     border-top: none;
    }
-}
\ No newline at end of file
+}
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/layout/components/AppBreadcrumb.js b/SAS/TMSS/frontend/tmss_webapp/src/layout/components/AppBreadcrumb.js
index 0abba394b1c1190aa1c84bf7ec20af19f97c720c..7c966d34bb8190efdab77a9c5211691f48ce2a77 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/layout/components/AppBreadcrumb.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/layout/components/AppBreadcrumb.js
@@ -27,11 +27,13 @@ export class AppBreadcrumb extends Component {
 
     onRoute() {
         const { breadcrumbs } = this.state;
+        const { setPageTitle } = this.props;
         const currentRoute = routes.find(route => matchPath(this.props.location.pathname, {path: route.path, exact: true, strict: true}));
 		//for intial route ,there wont be any route object so it failed 
 		if(!currentRoute){
 			return;
-		}
+        }
+        setPageTitle(currentRoute.pageTitle);
         if (!breadcrumbs.length) {
             this.setState({ breadcrumbs: [{...this.props.location, name: currentRoute.name}] });
             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
new file mode 100644
index 0000000000000000000000000000000000000000..0c7274c3471c957a2b2d961eade605d8a444d1bd
--- /dev/null
+++ b/SAS/TMSS/frontend/tmss_webapp/src/layout/components/PageHeader.js
@@ -0,0 +1,63 @@
+import React, { useEffect, useState } from 'react';
+import { routes } from '../../routes';
+import {matchPath, Link} from 'react-router-dom';
+
+export default ({ title, subTitle, actions, ...props}) => {
+    const [page, setPage] = useState({});
+
+    useEffect(() => {
+        const currentRoute = routes.find(route => matchPath(props.location.pathname, {path: route.path, exact: true, strict: true}));
+		//for intial route ,there wont be any route object so it failed 
+		if(!currentRoute){
+			return;
+        }
+        setPage(currentRoute);
+    }, [props.location.pathname]);
+
+    const onClickLink = (action) => {
+        console.log('Hi')
+        if (action.link) {
+            action.link();
+        }
+    };
+
+    const onButtonClick = (e, action) => {
+        if (action.actOn && action.actOn === 'click') {
+            action.props.callback(e);
+        }
+    };
+
+    const onButtonMouseOver = (e, action) => {
+        if (action.actOn && action.actOn === 'mouseOver') {
+            action.props.callback(e);
+        }
+    }
+
+    return (
+        <div className="page-header">
+            <div className="title">
+                <h2 className="page-title">{title || page.title}</h2>
+                {(page.subTitle || subTitle) && <h6 className="page-subtitle">{subTitle || page.subTitle}</h6>}
+            </div>
+            <div className="page-action-menu">
+                {(actions || []).map(action => {
+                    if (action.type === 'button') {
+                        return (
+                            <button className="p-link">
+                                <i className={`fa ${action.icon}`}  
+                                    onMouseOver={(e) => onButtonMouseOver(e, action)}
+                                    onClick={(e) => onButtonClick(e, action)} />
+                            </button>
+                        );
+                    }   else {
+                        return (
+                            <Link to={{ ...action.props }} title={action.title || ''} onClick={() => onClickLink(action)}>
+                                <i className={`fa ${action.icon}`}></i>
+                            </Link>
+                        );
+                    }
+                })}
+            </div>
+        </div>
+    );
+}
\ No newline at end of file
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_layout.scss b/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_layout.scss
index 79f22ea107106c4e26e10b2cc375414ea77b293d..7f1c64219e88a4c1101b7d7b68dc20a6d7f19050 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_layout.scss
+++ b/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_layout.scss
@@ -12,3 +12,4 @@
 @import "./_dashboard";
 @import "./_breadcrumb";
 @import "./_viewtable";
+@import "./_pageheader";
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_pageheader.scss b/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_pageheader.scss
new file mode 100644
index 0000000000000000000000000000000000000000..32a00c556353bf9a2324cc7d421b1d627525f637
--- /dev/null
+++ b/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_pageheader.scss
@@ -0,0 +1,24 @@
+.page-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: baseline;
+    border-bottom: 1px solid #e0e0e0;
+    margin-bottom: 10px;
+    padding-bottom: 5px;
+}
+.page-title {
+    margin-bottom: 0;
+}
+.page-subtitle {
+    color: #b4b2b2;
+    font-size: 100%;
+    font-weight: 400;
+    margin-bottom: 0px;
+}
+.page-action-menu i {
+    margin-left: 5px;
+}
+
+.page-header .fa {
+    font-size: 25px !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 79ddd60b6b80b15e064ae8a60df296ff6b51674b..29568c138c88fc43d4cd37e7936f5b4a0b813db9 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/create.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/create.js
@@ -1,5 +1,5 @@
 import React, {Component} from 'react';
-import { Link, Redirect } from 'react-router-dom';
+import { Redirect } from 'react-router-dom';
 import {InputText} from 'primereact/inputtext';
 import {Calendar} from 'primereact/calendar';
 import {InputTextarea} from 'primereact/inputtextarea';
@@ -12,6 +12,7 @@ import moment from 'moment'
 import _ from 'lodash';
 
 import AppLoader from '../../layout/components/AppLoader';
+import PageHeader from '../../layout/components/PageHeader';
 import CycleService from '../../services/cycle.service';
 import UnitConverter from '../../utils/unit.converter';
 import UIConstants from '../../utils/ui.constants';
@@ -326,9 +327,8 @@ export class CycleCreate extends Component {
         
         return (
             <React.Fragment>
-                <div className="p-grid">
-                    <Growl ref={(el) => this.growl = el} />
-                
+                <Growl ref={(el) => this.growl = el} />
+               { /*<div className="p-grid">
                     <div className="p-col-10 p-lg-10 p-md-10">
                         <h2>Cycle - Add</h2>
                     </div>
@@ -337,7 +337,9 @@ export class CycleCreate extends Component {
                             <i className="fa fa-window-close" style={{marginTop: "10px"}}></i>
                         </Link>
                     </div>
-                </div>
+                </div> */ }
+                
+                <PageHeader location={this.props.location} title={'Cycle - Add'} actions={[{icon:'fa-window-close',title:'Click to Close Add Cycle',props:{pathname: '/cycle' }}]}/>
                 { this.state.isLoading ? <AppLoader /> :
                 <>
                 <div>
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 4d599c33ef64cd790084b5f0012a3c2ad3fde1e4..f0c8a30a14cf449356b2f4ae8872517d49e9a93e 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/edit.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/edit.js
@@ -1,5 +1,5 @@
 import React, {Component} from 'react';
-import { Link, Redirect } from 'react-router-dom';
+import { Redirect } from 'react-router-dom';
 import _ from 'lodash';
 import moment from 'moment'
 
@@ -14,6 +14,7 @@ import {Growl} from 'primereact/components/growl/Growl';
 import {ResourceInputList} from './ResourceInputList';
 
 import AppLoader from '../../layout/components/AppLoader';
+import PageHeader from '../../layout/components/PageHeader';
 import CycleService from '../../services/cycle.service';
 import UnitConverter from '../../utils/unit.converter';
 import UIConstants from '../../utils/ui.constants';
@@ -360,9 +361,9 @@ export class CycleEdit extends Component {
         }
         return (
             <React.Fragment>
-                <div className="p-grid">
-                    <Growl ref={(el) => this.growl = el} />
-                
+                <Growl ref={(el) => this.growl = el} />
+                {/*} <div className="p-grid">
+                    
                     <div className="p-col-10 p-lg-10 p-md-10">
                         <h2>Cycle - Edit</h2>
                     </div>
@@ -371,7 +372,8 @@ export class CycleEdit extends Component {
                             <i className="fa fa-window-close" style={{marginTop: "10px"}}></i>
                         </Link>
                     </div>
-                </div>
+                </div> */}
+                <PageHeader location={this.props.location} title={'Cycle - Edit'} actions={[{icon:'fa-window-close',title:'Click to Close Cycle-Edit', props:{ pathname: `/cycle/view/${this.state.cycle.name}`}}]}/>
 
                 { this.state.isLoading ? <AppLoader/> :
                 <>
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/list.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/list.js
index 6fe6f2cb46c4cd10e7e64362b08ad553f6e64b2e..e4438cfd5b9cc69ff7e2116bdb4bff0bd9acf7e8 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/list.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/list.js
@@ -1,12 +1,13 @@
 import React, { Component } from 'react'
 import 'primeflex/primeflex.css';
-import { Link } from 'react-router-dom/cjs/react-router-dom.min';
+// import { Link } from 'react-router-dom/cjs/react-router-dom.min';
 import _ from 'lodash';
 
 import ViewTable from '../../components/ViewTable';
 import CycleService from '../../services/cycle.service';
 import UnitConversion from '../../utils/unit.converter';
 import AppLoader from '../../layout/components/AppLoader';
+import PageHeader from '../../layout/components/PageHeader';
 
 class CycleList extends Component{
 	 constructor(props){
@@ -111,7 +112,7 @@ class CycleList extends Component{
 	render(){
         return (
             <>
-            <div className="p-grid">
+           { /*<div className="p-grid">
                     <div className="p-col-10 p-lg-10 p-md-10">
                         <h2>Cycle - List </h2>
                     </div>
@@ -120,7 +121,15 @@ class CycleList extends Component{
                             <i className="fa fa-plus-square" style={{marginTop: "10px"}}></i>
                         </Link>
                     </div>
-                </div>
+                </div> */}
+                {/*
+                    * Call View table to show table data, the parameters are,
+                    data - Pass API data
+                    defaultcolumns - This colum will be populate by default in table with header mentioned
+                    showaction - {true/false} -> to show the action column
+                    paths - specify the path for navigation - Table will set "id" value for each row in action button
+                */}
+                <PageHeader location={this.props.location} title={'Cycle - List'} actions={[{icon:'fa-plus-square',title:'Click to Add Cycle', props:{ pathname: '/cycle/create'}}]}/>
                 {/*
                     * Call View table to show table data, the parameters are,
                     data - Pass API data
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/view.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/view.js
index 55430cc1fd440589988e30d2a1e13aa1e91c4d51..3a311b921c0d62f1111badea3ce00d53117fb8d8 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/view.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/view.js
@@ -8,6 +8,7 @@ import { Chips } from 'primereact/chips';
 import ResourceDisplayList from './ResourceDisplayList';
 
 import AppLoader from '../../layout/components/AppLoader';
+import PageHeader from '../../layout/components/PageHeader';
 import CycleService from '../../services/cycle.service';
 import UnitConverter from '../../utils/unit.converter';
 
@@ -20,6 +21,7 @@ export class CycleView extends Component {
         super(props);
         this.state = {
             isLoading: true,
+            cycle:'',
         };
         if (this.props.match.params.id) {
             this.state.cycleId  = this.props.match.params.id;
@@ -75,7 +77,7 @@ export class CycleView extends Component {
         
         return (
             <React.Fragment>
-                <div className="p-grid">
+               {/* <div className="p-grid">
                     <div className="p-col-10 p-lg-10 p-md-10">
                         <h2>Cycle - Details </h2>
                     </div>
@@ -90,7 +92,11 @@ export class CycleView extends Component {
                         </Link>
                     </div>
                     }
-                </div>
+                </div> */ }
+                <PageHeader location={this.props.location} title={'Cycle - Details'} 
+                            actions={[ {icon:'fa-edit', title:'Click to Edit Cycle', props:{ pathname: `/cycle/edit/${this.state.cycle.name}`, 
+                                        state: {id: this.state.cycle?this.state.cycle.name:''}}},
+                                        {icon: 'fa-window-close',props:{ pathname: `/cycle`}}]}/>
                 { this.state.isLoading && <AppLoader /> }
                 { this.state.cycle &&
                     <React.Fragment>
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Dashboard/index.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Dashboard/index.js
index a0a798161d65edf83901902a88e3957569741bd8..409176dce304825d2cc252ec3482e0cec2ee2291 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Dashboard/index.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Dashboard/index.js
@@ -1,16 +1,14 @@
 import React, {Component} from 'react';
+import PageHeader from '../../layout/components/PageHeader';
 
 
 export class Dashboard extends Component {
 
-    constructor(props){
-        super(props)
-        console.log(this.props)
-    }
     render() {
+       
         return (
-            <h1>Dashboard</h1>
-        );
+            <PageHeader location={this.props.location} title={'Dashboard'} />
+        )
     }
 }
 
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/ResourceInputList.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/ResourceInputList.js
index c1d9019421ff16c5570e3371e8ff338342b404f7..3d6ead61a870c889a801b9093f6a19fa13e01d70 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/ResourceInputList.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/ResourceInputList.js
@@ -40,7 +40,8 @@ export class ResourceInputList extends Component {
                     <div key={'div1-'+ index} className="col-lg-3 col-md-3 col-sm-12">
                         <InputNumber key={'item1-'+ index} id={'item1-'+ index} name={'item1-'+ index}
                             suffix={` ${this.props.unitMap[item.quantity_value]?this.props.unitMap[item.quantity_value].display:''}`}
-                            placeholder={` ${this.props.unitMap[item.quantity_value]?this.props.unitMap[item.quantity_value].display:item.name}`} min={0} useGrouping={false}
+                            placeholder={` ${this.props.unitMap[item.quantity_value]?this.props.unitMap[item.quantity_value].display:item.name}`}
+                            inputId={`${item.name}`} min={0} useGrouping={false}
                             value={this.state.projectQuota[item.name]} 
                             onChange={(e) => this.onInputChange(item.name, e)}
                             onBlur={(e) => this.onInputChange(item.name, e)}
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 64a96b3f0a9b6ba7ff8a99cf52d416e0e49a23a0..bc55f4dd20415f977128ce93c86597967b440a99 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/create.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/create.js
@@ -1,5 +1,5 @@
 import React, {Component} from 'react';
-import { Link, Redirect } from 'react-router-dom';
+import { Redirect } from 'react-router-dom';
 import _ from 'lodash';
 
 import {InputText} from 'primereact/inputtext';
@@ -15,6 +15,7 @@ import {Growl} from 'primereact/components/growl/Growl';
 import {ResourceInputList} from './ResourceInputList';
 
 import AppLoader from '../../layout/components/AppLoader';
+import PageHeader from '../../layout/components/PageHeader';
 import CycleService from '../../services/cycle.service';
 import ProjectService from '../../services/project.service';
 import UnitConverter from '../../utils/unit.converter';
@@ -335,9 +336,9 @@ export class ProjectCreate extends Component {
         
         return (
             <React.Fragment>
-                <div className="p-grid">
-                    <Growl ref={(el) => this.growl = el} />
-                
+                <Growl ref={(el) => this.growl = el} />
+                { /* <div className="p-grid">
+                    
                     <div className="p-col-10 p-lg-10 p-md-10">
                         <h2>Project - Add</h2>
                     </div>
@@ -346,7 +347,8 @@ export class ProjectCreate extends Component {
                             <i className="fa fa-window-close" style={{marginTop: "10px"}}></i>
                         </Link>
                     </div>
-                </div>
+                 </div> */ }
+                 <PageHeader location={this.props.location} title={'Project - Add'} actions={[{icon:'fa-window-close',title:'Click to Close Project', props:{ pathname: '/project'}}]}/>
                 { this.state.isLoading ? <AppLoader /> :
                 <>
                 <div>
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/create.test.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/create.test.js
index 84c2b338449d107059e43fa4396dead622a042fe..7eccc6d8e8814da4fb5788fbb43c47527697d628 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/create.test.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/create.test.js
@@ -3,6 +3,7 @@ import { BrowserRouter as Router } from 'react-router-dom';
 import { act } from "react-dom/test-utils";
 import { render, cleanup, fireEvent } from '@testing-library/react';
 import '@testing-library/jest-dom/extend-expect';
+import _ from 'lodash';
 
 import {ProjectCreate} from './create';
 import ProjectService from '../../services/project.service';
@@ -65,6 +66,7 @@ it("renders without crashing with all back-end data loaded", async () => {
     await act(async () => {
         content = render(<Router><ProjectCreate /></Router>);
     });
+    const spinButtons = content.queryAllByRole("spinbutton");
     
     expect(content.queryByText('Project - Add')).not.toBe(null);        // Page loaded successfully
     expect(projectCategoriesSpy).toHaveBeenCalled();                    // Mock Spy called successfully
@@ -73,8 +75,8 @@ it("renders without crashing with all back-end data loaded", async () => {
     expect(content.queryByText('Cycle-0')).toBeInTheDocument();         // Cycle multi-select loaded successfully
     expect(content.queryAllByText('Add Resources').length).toBe(2);     // Resource Dropdown loaded successfully
     expect(content.queryByText('Support hours')).toBeInTheDocument();         // Resources other than Default Resources listed in dropdown
-    expect(content.queryByPlaceholderText('Support Hours')).toBe(null);       // No resources other than Default Resources listed to get input
-    expect(content.queryByPlaceholderText('LOFAR Observing Time').value).toBe('1 Hours');         // Default Resource Listed with default value
+    expect(_.filter(spinButtons, {"id": "Support hours"}).length).toBe(0);       // No resources other than Default Resources listed to get input
+    expect(_.filter(spinButtons, {"id": "LOFAR Observing Time"})[0].value).toBe('1 Hours');         // Default Resource Listed with default value
 });
 
 it("Save button disabled initially when no data entered", async () => {
@@ -222,31 +224,31 @@ it("save project with default resources", async () => {
     expect(content.queryByTestId('projectId').value).toBe("");
     expect(content.queryByText("Success")).toBe(null);
     
-    const lofarObsTimeInput = content.queryByPlaceholderText('LOFAR Observing Time');
+    const lofarObsTimeInput = _.filter(spinButtons, {"id": "LOFAR Observing Time"})[0];
     fireEvent.change(lofarObsTimeInput, { target: { value: 10 } });
     expect(lofarObsTimeInput.value).toBe('10');
     
-    const lofarObsTimeAInput = content.queryByPlaceholderText('LOFAR Observing Time prio A');
+    const lofarObsTimeAInput = _.filter(spinButtons, {"id": "LOFAR Observing Time prio A"})[0];
     fireEvent.change(lofarObsTimeAInput, { target: { value: 15 } });
     expect(lofarObsTimeAInput.value).toBe('15');
     
-    const lofarObsTimeBInput = content.queryByPlaceholderText('LOFAR Observing Time prio B');
+    const lofarObsTimeBInput = _.filter(spinButtons, {"id": "LOFAR Observing Time prio B"})[0];
     fireEvent.change(lofarObsTimeBInput, { target: { value: 20 } });
     expect(lofarObsTimeBInput.value).toBe('20');
     
-    const cepProcTimeInput = content.queryByPlaceholderText('CEP Processing Time');
+    const cepProcTimeInput = _.filter(spinButtons, {"id": "CEP Processing Time"})[0];
     fireEvent.change(cepProcTimeInput, { target: { value: 5 } });
     expect(cepProcTimeInput.value).toBe('5');
     
-    const ltaStorageInput = content.queryByPlaceholderText('LTA Storage');
+    const ltaStorageInput = _.filter(spinButtons, {"id": "LTA Storage"})[0];
     fireEvent.change(ltaStorageInput, { target: { value: 2 } });
     expect(ltaStorageInput.value).toBe('2');
     
-    const noOfTriggerInput = content.queryByPlaceholderText('Number of triggers');
+    const noOfTriggerInput = _.filter(spinButtons, {"id": "Number of triggers"})[0];
     fireEvent.change(noOfTriggerInput, { target: { value: 3 } });
     expect(noOfTriggerInput.value).toBe('3');
     
-    const lofarSupTimeInput = content.queryByPlaceholderText('LOFAR Support Time');
+    const lofarSupTimeInput = _.filter(spinButtons, {"id": "LOFAR Support Time"})[0];
     fireEvent.change(lofarSupTimeInput, { target: { value: 25 } });
     expect(lofarSupTimeInput.value).toBe('25');
     
@@ -268,7 +270,7 @@ it("save project with added resources", async () => {
 
     const nameInput = content.queryByTestId('name');
     const descInput = content.queryByTestId('description');
-    const spinButtons = content.queryAllByRole("spinbutton");
+    let spinButtons = content.queryAllByRole("spinbutton");
     const rankInput = spinButtons.filter(function(element) { return element.id==="proj-rank"})[0];
 
     fireEvent.change(nameInput, { target: { value: 'OSR' } });
@@ -281,31 +283,31 @@ it("save project with added resources", async () => {
     expect(content.queryByTestId('projectId').value).toBe("");
     expect(content.queryByText("Success")).toBe(null);
     
-    const lofarObsTimeInput = content.queryByPlaceholderText('LOFAR Observing Time');
+    const lofarObsTimeInput = _.filter(spinButtons, {"id": "LOFAR Observing Time"})[0];
     fireEvent.change(lofarObsTimeInput, { target: { value: 10 } });
     expect(lofarObsTimeInput.value).toBe('10');
     
-    const lofarObsTimeAInput = content.queryByPlaceholderText('LOFAR Observing Time prio A');
+    const lofarObsTimeAInput = _.filter(spinButtons, {"id": "LOFAR Observing Time prio A"})[0];
     fireEvent.change(lofarObsTimeAInput, { target: { value: 15 } });
     expect(lofarObsTimeAInput.value).toBe('15');
     
-    const lofarObsTimeBInput = content.queryByPlaceholderText('LOFAR Observing Time prio B');
+    const lofarObsTimeBInput = _.filter(spinButtons, {"id": "LOFAR Observing Time prio B"})[0];
     fireEvent.change(lofarObsTimeBInput, { target: { value: 20 } });
     expect(lofarObsTimeBInput.value).toBe('20');
     
-    const cepProcTimeInput = content.queryByPlaceholderText('CEP Processing Time');
+    const cepProcTimeInput = _.filter(spinButtons, {"id": "CEP Processing Time"})[0];
     fireEvent.change(cepProcTimeInput, { target: { value: 5 } });
     expect(cepProcTimeInput.value).toBe('5');
     
-    const ltaStorageInput = content.queryByPlaceholderText('LTA Storage');
+    const ltaStorageInput = _.filter(spinButtons, {"id": "LTA Storage"})[0];
     fireEvent.change(ltaStorageInput, { target: { value: 2 } });
     expect(ltaStorageInput.value).toBe('2');
     
-    const noOfTriggerInput = content.queryByPlaceholderText('Number of triggers');
+    const noOfTriggerInput = _.filter(spinButtons, {"id": "Number of triggers"})[0];
     fireEvent.change(noOfTriggerInput, { target: { value: 3 } });
     expect(noOfTriggerInput.value).toBe('3');
     
-    const lofarSupTimeInput = content.queryByPlaceholderText('LOFAR Support Time');
+    const lofarSupTimeInput = _.filter(spinButtons, {"id": "LOFAR Support Time"})[0];
     fireEvent.change(lofarSupTimeInput, { target: { value: 25 } });
     expect(lofarSupTimeInput.value).toBe('25');
     
@@ -313,7 +315,7 @@ it("save project with added resources", async () => {
     expect(content.queryAllByText('Add Resources').length).toBe(2);
     expect(content.queryAllByText('Support hours').length).toBe(1);
     expect(content.getAllByRole("listbox")[3].children.length).toBe(2);
-    expect(content.queryByPlaceholderText('Support hours')).toBe(null);
+    expect(_.filter(spinButtons, {"id": "Support hours"}).length).toBe(0);
     const addResourceInput = content.getAllByRole("listbox")[3].children[1] ;
     fireEvent.click(addResourceInput);
     // After selecting New Resource
@@ -323,9 +325,10 @@ it("save project with added resources", async () => {
     const addResourceBtn = content.queryByTestId('add_res_btn');
     fireEvent.click(addResourceBtn);
     expect(content.queryAllByText('Add Resources').length).toBe(2);
-    expect(content.queryByPlaceholderText('Support hours')).not.toBe(null);
+    spinButtons = content.queryAllByRole("spinbutton");
 
-    const newResourceInput = content.queryByPlaceholderText('Support hours');
+    const newResourceInput = _.filter(spinButtons, {"id": "Support hours"})[0];
+    expect(newResourceInput).not.toBe(null);
     fireEvent.change(newResourceInput, { target: { value: 30 } });
     expect(newResourceInput.value).toBe('30');
     
@@ -360,15 +363,18 @@ it("remove default resource and added resource", async () => {
     const addResourceBtn = content.queryByTestId('add_res_btn');
     fireEvent.click(addResourceBtn);
     expect(content.queryAllByText('Add Resources').length).toBe(2);
-    expect(content.queryByPlaceholderText('Support hours')).not.toBe(null);
 
-    expect(content.queryByPlaceholderText('CEP Processing Time')).not.toBe(null);
+    const spinButtons = content.queryAllByRole("spinbutton");
+    
+    expect(_.filter(spinButtons, {"id": "Support hours"})[0]).not.toBe(null);
+
+    expect(_.filter(spinButtons, {"id": "CEP Processing Time"})[0]).not.toBe(null);
     expect(content.queryByTestId('CEP Processing Time-btn')).not.toBe(null);
     const removeDefResBtn = content.queryByTestId('CEP Processing Time-btn');
     await act(async () => {
         fireEvent.click(content.queryByTestId('CEP Processing Time-btn'));
     });
-    expect(content.queryByPlaceholderText('CEP Processing Time')).toBe(null);
+    expect(_.filter(spinButtons, {"id": "CEP Processing Time"}).length).toBe(0);
     expect(content.queryByTestId('CEP Processing Time-btn')).toBe(null);
 
     const removeResourceBtn = content.queryByTestId('Support hours-btn');
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 78b443a5c2d1eb457b3806a0cc4fe89e3fd2ab99..a1f48c927de8d73a0acbd2090c0892ad09ed6896 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/edit.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/edit.js
@@ -1,5 +1,5 @@
 import React, {Component} from 'react';
-import { Link, Redirect } from 'react-router-dom';
+import { Redirect } from 'react-router-dom';
 import _ from 'lodash';
 
 import {InputText} from 'primereact/inputtext';
@@ -10,11 +10,12 @@ import {Dropdown} from 'primereact/dropdown';
 import {MultiSelect} from 'primereact/multiselect';
 import { Button } from 'primereact/button';
 import {Dialog} from 'primereact/components/dialog/Dialog';
-import {Growl} from 'primereact/components/growl/Growl';
+//import {Growl} from 'primereact/components/growl/Growl';
 
 import {ResourceInputList} from './ResourceInputList';
 
 import AppLoader from '../../layout/components/AppLoader';
+import PageHeader from '../../layout/components/PageHeader';
 import CycleService from '../../services/cycle.service';
 import ProjectService from '../../services/project.service';
 import UnitConverter from '../../utils/unit.converter';
@@ -356,7 +357,7 @@ export class ProjectEdit extends Component {
         
         return (
             <React.Fragment>
-                <div className="p-grid">
+                {/*} <div className="p-grid">
                     <Growl ref={(el) => this.growl = el} />
                 
                     <div className="p-col-10 p-lg-10 p-md-10">
@@ -367,7 +368,8 @@ export class ProjectEdit extends Component {
                             <i className="fa fa-window-close" style={{marginTop: "10px"}}></i>
                         </Link>
                     </div>
-                </div>
+                  </div> */}
+                 <PageHeader location={this.props.location} title={'Project - Edit'} actions={[{icon:'fa-window-close',title:'Click to Close Project Edit Page', props : { pathname: `/project/view/${this.state.project.name}`}}]}/>
 
                 { this.state.isLoading ? <AppLoader/> :
                 <>
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/edit.test.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/edit.test.js
index dd13177fac9e2e1321d5b873783a691d4b96e769..eae81b7db6746b68d5239aa7232026fed08aa4a5 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/edit.test.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/edit.test.js
@@ -112,10 +112,10 @@ it("renders input fields with Project details if found", async () => {
     expect(content.queryByTestId("name").value).toBe('OSR-11');
 
     const spinButtons = content.queryAllByRole("spinbutton");
-    const trigPrioInput = spinButtons.filter(function(element) { return element.id==="trig_prio"})[0];
+    const trigPrioInput = _.filter(spinButtons, {"id": "trig_prio"})[0];
     expect(trigPrioInput.value).toBe("990"); 
     
-    const rankInput = spinButtons.filter(function(element) { return element.id==="proj-rank"})[0];
+    const rankInput = _.filter(spinButtons, {"id": "proj-rank"})[0];
     expect(rankInput.value).toBe("5"); 
 
     const trigger = content.getAllByLabelText(/trigger/i).filter((element) => { return element.id==="trigger"})[0];
@@ -132,15 +132,15 @@ it("renders input fields with Project details if found", async () => {
     const cycleInput = content.getAllByRole("listbox")[2] ;
     expect(content.queryAllByText('Cycle 0').length).toBe(2);
 
-    expect(content.queryByPlaceholderText("CEP Processing Time").value).toBe("10 Hours");
-    expect(content.queryByPlaceholderText("LOFAR Observing Time").value).toBe("20 Hours");
-    expect(content.queryByPlaceholderText("LOFAR Observing Time prio A").value).toBe("30 Hours");
-    expect(content.queryByPlaceholderText("LOFAR Observing Time prio B").value).toBe("40 Hours");
-    expect(content.queryByPlaceholderText("LOFAR Support Time").value).toBe("50 Hours");
-    expect(content.queryByPlaceholderText("LTA Storage").value).toBe("6 TB");
-    expect(content.queryByPlaceholderText("Number of triggers").value).toBe("7 Numbers");
-    expect(content.queryByPlaceholderText("Support hours").value).toBe("8 ");
-
+    expect(_.filter(spinButtons, {"id": "CEP Processing Time"})[0].value).toBe("10 Hours");
+    expect(_.filter(spinButtons, {"id": "LOFAR Observing Time"})[0].value).toBe("20 Hours");
+    expect(_.filter(spinButtons, {"id": "LOFAR Observing Time prio A"})[0].value).toBe("30 Hours");
+    expect(_.filter(spinButtons, {"id": "LOFAR Observing Time prio B"})[0].value).toBe("40 Hours");
+    expect(_.filter(spinButtons, {"id": "LOFAR Support Time"})[0].value).toBe("50 Hours");
+    expect(_.filter(spinButtons, {"id": "LTA Storage"})[0].value).toBe("6 TB");
+    expect(_.filter(spinButtons, {"id": "Number of triggers"})[0].value).toBe("7 Numbers");
+    expect(_.filter(spinButtons, {"id": "Support hours"})[0].value).toBe("9 Hours");
+    
     expect(content.queryByTestId('save-btn').hasAttribute("disabled")).toBeFalsy();
 
 });
@@ -157,11 +157,11 @@ it("save Project after editing fields", async () => {
     expect(content.queryByTestId("name").value).toBe('OSR-11');
 
     const spinButtons = content.queryAllByRole("spinbutton");
-    const trigPrioInput = spinButtons.filter(function(element) { return element.id==="trig_prio"})[0];
+    const trigPrioInput = _.filter(spinButtons, {"id": "trig_prio"})[0];
     fireEvent.blur(trigPrioInput, { target: { value: 900 } });
     expect(trigPrioInput.value).toBe("900"); 
     
-    const rankInput = spinButtons.filter(function(element) { return element.id==="proj-rank"})[0];
+    const rankInput = _.filter(spinButtons, {"id": "proj-rank"})[0];
     fireEvent.blur(rankInput, { target: { value: 2 } });
     expect(rankInput.value).toBe("2");
 
@@ -190,19 +190,19 @@ it("save Project after editing fields", async () => {
     expect(content.queryAllByText('Cycle-0').length).toBe(2);
     expect(content.queryAllByText('Cycle 0').length).toBe(1);
 
-    const lofarObsTimeInput = content.queryByPlaceholderText('LOFAR Observing Time');
+    const lofarObsTimeInput = _.filter(spinButtons, {"id": "LOFAR Observing Time"})[0];
     fireEvent.blur(lofarObsTimeInput, { target: { value: 10 } });
     expect(lofarObsTimeInput.value).toBe('10 Hours');
     
-    const cepProcTimeInput = content.queryByPlaceholderText('CEP Processing Time');
+    const cepProcTimeInput = _.filter(spinButtons, {"id": "CEP Processing Time"})[0];
     fireEvent.blur(cepProcTimeInput, { target: { value: 5 } });
     expect(cepProcTimeInput.value).toBe('5 Hours');
     
-    const ltaStorageInput = content.queryByPlaceholderText('LTA Storage');
+    const ltaStorageInput = _.filter(spinButtons, {"id": "LTA Storage"})[0];
     fireEvent.blur(ltaStorageInput, { target: { value: 2 } });
     expect(ltaStorageInput.value).toBe('2 TB');
     
-    const noOfTriggerInput = content.queryByPlaceholderText('Number of triggers');
+    const noOfTriggerInput = _.filter(spinButtons, {"id": "Number of triggers"})[0];
     fireEvent.blur(noOfTriggerInput, { target: { value: 3 } });
     expect(noOfTriggerInput.value).toBe('3 Numbers');
     
@@ -238,13 +238,15 @@ it("save Project after adding, modifying and deleting resources", async () => {
     const addResourceBtn = content.queryByTestId('add_res_btn');
     fireEvent.click(addResourceBtn);
     expect(content.queryAllByText('Add Resources').length).toBe(2);
-    expect(content.queryByPlaceholderText('LOFAR Support hours')).not.toBe(null);
-    const lofarSupHrsInput = content.queryByPlaceholderText('LOFAR Support hours');
+    
+    const spinButtons = content.queryAllByRole("spinbutton");
+    const lofarSupHrsInput = _.filter(spinButtons, {"id": "LOFAR Support hours"})[0];
+    expect(lofarSupHrsInput).not.toBe(null);
     fireEvent.blur(lofarSupHrsInput, { target: { value: 100 } });
-    expect(lofarSupHrsInput.value).toBe('100 ');
+    expect(lofarSupHrsInput.value).toBe('100 Hours');
 
     // Editing existing resource
-    const lofarObsTimeInput = content.queryByPlaceholderText('LOFAR Observing Time');
+    const lofarObsTimeInput = _.filter(spinButtons, {"id": "LOFAR Observing Time"})[0];
     fireEvent.blur(lofarObsTimeInput, { target: { value: 10 } });
     expect(lofarObsTimeInput.value).toBe('10 Hours');
     
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/list.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/list.js
index c26a43fa9bfbf24144be35f8b1208c154b3391df..4aa4e98a8cd8485d58fb75da63c8f29f8a8eea44 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/list.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/list.js
@@ -1,8 +1,9 @@
 import React, {Component} from 'react';
 import ProjectService from '../../services/project.service';
 import ViewTable from '../../components/ViewTable';
-import { Link } from 'react-router-dom/cjs/react-router-dom.min';
+// import { Link } from 'react-router-dom/cjs/react-router-dom.min';
 import AppLoader from '../../layout/components/AppLoader';
+import PageHeader from '../../layout/components/PageHeader';
 
 export class ProjectList extends Component{
     constructor(props){
@@ -71,7 +72,7 @@ export class ProjectList extends Component{
     render(){
         return(
             <>
-                <div className="p-grid">
+               {/*<div className="p-grid">
                     <div className="p-col-10 p-lg-10 p-md-10">
                         <h2>Project - List </h2>
                     </div>
@@ -80,7 +81,8 @@ export class ProjectList extends Component{
                             <i className="fa fa-plus-square" style={{marginTop: "10px"}}></i>
                         </Link>
                     </div>
-                </div>
+                </div> */}
+                <PageHeader location={this.props.location} title={'Project - List'} actions={[{icon: 'fa-plus-square',title:'Click to Add Project', props:{pathname: '/project/create' }}]}/>
                 {this.state.isLoading? <AppLoader /> : this.state.isprocessed &&
                     <ViewTable 
                         data={this.state.projectlist} 
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/view.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/view.js
index 2ede26034deb218bf3ba36f0049ada765236d2a9..799d8cef35b4b39270d1d6cce36c79fe0f50606a 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/view.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/view.js
@@ -4,10 +4,12 @@ import moment from 'moment';
 import _ from 'lodash';
 
 import { Chips } from 'primereact/chips';
+import { TieredMenu } from 'primereact/tieredmenu';
 
 import ResourceDisplayList from './ResourceDisplayList';
 
 import AppLoader from '../../layout/components/AppLoader';
+import PageHeader from '../../layout/components/PageHeader';
 import ProjectService from '../../services/project.service';
 import UnitConverter from '../../utils/unit.converter';
 
@@ -20,6 +22,7 @@ export class ProjectView extends Component {
         super(props);
         this.state = {
             isLoading: true,
+            project:'',
         };
         if (this.props.match.params.id) {
             this.state.projectId  = this.props.match.params.id;
@@ -28,6 +31,11 @@ export class ProjectView extends Component {
         }
         this.state.redirect = this.state.projectId?"":'/project'         // If no project id is passed, redirect to Project list page
         this.resourceUnitMap = UnitConverter.resourceUnitMap;       // Resource unit conversion factor and constraints
+        this.optionsMenu = React.createRef();
+        this.menuOptions = [ {label:'Add Scheduling Unit', icon: "fa fa-", command: () => {this.selectOptionMenu('Add SU')}} ];
+        
+        this.showOptionMenu = this.showOptionMenu.bind(this);
+        this.selectOptionMenu = this.selectOptionMenu.bind(this);
     }
 
     componentDidMount() {
@@ -68,6 +76,22 @@ export class ProjectView extends Component {
         
     }
 
+    showOptionMenu(event) {
+        this.optionsMenu.toggle(event);
+    }
+    
+    selectOptionMenu(menuName) {
+        switch(menuName) {
+            case 'Add SU': {
+                this.setState({redirect: `/project/${this.state.project.name}/schedulingunit/create`});
+                break;
+            }
+            default: {
+                break;
+            }
+        }
+    }
+
     render() {
         if (this.state.redirect) {
             return <Redirect to={ {pathname: this.state.redirect} }></Redirect>
@@ -75,7 +99,7 @@ export class ProjectView extends Component {
         
         return (
             <React.Fragment>
-                <div className="p-grid">
+                { /*}  <div className="p-grid">
                     <div className="p-col-10 p-lg-10 p-md-10">
                         <h2>Project - Details </h2>
                     </div>
@@ -86,11 +110,27 @@ export class ProjectView extends Component {
                         </Link>
                         <Link to={{ pathname: `/project/edit/${this.state.project.name}`, state: {id: this.state.project?this.state.project.name:''}}} title="Edit Project" 
                                  style={{float: "right"}}>
-                            <i className="fa fa-edit" style={{marginTop: "10px"}}></i>
+                            <i className="fa fa-edit" style={{marginTop: "10px", marginLeft: "5px"}}></i>
                         </Link>
+                        <TieredMenu model={this.menuOptions} popup ref={el => this.optionsMenu = el} />
+                        <button className="p-link" style={{float: "right"}}>
+                            <i className="fa fa-bars" label="Toggle Columns" style={{marginTop: "10px", marginLeft: "5px"}} 
+                                onMouseOver={(e) => this.optionsMenu.toggle(e)} />
+                        </button>
+                        
                     </div>
                     }
-                </div>
+                </div> */}
+                <TieredMenu model={this.menuOptions} popup ref={el => this.optionsMenu = el} />
+                <PageHeader location={this.props.location} title={'Project - View'} 
+                            actions={[  {icon:'fa-bars',title: '', type:'button',
+                                         actOn:'mouseOver', props : { callback: this.showOptionMenu}},
+                                        {icon: 'fa-edit',title:'Click to Edit Project', type:'link',
+                                         props : { pathname: `/project/edit/${this.state.project.name}`, 
+                                                   state: {id: this.state.project?this.state.project.name:''&& this.state.project}}},
+                                        {icon:'fa-window-close',title: 'Click to Close Project View', type:'link',
+                                         props : { pathname: `/project`}},
+                                        ]}/>
                 { this.state.isLoading && <AppLoader /> }
                 { this.state.project &&
                     <React.Fragment>
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/view.test.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/view.test.js
index aaf9327d0308d4076806ba99897dc7a345df0e23..3847248a84ccbf4d50b6d39a0498b19a7d267d84 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/view.test.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/view.test.js
@@ -66,7 +66,7 @@ it("renders Project details if found", async () => {
     expect(content.queryByText("50 Hours")).not.toBe(null);
     expect(content.queryByText("6 TB")).not.toBe(null);
     expect(content.queryByText("7 Numbers")).not.toBe(null);
-    expect(content.queryByText("8")).not.toBe(null);
+    expect(content.queryByText("9 Hours")).not.toBe(null);
 
 });
 
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 14923ef9cd77a73146c6c7375316805821f81249..0a6258a315d9c1b44aeed07cf9dbefdcd497b5fc 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js
@@ -36,7 +36,7 @@ class SchedulingUnitList extends Component{
                 "Duration":"filter-input-50",
                 "Type": "filter-input-75"
             }],
-            defaultSortColumn: [{id: "Name", desc: false},{id: "Created Date", desc: false}],
+            defaultSortColumn: [{id: "Name", desc: false}],
         }
     }
     
@@ -52,17 +52,17 @@ class SchedulingUnitList extends Component{
                 blueprintdata.map(blueP => { 
                     blueP.duration = moment.utc(blueP.duration*1000).format('HH:mm:ss'); 
                     blueP.type="Blueprint"; 
-                    blueP['actionpath'] = '/task/view/type/id';
+                    blueP['actionpath'] = '/schedulingunit/view/blueprint/'+blueP.id;
                     return blueP; 
                 });
                 output.push(...blueprintdata);
-                scheduleunit['actionpath']='/schedulingunit/view';
+                scheduleunit['actionpath']='/schedulingunit/view/draft/'+scheduleunit.id;
                 scheduleunit['type'] = 'Draft';
                 scheduleunit['duration'] = moment.utc(scheduleunit.duration*1000).format('HH:mm:ss');
                 output.push(scheduleunit);
             }
             this.setState({
-                scheduleunit: output, isLoading:false
+                scheduleunit: output, isLoading: false
             });
         })
     }
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 46dd2fa42de19b50cacf93cbe8ae46bef4265be1..096a7c62e9530967a72d32fd558a38d549c9af75 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js
@@ -1,9 +1,10 @@
 import React, { Component } from 'react'
-import {Link} from 'react-router-dom'
+// import {Link} from 'react-router-dom'
 import 'primeflex/primeflex.css';
 import { Chips } from 'primereact/chips';
 
 import AppLoader from "./../../layout/components/AppLoader";
+import PageHeader from '../../layout/components/PageHeader';
 
 import ViewTable from './../../components/ViewTable';
 import ScheduleService from '../../services/schedule.service';
@@ -49,38 +50,63 @@ class ViewSchedulingUnit extends Component{
                 "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",
-            }],
-            defaultSortColumn: [{id: "Name", desc: false}],
+            }]
+        }
+        if (this.props.match.params.id) {
+            this.state.scheduleunitId  = this.props.match.params.id;
+        }
+        if (this.props.match.params.type) {
+            this.state.scheduleunitType = this.props.match.params.type;
         }
     }
 
     componentDidMount(){ 
-        let schedule_id = this.props.location.state.id
-        if (schedule_id) {
-            ScheduleService.getSchedulingUnitDraftById(schedule_id)
-            .then(scheduleunit =>{
-                ScheduleService.getScheduleTasksBySchedulingUnitId(scheduleunit.data.id)
-                .then(tasks =>{
-                    tasks.map(task => {
-                        task.duration = moment.utc(task.duration*1000).format('HH:mm:ss'); 
-                        task.relative_start_time = moment.utc(task.relative_start_time*1000).format('HH:mm:ss'); 
-                        task.relative_stop_time = moment.utc(task.relative_stop_time*1000).format('HH:mm:ss'); 
-                        return task;
+        let schedule_id = this.state.scheduleunitId;
+        let schedule_type = this.state.scheduleunitType;
+        if (schedule_type && schedule_id) {
+            this.getScheduleUnit(schedule_type, schedule_id)
+            .then(schedulingUnit =>{
+                if (schedulingUnit) {
+                    this.getScheduleUnitTasks(schedule_type, schedulingUnit)
+                        .then(tasks =>{
+                    /* tasks.map(task => {
+                            task.duration = moment.utc(task.duration*1000).format('HH:mm:ss'); 
+                            task.relative_start_time = moment.utc(task.relative_start_time*1000).format('HH:mm:ss'); 
+                            task.relative_stop_time = moment.utc(task.relative_stop_time*1000).format('HH:mm:ss'); 
+                            return task;
+                        });*/
+                        this.setState({
+                            scheduleunit : schedulingUnit,
+                            schedule_unit_task : tasks,
+                            isLoading: false,
+                        });
                     });
+                }   else {
                     this.setState({
-                        scheduleunit : scheduleunit.data,
-                        schedule_unit_task : tasks,
-                        isLoading: false
+                        isLoading: false,
                     });
-				});
-			})
+                }
+            });
 		}
     }
-	
+    
+    getScheduleUnitTasks(type, scheduleunit){
+        if(type === 'draft')
+            return ScheduleService.getTasksBySchedulingUnit(scheduleunit.id);
+        else
+            return ScheduleService.getTaskBlueprintsBySchedulingUnit(scheduleunit);
+    }
+    getScheduleUnit(type, id){
+        if(type === 'draft')
+            return ScheduleService.getSchedulingUnitDraftById(id)
+        else
+            return ScheduleService.getSchedulingUnitBlueprintById(id)
+    }
+
     render(){
         return(
 		   <>   
-                <div className="p-grid">
+                {/*}  <div className="p-grid">
                 <div className="p-col-10">
                   <h2>Scheduling Unit - Details </h2>
 			    </div>
@@ -89,15 +115,18 @@ class ViewSchedulingUnit extends Component{
                                 style={{float:'right'}}>
                         <i className="fa fa-times" style={{marginTop: "10px", marginLeft: '5px'}}></i>
                     </Link>
-                    {/* <Link to={{ pathname: '/schedulingunit/edit', state: {id: this.state.scheduleunit?this.state.scheduleunit.id:''}}} title="Edit" 
+                     <Link to={{ pathname: '/schedulingunit/edit', state: {id: this.state.scheduleunit?this.state.scheduleunit.id:''}}} title="Edit" 
                             style={{float:'right'}}>
                     <i className="fa fa-edit" style={{marginTop: "10px"}}></i>
-                    </Link> */}
-                </div>
+                    </Link> 
                 </div>
+                </div> */}
+                <PageHeader location={this.props.location} title={'Scheduling Unit - Details'} 
+                            actions={[{icon: 'fa-window-close',title:'Click to Close Scheduling Unit View', props : { pathname: '/schedulingunit'}}]}/>
 				{ this.state.isLoading ? <AppLoader/> :this.state.scheduleunit &&
 			    <>
-		            <div className="p-grid">
+		            <div className="main-content">
+                    <div className="p-grid">
                         <label  className="col-lg-2 col-md-2 col-sm-12">Name</label>
                         <span className="p-col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.name}</span>
                         <label  className="col-lg-2 col-md-2 col-sm-12">Description</label>
@@ -119,7 +148,7 @@ class ViewSchedulingUnit extends Component{
                         <label className="col-lg-2 col-md-2 col-sm-12">Template ID</label>
                         <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.requirements_template_id}</span>
                         <label  className="col-lg-2 col-md-2 col-sm-12">Scheduling set</label>
-                        <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.scheduling_set_id}</span>
+                        <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.scheduling_set_object.name}</span>
                     </div>
                     <div className="p-grid">
                         <label className="col-lg-2 col-md-2 col-sm-12">Duration (HH:mm:ss)</label>
@@ -127,6 +156,7 @@ class ViewSchedulingUnit extends Component{
                         <label  className="col-lg-2 col-md-2 col-sm-12">Tags</label>
                         <Chips className="p-col-4 chips-readonly" disabled value={this.state.scheduleunit.tags}></Chips>
                     </div>
+                    </div>
                 </>
 			 
                 }
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/create.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/create.js
new file mode 100644
index 0000000000000000000000000000000000000000..5aafacbe4360cb71c87c3741b62f5d6034aee552
--- /dev/null
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/create.js
@@ -0,0 +1,440 @@
+import React, {Component} from 'react';
+import { Link, Redirect } from 'react-router-dom';
+import _ from 'lodash';
+import $RefParser from "@apidevtools/json-schema-ref-parser";
+
+import {InputText} from 'primereact/inputtext';
+import {InputTextarea} from 'primereact/inputtextarea';
+import {Dropdown} from 'primereact/dropdown';
+import { Button } from 'primereact/button';
+import {Dialog} from 'primereact/components/dialog/Dialog';
+import {Growl} from 'primereact/components/growl/Growl';
+
+import AppLoader from '../../layout/components/AppLoader';
+import Jeditor from '../../components/JSONEditor/JEditor';
+
+import ProjectService from '../../services/project.service';
+import ScheduleService from '../../services/schedule.service';
+import TaskService from '../../services/task.service';
+import UIConstants from '../../utils/ui.constants';
+
+/**
+ * Component to create a new SchedulingUnit from Observation strategy template
+ */
+export class SchedulingUnitCreate extends Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            isLoading: true,                        // Flag for loading spinner
+            dialog: { header: '', detail: ''},      // Dialog properties
+            redirect: null,                         // URL to redirect
+            errors: [],                             // Form Validation errors
+            schedulingSets: [],                     // Scheduling set of the selected project
+            schedulingUnit: {
+                project: (props.match?props.match.params.project:null) || null,
+            },
+            projectDisabled: (props.match?(props.match.params.project? true:false):false),      // Disable project selection if 
+            observStrategy: {},                     // Selected strategy to create SU
+            paramsSchema: null,                     // JSON Schema to be generated from strategy template to pass to JSOn editor
+            validEditor: false,                     // For JSON editor validation
+            validFields: {},                        // For Form Validation
+        }
+        this.projects = [];                         // All projects to load project dropdown
+        this.schedulingSets = [];                   // All scheduling sets to be filtered for project
+        this.observStrategies = [];                 // All Observing strategy templates
+        this.taskTemplates = [];                    // All task templates to be filtered based on tasks in selected strategy template
+        this.tooltipOptions = UIConstants.tooltipOptions;
+        this.nameInput = React.createRef();         // Ref to Name field for auto focus
+        this.formRules = {                          // Form validation rules
+            name: {required: true, message: "Name can not be empty"},
+            description: {required: true, message: "Description can not be empty"},
+            project: {required: true, message: "Select project to get Scheduling Sets"},
+            scheduling_set_id: {required: true, message: "Select the Scheduling Set"},
+        };
+ 
+        this.setEditorOutput = this.setEditorOutput.bind(this);
+        this.changeProject = this.changeProject.bind(this);
+        this.changeStrategy = this.changeStrategy.bind(this);
+        this.setSchedUnitParams = this.setSchedUnitParams.bind(this);
+        this.validateForm = this.validateForm.bind(this);
+        this.validateEditor = this.validateEditor.bind(this);
+        this.setEditorFunction = this.setEditorFunction.bind(this);
+        this.saveSchedulingUnit = this.saveSchedulingUnit.bind(this);
+        this.cancelCreate = this.cancelCreate.bind(this);
+        this.reset = this.reset.bind(this);
+    }
+
+    componentDidMount() {
+        const promises = [  ProjectService.getProjectList(), 
+                            ScheduleService.getSchedulingSets(),
+                            ScheduleService.getObservationStrategies(),
+                            TaskService.getTaskTemplates()]
+        Promise.all(promises).then(responses => {
+            this.projects = responses[0];
+            this.schedulingSets = responses[1];
+            this.observStrategies = responses[2];
+            this.taskTemplates = responses[3];
+            if (this.state.schedulingUnit.project) {
+                const projectSchedSets = _.filter(this.schedulingSets, {'project_id': this.state.schedulingUnit.project});
+                this.setState({isLoading: false, schedulingSets: projectSchedSets});
+            }   else {
+                this.setState({isLoading: false});
+            }
+        }); 
+    }
+
+    /**
+     * Function to call on change of project and reload scheduling set dropdown
+     * @param {string} projectName 
+     */
+    changeProject(projectName) {
+        const projectSchedSets = _.filter(this.schedulingSets, {'project_id': projectName});
+        let schedulingUnit = this.state.schedulingUnit;
+        schedulingUnit.project = projectName;
+        this.setState({schedulingUnit: schedulingUnit, schedulingSets: projectSchedSets, validForm: this.validateForm('project')});
+    }
+
+    /**
+     * Function called when observation strategy template is changed. 
+     * It generates the JSON schema for JSON editor and defult vales for the parameters to be captured
+     * @param {number} strategyId 
+     */
+    async changeStrategy (strategyId) {
+        const observStrategy = _.find(this.observStrategies, {'id': strategyId});
+        const tasks = observStrategy.template.tasks;    
+        let paramsOutput = {};
+        let schema = { type: 'object', additionalProperties: false, 
+                        properties: {}, definitions:{}
+                     };
+
+        for (const taskName in tasks)  {
+            const task = tasks[taskName];
+            //Resolve task from the strategy template
+            const $taskRefs = await $RefParser.resolve(task);
+
+            // Identify the task specification template of every task in the strategy template
+            const taskTemplate = _.find(this.taskTemplates, {'name': task['specifications_template']});
+            schema['$id'] = taskTemplate.schema['$id'];
+            schema['$schema'] = taskTemplate.schema['$schema'];
+            observStrategy.template.parameters.forEach(async(param, index) => {
+                if (param.refs[0].indexOf(`/tasks/${taskName}`) > 0) {
+                    // Resolve the identified template
+                    const $templateRefs = await $RefParser.resolve(taskTemplate);
+                    let property = { };
+                    let tempProperty = null;
+                    // Get the property type from the template and create new property in the schema for the parameters
+                    try {
+                        tempProperty = $templateRefs.get(param.refs[0].replace(`#/tasks/${taskName}/specifications_doc`, '#/schema/properties'))
+                    }   catch(error) {
+                        const taskPaths = param.refs[0].split("/");
+                        tempProperty = _.cloneDeep(taskTemplate.schema.properties[taskPaths[4]]);
+                        if (tempProperty.type === 'array') {
+                            tempProperty = tempProperty.items.properties[taskPaths[6]];
+                        }
+                        property = tempProperty;
+                    }
+                    property.title = param.name;
+                    property.default = $taskRefs.get(param.refs[0].replace(`#/tasks/${taskName}`, '#'));
+                    paramsOutput[`param_${index}`] = property.default;
+                    schema.properties[`param_${index}`] = property;
+                    // Set property defintions taken from the task template in new schema
+                    for (const definitionName in taskTemplate.schema.definitions) {
+                        schema.definitions[definitionName] = taskTemplate.schema.definitions[definitionName];
+                    }
+                }
+            });
+        }
+        this.setState({observStrategy: observStrategy, paramsSchema: schema, paramsOutput: paramsOutput});
+
+        // Function called to clear the JSON Editor fields and reload with new schema
+        if (this.state.editorFunction) {
+            this.state.editorFunction();
+        }
+    }
+
+    /**
+     * This is the callback method to be passed to the JSON editor. 
+     * JEditor will call this function when there is change in the editor.
+     * @param {Object} jsonOutput 
+     * @param {Array} errors 
+     */
+    setEditorOutput(jsonOutput, errors) {
+        this.paramsOutput = jsonOutput;
+        this.validEditor = errors.length === 0;
+        this.setState({ paramsOutput: jsonOutput, 
+                        validEditor: errors.length === 0,
+                        validForm: this.validateForm()});
+    }
+
+    /**
+     * This function is mainly added for Unit Tests. If this function is removed Unit Tests will fail.
+     */
+    validateEditor() {
+        return this.validEditor?true:false;
+    }
+    
+    /**
+     * Function to set form values to the SU object
+     * @param {string} key 
+     * @param {object} value 
+     */
+    setSchedUnitParams(key, value) {
+        let schedulingUnit = this.state.schedulingUnit;
+        schedulingUnit[key] = value;
+        this.setState({schedulingUnit: schedulingUnit, validForm: this.validateForm(key), validEditor: this.validateEditor()});
+        this.validateEditor();
+    }
+
+    /**
+     * 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});
+    }
+
+    /**
+     * Validation function to validate the form or field based on the form rules.
+     * If no argument passed for fieldName, validates all fields in the form.
+     * @param {string} fieldName 
+     */
+    validateForm(fieldName) {
+        let validForm = false;
+        let errors = this.state.errors;
+        let validFields = this.state.validFields;
+        if (fieldName) {
+            delete errors[fieldName];
+            delete validFields[fieldName];
+            if (this.formRules[fieldName]) {
+                const rule = this.formRules[fieldName];
+                const fieldValue = this.state.schedulingUnit[fieldName];
+                if (rule.required) {
+                    if (!fieldValue) {
+                        errors[fieldName] = rule.message?rule.message:`${fieldName} is required`;
+                    }   else {
+                        validFields[fieldName] = true;
+                    }
+                }
+            }
+        }   else {
+            errors = {};
+            validFields = {};
+            for (const fieldName in this.formRules) {
+                const rule = this.formRules[fieldName];
+                const fieldValue = this.state.schedulingUnit[fieldName];
+                if (rule.required) {
+                    if (!fieldValue) {
+                        errors[fieldName] = rule.message?rule.message:`${fieldName} is required`;
+                    }   else {
+                        validFields[fieldName] = true;
+                    }
+                }
+            }
+        }
+        this.setState({errors: errors, validFields: validFields});
+        if (Object.keys(validFields).length === Object.keys(this.formRules).length) {
+            validForm = true;
+        }
+        return validForm;
+    }
+
+    /**
+     * Function to create Scheduling unit
+     */
+    async saveSchedulingUnit() {
+        let observStrategy = _.cloneDeep(this.state.observStrategy);
+        const $refs = await $RefParser.resolve(observStrategy.template);
+        observStrategy.template.parameters.forEach(async(param, index) => {
+            $refs.set(observStrategy.template.parameters[index]['refs'][0], this.state.paramsOutput['param_' + index]);
+        });
+        
+        const schedulingUnit = await ScheduleService.saveSUDraftFromObservStrategy(observStrategy, this.state.schedulingUnit);
+        if (schedulingUnit) {
+            // this.growl.show({severity: 'success', summary: 'Success', detail: 'Scheduling Unit and tasks created successfully!'});
+            const dialog = {header: 'Success', detail: 'Scheduling Unit and Tasks are created successfully. Do you want to create another Scheduling Unit?'};
+            this.setState({schedulingUnit: schedulingUnit, dialogVisible: true, dialog: dialog})
+        }   else {
+            this.growl.show({severity: 'error', summary: 'Error Occured', detail: 'Unable to save Scheduling Unit/Tasks'});
+        }
+    }
+
+    /**
+     * Cancel SU creation and redirect
+     */
+    cancelCreate() {
+        this.setState({redirect: '/schedulingunit'})
+    }
+
+    /**
+     * Reset function to be called when user wants to create new SU
+     */
+    reset() {
+        const schedulingSets = this.state.schedulingSets;
+        this.nameInput.element.focus();
+        this.setState({
+            dialogVisible: false,
+            dialog: { header: '', detail: ''},      
+            errors: [],
+            schedulingSets: this.props.match.params.project?schedulingSets:[],
+            schedulingUnit: {
+                name: '',
+                description: '',
+                project: this.props.match.params.project || null,
+            },
+            projectDisabled: (this.props.match.params.project? true:false),
+            observStrategy: {},
+            paramsOutput: null,
+            validEditor: false,
+            validFields: {}
+        });
+        this.state.editorFunction();
+    }
+
+    render() {
+        if (this.state.redirect) {
+            return <Redirect to={ {pathname: this.state.redirect} }></Redirect>
+        }
+        
+        const schema = this.state.paramsSchema;
+        
+        let jeditor = null;
+        if (schema) {
+		    jeditor = React.createElement(Jeditor, {title: "Task Parameters", 
+                                                        schema: schema,
+                                                        initValue: this.state.paramsOutput, 
+                                                        callback: this.setEditorOutput,
+                                                        parentFunction: this.setEditorFunction
+                                                    });
+        }
+        return (
+            <React.Fragment>
+                <div className="p-grid">
+                    <Growl ref={(el) => this.growl = el} />
+                
+                    <div className="p-col-10 p-lg-10 p-md-10">
+                        <h2>Scheduling Unit - Add</h2>
+                    </div>
+                    <div className="p-col-2 p-lg-2 p-md-2">
+                        <Link to={{ pathname: '/schedulingunit'}} tite="Close" style={{float: "right"}}>
+                            <i className="fa fa-window-close" style={{marginTop: "10px"}}></i>
+                        </Link>
+                    </div>
+                </div>
+                { this.state.isLoading ? <AppLoader /> :
+                <>
+                <div>
+                    <div className="p-fluid">
+                        <div className="p-field p-grid">
+                            <label htmlFor="schedUnitName" className="col-lg-2 col-md-2 col-sm-12">Name <span style={{color:'red'}}>*</span></label>
+                            <div className="col-lg-3 col-md-3 col-sm-12">
+                                <InputText className={this.state.errors.name ?'input-error':''} id="schedUnitName" data-testid="name" 
+                                            tooltip="Enter name of the Scheduling Unit" tooltipOptions={this.tooltipOptions} maxLength="128"
+                                            ref={input => {this.nameInput = input;}}
+                                            value={this.state.schedulingUnit.name} autoFocus
+                                            onChange={(e) => this.setSchedUnitParams('name', e.target.value)}
+                                            onBlur={(e) => this.setSchedUnitParams('name', e.target.value)}/>
+                                <label className={this.state.errors.name?"error":"info"}>
+                                    {this.state.errors.name ? this.state.errors.name : "Max 128 characters"}
+                                </label>
+                            </div>
+                            <div className="col-lg-1 col-md-1 col-sm-12"></div>
+                            <label htmlFor="description" className="col-lg-2 col-md-2 col-sm-12">Description <span style={{color:'red'}}>*</span></label>
+                            <div className="col-lg-3 col-md-3 col-sm-12">
+                                <InputTextarea className={this.state.errors.description ?'input-error':''} rows={3} cols={30} 
+                                            tooltip="Longer description of the scheduling unit" tooltipOptions={this.tooltipOptions} maxLength="128"
+                                            data-testid="description" value={this.state.schedulingUnit.description} 
+                                            onChange={(e) => this.setSchedUnitParams('description', e.target.value)}
+                                            onBlur={(e) => this.setSchedUnitParams('description', e.target.value)}/>
+                                <label className={this.state.errors.description ?"error":"info"}>
+                                    {this.state.errors.description ? this.state.errors.description : "Max 255 characters"}
+                                </label>
+                            </div>
+                        </div>
+                        <div className="p-field p-grid">
+                            <label htmlFor="project" className="col-lg-2 col-md-2 col-sm-12">Project <span style={{color:'red'}}>*</span></label>
+                            <div className="col-lg-3 col-md-3 col-sm-12" data-testid="project" >
+                                <Dropdown inputId="project" optionLabel="name" optionValue="name" 
+                                        tooltip="Project" tooltipOptions={this.tooltipOptions}
+                                        value={this.state.schedulingUnit.project} disabled={this.state.projectDisabled}
+                                        options={this.projects} 
+                                        onChange={(e) => {this.changeProject(e.value)}} 
+                                        placeholder="Select Project" />
+                                <label className={this.state.errors.project ?"error":"info"}>
+                                    {this.state.errors.project ? this.state.errors.project : "Select Project to get Scheduling Sets"}
+                                </label>
+                            </div>
+                            <div className="col-lg-1 col-md-1 col-sm-12"></div>
+                            <label htmlFor="schedSet" className="col-lg-2 col-md-2 col-sm-12">Scheduling Set <span style={{color:'red'}}>*</span></label>
+                            <div className="col-lg-3 col-md-3 col-sm-12">
+                                <Dropdown data-testid="schedSet" id="schedSet" optionLabel="name" optionValue="id" 
+                                        tooltip="Scheduling set of the project" tooltipOptions={this.tooltipOptions}
+                                        value={this.state.schedulingUnit.scheduling_set_id} 
+                                        options={this.state.schedulingSets} 
+                                        onChange={(e) => {this.setSchedUnitParams('scheduling_set_id',e.value)}} 
+                                        placeholder="Select Scheduling Set" />
+                                <label className={this.state.errors.scheduling_set_id ?"error":"info"}>
+                                    {this.state.errors.scheduling_set_id ? this.state.errors.scheduling_set_id : "Scheduling Set of the Project"}
+                                </label>
+                            </div>
+                        </div>
+                        <div className="p-field p-grid">
+                            <label htmlFor="observStrategy" className="col-lg-2 col-md-2 col-sm-12">Observation Strategy <span style={{color:'red'}}>*</span></label>
+                            <div className="col-lg-3 col-md-3 col-sm-12" data-testid="observStrategy" >
+                                <Dropdown inputId="observStrategy" optionLabel="name" optionValue="id" 
+                                        tooltip="Observation Strategy Template to be used to create the Scheduling Unit and Tasks" tooltipOptions={this.tooltipOptions}
+                                        value={this.state.observStrategy.id} 
+                                        options={this.observStrategies} 
+                                        onChange={(e) => {this.changeStrategy(e.value)}} 
+                                        placeholder="Select Strategy" />
+                            </div>
+                            <div className="col-lg-1 col-md-1 col-sm-12"></div>
+                        </div>
+                        
+                    </div>
+                    <div className="p-fluid">
+                        <div className="p-grid">
+                            <div className="p-col-12">
+                                {this.state.paramsSchema?jeditor:""}
+                            </div>
+                        </div>
+                    </div>
+                    
+                    <div className="p-grid p-justify-start">
+                        <div className="p-col-1">
+                            <Button label="Save" className="p-button-primary" icon="pi pi-check" onClick={this.saveSchedulingUnit} 
+                                    disabled={!this.state.validEditor || !this.state.validForm} data-testid="save-btn" />
+                        </div>
+                        <div className="p-col-1">
+                            <Button label="Cancel" className="p-button-danger" icon="pi pi-times" onClick={this.cancelCreate}  />
+                        </div>
+                    </div>
+                </div>
+                    
+                </>
+                }
+
+                {/* Dialog component to show messages and get input */}
+                <div className="p-grid" data-testid="confirm_dialog">
+                    <Dialog header={this.state.dialog.header} visible={this.state.dialogVisible} style={{width: '25vw'}} inputId="confirm_dialog"
+                            modal={true}  onHide={() => {this.setState({dialogVisible: false})}} 
+                            footer={<div>
+                                <Button key="back" onClick={() => {this.setState({dialogVisible: false, redirect: `/schedulingunit/view/draft/${this.state.schedulingUnit.id}`});}} label="No" />
+                                <Button key="submit" type="primary" onClick={this.reset} label="Yes" />
+                                </div>
+                            } >
+                            <div className="p-grid">
+                                <div className="col-lg-2 col-md-2 col-sm-2" style={{margin: 'auto'}}>
+                                    <i className="pi pi-check-circle pi-large pi-success"></i>
+                                </div>
+                                <div className="col-lg-10 col-md-10 col-sm-10">
+                                    {this.state.dialog.detail}
+                                </div>
+                            </div>
+                    </Dialog>
+                </div>
+            </React.Fragment>
+        );
+    }
+}
+
+export default SchedulingUnitCreate;
\ No newline at end of file
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/create.test.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/create.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..ccdaf6f98f69ceb13f23508624b911590cd9f148
--- /dev/null
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/create.test.js
@@ -0,0 +1,140 @@
+import React from 'react';
+import { BrowserRouter as Router } from 'react-router-dom';
+import { act } from "react-dom/test-utils";
+import { render, cleanup, fireEvent } from '@testing-library/react';
+import '@testing-library/jest-dom/extend-expect';
+
+import {SchedulingUnitCreate} from './create';
+
+import ScheduleService from '../../services/schedule.service';
+import ProjectService from '../../services/project.service';
+import TaskService from '../../services/task.service';
+
+import SUServiceMock from '../../__mocks__/scheduleunit.service.data';
+import ProjectServiceMock from '../../__mocks__/project.service.data';
+import TaskServiceMock from '../../__mocks__/task.service.data';
+
+
+
+let projectListSpy, scheduleSetListSpy, observStrategiesSpy, taskTemplatesSpy, saveSUFromStrategySpy, updateSUSpy, createSUTasksSpy;
+
+beforeEach(() => {
+    setMockSpy();
+});
+
+afterEach(() => {
+    // cleanup on exiting
+    clearMockSpy();
+    cleanup();
+});
+
+const setMockSpy = () => {
+    projectListSpy = jest.spyOn(ProjectService, 'getProjectList');
+    projectListSpy.mockImplementation(() => { return Promise.resolve(ProjectServiceMock.projectList)});
+    scheduleSetListSpy = jest.spyOn(ScheduleService, 'getSchedulingSets');
+    scheduleSetListSpy.mockImplementation(() => { return Promise.resolve(SUServiceMock.scheduleSetList)});
+    observStrategiesSpy = jest.spyOn(ScheduleService, 'getObservationStrategies');
+    observStrategiesSpy.mockImplementation(() => { return Promise.resolve(SUServiceMock.observStrategies)});
+    taskTemplatesSpy = jest.spyOn(TaskService, 'getTaskTemplates');
+    taskTemplatesSpy.mockImplementation(() => { return Promise.resolve(TaskServiceMock.taskTemplates)});
+    saveSUFromStrategySpy = jest.spyOn(ScheduleService, 'saveSUDraftFromObservStrategy');
+    saveSUFromStrategySpy.mockImplementation((observStrategy, schedulingUnit) => { 
+        return Promise.resolve(SUServiceMock.schedulingUnitFromObservStrategy);
+    });
+    updateSUSpy = jest.spyOn(ScheduleService, 'updateSchedulingUnitDraft');
+    updateSUSpy.mockImplementation((schedulingUnit) => { 
+        return Promise.resolve(SUServiceMock.schedulingUnitFromObservStrategy);
+    });
+    createSUTasksSpy = jest.spyOn(ScheduleService, 'createSUTaskDrafts');
+    createSUTasksSpy.mockImplementation((schedulingUnit) => { 
+        return Promise.resolve(SUServiceMock.schedulingUnitFromObservStrategy);
+    });
+    
+}
+
+const clearMockSpy = () => {
+    projectListSpy.mockRestore();
+    scheduleSetListSpy.mockRestore();
+    observStrategiesSpy.mockRestore();
+    taskTemplatesSpy.mockRestore();
+    saveSUFromStrategySpy.mockRestore();
+    updateSUSpy.mockRestore();
+    createSUTasksSpy.mockRestore();
+}
+
+it("renders create page with all fields and default values", async() => {
+    console.log("renders create page with all fields and default values ------------------------");
+    
+    let content;
+    await act(async () => {
+        content = render(<Router><SchedulingUnitCreate /></Router>);
+    });
+
+    expect(content.queryByText('Scheduling Unit - Add')).not.toBe(null);        // Page loaded successfully
+    expect(projectListSpy).toHaveBeenCalled();                                  // Mock Spy called successfully
+    expect(observStrategiesSpy).toHaveBeenCalled();                             // Mock Spy called successfully
+    expect(scheduleSetListSpy).toHaveBeenCalled();                              // Mock Spy called successfully
+    expect(taskTemplatesSpy).toHaveBeenCalled();                                // Mock Spy called successfully
+    expect(content.queryByText('TMSS-Commissioning')).toBeInTheDocument();      // Project Dropdown  loaded successfully
+    expect(content.queryByText('UC1 observation strategy template')).toBeInTheDocument();      // Observation Strategy Dropdown  loaded successfully
+    expect(content.queryByText('Task Parameters')).not.toBeInTheDocument();      // JSON Editor not rendered
+    expect(content.queryByTestId('save-btn')).toHaveAttribute("disabled");
+});
+
+it("creates new Scheduling Unit with default values", async() => {
+    console.log("creates new Scheduling Unit with default values ------------------------");
+    
+    let content;
+    await act(async () => {
+        content = render(<Router><SchedulingUnitCreate /></Router>);
+    });
+
+    const nameInput = content.queryByTestId('name');
+    const descInput = content.queryByTestId('description');
+    const projInput = content.getAllByRole("listbox")[0].children[2] ;
+    const observStrategyInput = content.getAllByRole("listbox")[2].children[0] ;
+    
+    // Set values for all mandatory input and test if save button is enabled
+    fireEvent.change(nameInput, { target: { value: 'UC1 test scheduling unit 1.1' } });
+    expect(nameInput.value).toBe("UC1 test scheduling unit 1.1");
+    fireEvent.change(descInput, { target: { value: 'UC1 test scheduling unit 1.1' } });
+    expect(descInput.value).toBe("UC1 test scheduling unit 1.1");
+    
+    // After selecting values for all dropdowns
+    await act(async () => {
+        fireEvent.click(projInput);
+    });
+    const schedulingSetInput = content.getAllByRole("listbox")[1].children[0] ;
+    expect(content.queryAllByText('Select Project').length).toBe(1);
+    expect(content.queryAllByText('TMSS-Commissioning').length).toBe(3);
+    
+    await act(async () => {
+        fireEvent.click(schedulingSetInput);
+    });
+    expect(content.queryAllByText('Select Scheduling Set').length).toBe(1);
+    expect(content.queryAllByText('Test Scheduling Set UC1 example 0').length).toBe(3);
+    
+    await act( async() => {
+        fireEvent.click(observStrategyInput);
+    });
+    expect(content.queryAllByText('Select Strategy').length).toBe(1);
+    expect(content.queryAllByText('UC1 observation strategy template').length).toBe(3);
+    expect(content.queryByText('Task Parameters')).toBeInTheDocument();
+    expect(content.queryByText('Target Pointing 0')).toBeInTheDocument();
+    expect(content.queryByText('Not a valid input. Mimimum: 00:00:00, Maximum:23:59:59.')).not.toBeInTheDocument();
+    expect(content.queryByText('Not a valid input. Mimimum: 00:00:00, Maximum:90:00:00.')).not.toBeInTheDocument();
+    
+    /* This is set again to call the validateEditor function in the component. 
+        If this is removed, the editor validation will not occur in the test but works in browser.*/
+    await act( async() => {
+        fireEvent.change(nameInput, { target: { value: 'UC1 test scheduling unit 1.1' } });
+    });
+
+    expect(content.queryByTestId('save-btn').hasAttribute("disabled")).toBeFalsy();
+
+    await act(async () => {
+        fireEvent.click(content.queryByTestId('save-btn'));
+    });
+    expect(saveSUFromStrategySpy).toHaveBeenCalled();
+    
+});
\ No newline at end of file
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/index.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/index.js
index 062317b2127f42ca3115e39fba3964121f83f3c4..6d202556c02b04be61955e04696017798ce623ae 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/index.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/index.js
@@ -1,5 +1,6 @@
 import React, {Component} from 'react';
 import SchedulingUnitList from './SchedulingUnitList';
+import PageHeader from '../../layout/components/PageHeader';
 
 export class Scheduling extends Component {
     constructor(props){
@@ -14,7 +15,9 @@ export class Scheduling extends Component {
     render() {
 		   return (
             <>
-                <h2>Scheduling Unit - List</h2>
+                <PageHeader location={this.props.location} title={'Scheduling Unit - List'}
+                            actions={[{icon: 'fa fa-plus-square', title: 'Add New Scheduling Unit', 
+                                        props: {pathname: '/schedulingunit/create'}}]} />
                 {this.state.scheduleunit && 
 				<SchedulingUnitList /> }
 		    </>
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 f978f5907620d28130f89f5893c110d3344ca6ba..e27a10133358176a42bc1e5fd38154c1eee6fff9 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/edit.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/edit.js
@@ -12,6 +12,7 @@ import Jeditor from '../../components/JSONEditor/JEditor';
 
 import TaskService from '../../services/task.service';
 import AppLoader from "./../../layout/components/AppLoader";
+import PageHeader from '../../layout/components/PageHeader';
 
 
 export class TaskEdit extends Component {
@@ -190,7 +191,7 @@ export class TaskEdit extends Component {
         
         return (
             <React.Fragment>
-                <div className="p-grid">
+                {/*} <div className="p-grid">
                     <div className="p-col-10 p-lg-10 p-md-10">
                         <h2>Task - Edit</h2>
                     </div>
@@ -200,8 +201,8 @@ export class TaskEdit extends Component {
                             <i className="fa fa-window-close" style={{marginTop: "10px"}}></i>
                         </Link>
                     </div>
-                </div>
-				
+                    </div> */}
+				<PageHeader location={this.props.location} title={'Task - Edit'} actions={[{icon: 'fa-window-close',title:'Click to Close Task Edit Page' ,props : { pathname:  `/task/view/draft/${this.state.task?this.state.task.id:''}`}}]}/>
 				{isLoading ? <AppLoader/> :
                 <div>
 			        <div className="p-fluid">
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 a8d612e25fed0eb865b57cd798a5ad8134e0d3a3..8fba525a164738a9c539e668eff231345742deb9 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/view.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/view.js
@@ -1,12 +1,13 @@
 import React, {Component} from 'react';
 import {Link, Redirect} from 'react-router-dom'
 import moment from 'moment';
-
+import _ from 'lodash';
 import Jeditor from '../../components/JSONEditor/JEditor';
 
 import TaskService from '../../services/task.service';
 import { Chips } from 'primereact/chips';
 import AppLoader from '../../layout/components/AppLoader';
+import PageHeader from '../../layout/components/PageHeader';
 
 export class TaskView extends Component {
     DATE_FORMAT = 'YYYY-MMM-DD HH:mm:ss';
@@ -80,8 +81,9 @@ export class TaskView extends Component {
             .then((task) => {
                 if (task) {
                     TaskService.getSchedulingUnit(taskType, (taskType==='draft'?task.scheduling_unit_draft_id:task.scheduling_unit_blueprint_id))
-                        .then((schedulingUnit) => {
-                            this.setState({schedulingUnit: schedulingUnit});
+                        .then((schedulingUnit) => {console.log('schedulingUnit' ,schedulingUnit)
+                            let path = _.join(['/schedulingunit','view',((this.state.taskType === "draft")?'draft':'blueprint'),schedulingUnit.id], '/');
+                            this.setState({schedulingUnit: schedulingUnit, supath:path});
                         });
                         TaskService.getTaskTemplate(task.specifications_template_id)
                         .then((taskTemplate) => {
@@ -113,6 +115,22 @@ export class TaskView extends Component {
                                                     });
         }
 
+        let actions = [ ];
+        if (this.state.taskType === 'draft') {
+            actions = [{   icon: 'fa-edit',
+                            title:'Click to Edit Task', 
+                            props : { pathname:'/task/edit',
+                                        state: {taskId: this.state.task?this.state.task.id:''} 
+                                    } 
+                        },
+                        {   icon: 'fa-window-close',
+                            title:'Click to Close Task', 
+                            props : { pathname:'/task' }}];
+        }   else {
+            actions = [{    icon: 'fa-lock',
+                            title: 'Cannot edit blueprint'}];
+        }
+
         // Child component to render predecessors and successors list
         const TaskRelationList = ({ list }) => (
             <ul className="task-list">
@@ -126,7 +144,7 @@ export class TaskView extends Component {
           );
         return (
             <React.Fragment>
-                <div className="p-grid">
+                {/* <div className="p-grid">
                     <div className="p-col-10 p-lg-10 p-md-10">
                         <h2>Task - Details </h2>
                     </div>
@@ -147,7 +165,9 @@ export class TaskView extends Component {
                             <i className="fa fa-lock" style={{float:"right", marginTop: "10px"}}></i>
                         }
                     </div>
-                </div>
+                    </div> */}
+                <PageHeader location={this.props.location} title={'Task - View'} 
+                            actions={actions}/>
                 { this.state.isLoading? <AppLoader /> : this.state.task &&
                     <React.Fragment>
                         <div className="main-content">
@@ -181,7 +201,7 @@ export class TaskView extends Component {
                             {this.state.schedulingUnit &&
                             <>
                                 <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>
+                                <Link className="col-lg-4 col-md-4 col-sm-12" to={ { pathname:this.state.supath, state: {id: this.state.schedulingUnit.id}}}>{this.state.schedulingUnit?this.state.schedulingUnit.name:''}</Link>
                             </>}
                         </div>
                         <div className="p-grid">
@@ -204,7 +224,7 @@ export class TaskView extends Component {
                                 }
                                 {this.state.taskType === 'blueprint' &&
                                     // <Link className="col-lg-4 col-md-4 col-sm-12" to={ { pathname:'/task/view', state: {id: this.state.task.draft_id, type: 'draft'}}}>{this.state.task.draftObject.name}</Link>
-                                    <Link className="col-lg-4 col-md-4 col-sm-12" to={ { pathname:`/task/view/draft/${this.state.task.draft_id}`}}>{this.state.task.draftObject.name}</Link>
+                                    <Link to={ { pathname:`/task/view/draft/${this.state.task.draft_id}`}}>{this.state.task.draftObject.name}</Link>
                                 }
                             </div>
                         </div>
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/index.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/index.js
index 0739e7824a404d7e1a21de18298cd809ae0dd79d..bebe99d8eb04460c38b2097e576b94ce6d5dfc16 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/index.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/index.js
@@ -10,82 +10,115 @@ import {ProjectList, ProjectCreate, ProjectView, ProjectEdit} from './Project';
 import {Dashboard} from './Dashboard';
 import {Scheduling} from './Scheduling';
 import {TaskEdit, TaskView} from './Task';
-import ViewSchedulingUnit from './Scheduling/ViewSchedulingUnit'
+import ViewSchedulingUnit from './Scheduling/ViewSchedulingUnit';
+import SchedulingUnitCreate from './Scheduling/create';
 import { CycleList, CycleCreate, CycleView, CycleEdit } from './Cycle';
 
 export const routes = [
     {
         path: "/not-found",
-        component: NotFound
+        component: NotFound,
+        
     },{
         path: "/dashboard",
         component: Dashboard,
-        name: 'Dashboard'
+        name: 'Dashboard',
+        title: 'Dashboard'
     },{
         path: "/schedulingunit",
         component: Scheduling,
-        name: 'Scheduling Unit'
+        name: 'Scheduling Unit',
+        title: 'Scheduling Unit - List'
+    },{
+        path: "/schedulingunit/create",
+        component: SchedulingUnitCreate,
+        name: 'Scheduling Unit Add'
     },{
         path: "/task",
         component: TaskView,
-        name: 'Task'
+        name: 'Task',
+        title: 'Task-View'
     },{
         path: "/task/view",
         component: TaskView,
-        name: 'Task'
+        name: 'Task',
+        title: 'Task View'
     },{
         path: "/task/view/:type/:id",
         component: TaskView,
-        name: 'Task Details'
+        name: 'Task Details',
+        title: 'Task Details'
     },{
         path: "/task/edit",
         component: TaskEdit,
-        name: 'Task Edit'
+        name: 'Task Edit',
+        title: 'Task-Edit'
     },{
         path: "/schedulingunit/view",
         component: ViewSchedulingUnit,
+        name: 'Scheduling View',
+        title: 'Scheduling Unit - Details'
+    },{
+        path: "/schedulingunit/view/:type/:id",
+        component: ViewSchedulingUnit,
         name: 'Scheduling View'
     },{
         path: "/project",
         component: ProjectList,
-        name: 'Project List'
+        name: 'Project List',
+        title: 'Project - List'
     },{
         path: "/project/create",
         component: ProjectCreate,
-        name: 'Project Add'
+        name: 'Project Add',
+        title: 'Project - Add'
     },{
         path: "/project/view",
         component: ProjectView,
-        name: 'Project View'
+        name: 'Project View',
+        title: 'Project - Details '
     },{
         path: "/project/view/:id",
         component: ProjectView,
-        name: 'Project View'
-    },{
+        name: 'Project View',
+        title: 'Project - View'
+    },
+    {
         path: "/project/edit/:id",
         component: ProjectEdit,
-        name: 'Project Edit'
+        name: 'Project Edit',
+        title: 'Project Edit'
+    },{
+        path: "/project/:project/schedulingunit/create",
+        component: SchedulingUnitCreate,
+        name: 'Scheduling Unit Add',
+        title: 'Scheduling Unit - Add'
     },{
         path: "/cycle/edit/:id",
         component: CycleEdit,
-        name: 'Cycle Edit'
+        name: 'Cycle Edit',
+        title:'Cycle-Edit'
     },{
         path: "/cycle/view",
         component: CycleView,
-        name: 'Cycle View'
+        name: 'Cycle View',
+        title:'Cycle-View'
     },{
         path: "/cycle/view/:id",
         component: CycleView,
-        name: 'Cycle View'
+        name: 'Cycle View',
+        title:'Cycle-View'
     }, {
         path: "/cycle/create",
         component: CycleCreate,
-        name: 'Cycle Add'
+        name: 'Cycle Add',
+        title:'Cycle-Add'
     },
     {
         path: "/cycle",
         component: CycleList,
-        name: 'Cycle List'
+        name: 'Cycle List',
+        title:'Cycle-List'
     },
 ];
 
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 f09e1da9e877f7867ce4f2614cabadccf3a9f6aa..a7e65ace0ccd24316cb5902bf1741a14cc94fddb 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/services/schedule.service.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/services/schedule.service.js
@@ -1,5 +1,7 @@
 import axios from 'axios'
-import _ from 'lodash';
+import moment from 'moment';
+
+import TaskService from './task.service';
 
 axios.defaults.headers.common['Authorization'] = 'Basic dGVzdDp0ZXN0';
 
@@ -24,26 +26,68 @@ const ScheduleService = {
         });
         return res;
     },
+    getSchedulingUnitBlueprintById: async function (id){
+        try {
+            const response = await axios.get('/api/scheduling_unit_blueprint/'+id);
+            let schedulingUnit = response.data;
+            if (schedulingUnit) {
+                const schedulingUnitDraft = await this.getSchedulingUnitDraftById(schedulingUnit.draft_id);
+                schedulingUnit.scheduling_set_id = schedulingUnitDraft.scheduling_set_id;
+                schedulingUnit.scheduling_set = schedulingUnitDraft.scheduling_set;
+                schedulingUnit.scheduling_set_object = schedulingUnitDraft.scheduling_set_object;
+            }
+            return schedulingUnit;
+        }   catch(error) {
+            console.error(error);
+            return null;
+        }
+    },
     getSchedulingUnitDraftById: async function (id){
+        try {
+            const schedulingUnit = (await axios.get('/api/scheduling_unit_draft/'+id)).data;
+            const schedulingSet = (await axios.get(`/api/scheduling_set/${schedulingUnit.scheduling_set_id}`)).data;
+            schedulingUnit.scheduling_set_object = schedulingSet;
+            return schedulingUnit;
+        }   catch(error){
+            console.error('[schedule.services.getSchedulingUnitDraftById]',error);
+            return null;
+        }
+    },
+    getTaskBlueprintById: async function(id){
         let res = [];
-        await axios.get('/api/scheduling_unit_draft/'+id)
+        await axios.get('/api/task_blueprint/'+id)
         .then(response => {
             res= response; 
         }).catch(function(error) {
-            console.error('[schedule.services.getSchedulingUnitDraftById]',error);
+            console.error('[schedule.services.getTaskBlueprintById]',error);
         });
         return res;
     },
-    getScheduleTasksBySchedulingUnitId: async function(id){
+    getTaskBlueprintsBySchedulingUnit: async function(scheduleunit){
+        // there no single api to fetch associated task_blueprint, so iteare the task_blueprint id to fetch associated task_blueprint
+        let taskblueprintsList = [];
+        if(scheduleunit.task_blueprints_ids){
+            for(const id of scheduleunit.task_blueprints_ids){
+               await this.getTaskBlueprintById(id).then(response =>{
+                    let taskblueprint = response.data;
+                    taskblueprint['tasktype'] = 'Blueprint';
+                    taskblueprint['actionpath'] = '/task/view/blueprint/'+taskblueprint['id'];
+                    taskblueprint['blueprint_draft'] = taskblueprint['draft'];
+                    taskblueprint['relative_start_time'] = 0;
+                    taskblueprint['relative_stop_time'] = 0;
+                    taskblueprint.duration = moment.utc(taskblueprint.duration*1000).format('HH:mm:ss'); 
+                    taskblueprintsList.push(taskblueprint);
+                })
+            }
+        }
+        return taskblueprintsList;
+    },
+    getTasksBySchedulingUnit: async function(id){
         let scheduletasklist=[];
-        let taskblueprints = [];
         // 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'];
-        await this.getTaskBlueprints().then( blueprints =>{
-            taskblueprints = blueprints.data.results;
-        })
         await this.getTasksDraftBySchedulingUnitId(id)
-        .then(response =>{
+        .then(async(response) =>{
             for(const task of response.data.results){
                 let scheduletask = [];
                 scheduletask['tasktype'] = 'Draft';
@@ -54,13 +98,12 @@ const ScheduleService = {
                 for(const key of commonkeys){
                     scheduletask[key] = task[key];
                 }
-
+                scheduletask.duration = moment.utc(scheduletask.duration*1000).format('HH:mm:ss'); 
+                scheduletask.relative_start_time = moment.utc(scheduletask.relative_start_time*1000).format('HH:mm:ss'); 
+                scheduletask.relative_stop_time = moment.utc(scheduletask.relative_stop_time*1000).format('HH:mm:ss'); 
                //Fetch blueprint details for Task Draft
-                let filteredblueprints =  _.filter(taskblueprints, function(o) {
-                    if (o.draft_id === task['id']) return o;
-                });
-
-                for(const blueprint of filteredblueprints){
+                const draftBlueprints = await TaskService.getDraftsTaskBlueprints(task.id);
+                for(const blueprint of draftBlueprints){
                     let taskblueprint = [];
                     taskblueprint['tasktype'] = 'Blueprint';
                     taskblueprint['actionpath'] = '/task/view/blueprint/'+blueprint['id'];
@@ -68,6 +111,10 @@ const ScheduleService = {
                     for(const key of commonkeys){
                         taskblueprint[key] = blueprint[key];
                     }
+                    taskblueprint.duration = moment.utc(taskblueprint.duration*1000).format('HH:mm:ss'); 
+                    taskblueprint.relative_start_time = moment.utc(taskblueprint.relative_start_time*1000).format('HH:mm:ss'); 
+                    taskblueprint.relative_stop_time = moment.utc(taskblueprint.relative_stop_time*1000).format('HH:mm:ss'); 
+
                     //Add Blue print details to array
                     scheduletasklist.push(taskblueprint);
                 }
@@ -119,6 +166,68 @@ const ScheduleService = {
         });
         return res;
     },
+    getSchedulingSets: async function() {
+        try {
+            const response = await axios.get('/api/scheduling_set/');
+            return response.data.results;
+        }   catch(error) {
+            console.error(error);
+            return [];
+        };
+    },
+    getObservationStrategies: async function() {
+        try {
+            const response = await axios.get('/api/scheduling_unit_observing_strategy_template/');
+            return response.data.results;
+        }   catch(error) {
+            console.error(error);
+            return [];
+        };
+    },
+    saveSUDraftFromObservStrategy: async function(observStrategy, schedulingUnit) {
+        try {
+            // Create the scheduling unit draft with observation strategy and scheduling set
+            const url = `/api/scheduling_unit_observing_strategy_template/${observStrategy.id}/create_scheduling_unit/?scheduling_set_id=${schedulingUnit.scheduling_set_id}&name=${schedulingUnit.name}&description=${schedulingUnit.description}`
+            const suObsResponse = await axios.get(url);
+            schedulingUnit = suObsResponse.data;
+            if (schedulingUnit && schedulingUnit.id) {
+                // Update the newly created SU draft requirement_doc with captured parameter values
+                schedulingUnit.requirements_doc = observStrategy.template;
+                delete schedulingUnit['duration'];
+                schedulingUnit = await this.updateSchedulingUnitDraft(schedulingUnit);
+                if (!schedulingUnit || !schedulingUnit.id) {
+                    return null;
+                }
+                // Create task drafts with updated requirement_doc
+                schedulingUnit = await this.createSUTaskDrafts(schedulingUnit);
+                if (schedulingUnit && schedulingUnit.task_drafts.length > 0) {
+                    return schedulingUnit;
+                }
+            }
+            return null;
+        }   catch(error) {
+            console.error(error);
+            return null;
+        };
+    },
+    updateSchedulingUnitDraft: async function(schedulingUnit) {
+        try {
+            const suUpdateResponse = await axios.put(`/api/scheduling_unit_draft/${schedulingUnit.id}/`, schedulingUnit);
+            return suUpdateResponse.data;
+        }   catch(error) {
+            console.error(error);
+            return null
+        }
+    },
+    createSUTaskDrafts: async (schedulingUnit) => {
+        try {
+            const suCreateTaskResponse = await axios.get(`/api/scheduling_unit_draft/${schedulingUnit.id}/create_task_drafts/`);
+            return suCreateTaskResponse.data;
+        }   catch(error) {
+            console.error(error);
+            return null;
+        }
+    }
 }
 
 export default ScheduleService;
\ No newline at end of file
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/services/task.service.js b/SAS/TMSS/frontend/tmss_webapp/src/services/task.service.js
index e55f34d594e5c81fd4aca1d819e9def4820155ac..bf908a57c61c92a9cb56d897a026f5ef52269b3a 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/services/task.service.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/services/task.service.js
@@ -49,7 +49,8 @@ const TaskService = {
     },
     getSchedulingUnit: async function(type, id) {
       try {
-        const response = await axios.get('/api/scheduling_unit_draft/' + id);
+        const url = `/api/scheduling_unit_${type}/${id}`;
+        const response = await axios.get(url);
         return response.data;
       } catch (error) {
         console.error(error);
diff --git a/SAS/TMSS/src/tmss/tmssapp/CMakeLists.txt b/SAS/TMSS/src/tmss/tmssapp/CMakeLists.txt
index ce90a97ca56b68023feb255adaa33e5cfc18c586..311d21b6b56d1a4fa3b7b97021d0cde8ccd5d04e 100644
--- a/SAS/TMSS/src/tmss/tmssapp/CMakeLists.txt
+++ b/SAS/TMSS/src/tmss/tmssapp/CMakeLists.txt
@@ -9,6 +9,7 @@ set(_py_files
     populate.py
     subtasks.py
     tasks.py
+    conversions.py
     )
 
 python_install(${_py_files}
diff --git a/SAS/TMSS/src/tmss/tmssapp/adapters/sip.py b/SAS/TMSS/src/tmss/tmssapp/adapters/sip.py
index 6a2080dc014016dcdc86e6843269fc5220d2b517..3de850a26251957507e23f9e1ac0f21d5b832fc7 100644
--- a/SAS/TMSS/src/tmss/tmssapp/adapters/sip.py
+++ b/SAS/TMSS/src/tmss/tmssapp/adapters/sip.py
@@ -31,6 +31,7 @@ mapping_filterset_type_TMSS_2_SIP = {
     "HBA_210_250": constants.FILTERSELECTIONTYPE_210_250_MHZ
 }
 
+
 def get_number_of_dataproducts_of_type(subtask, dataproduct_datatype):
     """
     Retrieve the number of dataproducts of given data type in subtask:
@@ -42,7 +43,7 @@ def get_number_of_dataproducts_of_type(subtask, dataproduct_datatype):
     subtask_outputs = list(SubtaskOutput.objects.filter(subtask_id=subtask.id))
     for subtask_output in subtask_outputs:
         dataproducts = list(Dataproduct.objects.filter(producer_id=subtask_output.id,
-                                                       dataformat=dataproduct_datatype))
+                                                       datatype=dataproduct_datatype))
         nbr_dataproduct += len(dataproducts)
     return nbr_dataproduct
 
@@ -248,8 +249,7 @@ def create_sip_representation_for_dataproduct(dataproduct: Dataproduct):
                           "unknown": constants.STORAGEWRITERTYPE_UNKNOWN}
 
     try:
-        # todo: why is this not with the data but with the connector? The type of data should not depend on what it is used for? I don't get it... - what if we have several connectors?
-        dataproduct_type = type_map[dataproduct.producer.subtask.task_blueprint.specifications_template.output_connector_types.first().datatype.value]  # todo: does not work on the main dataproduct?
+        dataproduct_type = type_map[dataproduct.datatype.value]
     except Exception as err:
         dataproduct_type = constants.DATAPRODUCTTYPE_UNKNOWN
         logger.warning("Could not determine the type of dataproduct id %s (%s). Falling back to %s" % (dataproduct.id, err, dataproduct_type))
diff --git a/SAS/TMSS/src/tmss/tmssapp/conversions.py b/SAS/TMSS/src/tmss/tmssapp/conversions.py
new file mode 100644
index 0000000000000000000000000000000000000000..e851ecbe396955955f1ae9dc1f32890cb819b53d
--- /dev/null
+++ b/SAS/TMSS/src/tmss/tmssapp/conversions.py
@@ -0,0 +1,41 @@
+from astropy.time import Time
+import astropy.units
+from lofar.lta.sip import station_coordinates
+from datetime import datetime
+from astropy.coordinates.earth import EarthLocation
+
+
+def local_sidereal_time_for_utc_and_station(timestamp: datetime = None,
+                                            station: str = 'CS002',
+                                            field: str = 'LBA',
+                                            kind: str = "apparent"):
+    """
+    calculate local sidereal time for given utc time and station
+    :param timestamp: timestamp as datetime object
+    :param station: station name
+    :param field: antennafield, 'LBA' or 'HBA'
+    :param kind: 'mean' or 'apparent'
+    :return:
+    """
+    if timestamp is None:
+        timestamp = datetime.utcnow()
+    station_coords = station_coordinates.parse_station_coordinates()
+    field_coords = station_coords["%s_%s" % (station, field)]
+    location = EarthLocation.from_geocentric(x=field_coords['x'], y=field_coords['y'], z=field_coords['z'], unit=astropy.units.m)
+    return local_sidereal_time_for_utc_and_longitude(timestamp=timestamp, longitude=location.lon.to_string(decimal=True), kind=kind)
+
+
+def local_sidereal_time_for_utc_and_longitude(timestamp: datetime = None,
+                                              longitude: float = 6.8693028,
+                                              kind: str = "apparent"):
+    """
+    :param timestamp: timestamp as datetime object
+    :param longitude: decimal longitude of observer location (defaults to CS002 LBA center)
+    :param kind: 'mean' or 'apparent'
+    :return:
+    """
+    if timestamp is None:
+        timestamp = datetime.utcnow()
+    t = Time(timestamp, format='datetime', scale='utc')
+    return t.sidereal_time(kind=kind, longitude=longitude)
+
diff --git a/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py b/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py
index 77d47478a440ed426e0b651f522874a8ab2b8fff..24795d174b38e89c28ed9683403e7e5f26b13187 100644
--- a/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py
+++ b/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py
@@ -1,4 +1,4 @@
-# Generated by Django 2.2.12 on 2020-08-04 12:35
+# Generated by Django 3.0.9 on 2020-09-09 13:04
 
 from django.conf import settings
 import django.contrib.postgres.fields
@@ -52,6 +52,7 @@ class Migration(migrations.Migration):
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
                 ('description', models.CharField(help_text='A longer description of this object.', max_length=255)),
                 ('location', models.CharField(help_text='Human-readable location of the cluster.', max_length=128)),
+                ('archive_site', models.BooleanField(help_text='TRUE if this cluster is an archive site, FALSE if not (f.e. a local cluster, or user-owned cluster).')),
             ],
             options={
                 'abstract': False,
@@ -304,6 +305,7 @@ class Migration(migrations.Migration):
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
                 ('description', models.CharField(help_text='A longer description of this object.', max_length=255)),
                 ('capacity', models.BigIntegerField(help_text='Capacity in bytes')),
+                ('directory', models.CharField(help_text='Root directory under which we are allowed to write our data.', max_length=1024)),
             ],
             options={
                 'abstract': False,
@@ -358,6 +360,7 @@ class Migration(migrations.Migration):
                 ('private_data', models.BooleanField(default=True, help_text='True if data of this project is sensitive. Sensitive data is not made public.')),
                 ('expert', models.BooleanField(default=False, help_text='Expert projects put more responsibility on the PI.')),
                 ('filler', models.BooleanField(default=False, help_text='Use this project to fill up idle telescope time.')),
+                ('archive_subdirectory', models.CharField(help_text='Subdirectory in which this project will store its data in the LTA. The full directory is constructed by prefixing with archive_location→directory.', max_length=1024)),
             ],
             options={
                 'abstract': False,
@@ -1060,6 +1063,11 @@ class Migration(migrations.Migration):
             name='resource_type',
             field=models.ForeignKey(help_text='Resource type.', on_delete=django.db.models.deletion.PROTECT, to='tmssapp.ResourceType'),
         ),
+        migrations.AddField(
+            model_name='project',
+            name='archive_location',
+            field=models.ForeignKey(help_text='Ingest data to this LTA cluster only (NULLable). NULL means: no preference.', null=True, on_delete=django.db.models.deletion.PROTECT, to='tmssapp.Filesystem'),
+        ),
         migrations.AddField(
             model_name='project',
             name='cycles',
@@ -1152,6 +1160,11 @@ class Migration(migrations.Migration):
             name='dataformat',
             field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tmssapp.Dataformat'),
         ),
+        migrations.AddField(
+            model_name='dataproduct',
+            name='datatype',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tmssapp.Datatype'),
+        ),
         migrations.AddField(
             model_name='dataproduct',
             name='feedback_template',
@@ -1177,6 +1190,10 @@ class Migration(migrations.Migration):
             name='resource_type',
             field=models.ForeignKey(help_text='Resource type.', on_delete=django.db.models.deletion.PROTECT, to='tmssapp.ResourceType'),
         ),
+        migrations.AddConstraint(
+            model_name='commonschematemplate',
+            constraint=models.UniqueConstraint(fields=('name', 'version'), name='commonschematemplate_unique_name_version'),
+        ),
         migrations.AddField(
             model_name='antennaset',
             name='station_type',
diff --git a/SAS/TMSS/src/tmss/tmssapp/models/scheduling.py b/SAS/TMSS/src/tmss/tmssapp/models/scheduling.py
index a68d3f566c92d25b1582386634904001dde549fa..a84cdfe8ef973725814bdc6febd9dcc430cf1d21 100644
--- a/SAS/TMSS/src/tmss/tmssapp/models/scheduling.py
+++ b/SAS/TMSS/src/tmss/tmssapp/models/scheduling.py
@@ -262,6 +262,7 @@ class Dataproduct(BasicCommon):
     filename = CharField(max_length=128, help_text='Name of the file (or top-level directory) of the dataproduct. Adheres to a naming convention, but is not meant for parsing.')
     directory = CharField(max_length=1024, help_text='Directory where this dataproduct is (to be) stored.')
     dataformat = ForeignKey('Dataformat', null=False, on_delete=PROTECT)
+    datatype = ForeignKey('Datatype', null=False, on_delete=PROTECT)
     deleted_since = DateTimeField(null=True, help_text='When this dataproduct was removed from disk, or NULL if not deleted (NULLable).')
     pinned_since = DateTimeField(null=True, help_text='When this dataproduct was pinned to disk, that is, forbidden to be removed, or NULL if not pinned (NULLable).')
     specifications_doc = JSONField(help_text='Dataproduct properties (f.e. beam, subband), to distinguish them when produced by the same task, and to act as input for selections in the Task Input and Work Request Relation Blueprint objects.')
@@ -298,10 +299,18 @@ class DataproductTransform(BasicCommon):
 class Filesystem(NamedCommon):
     capacity = BigIntegerField(help_text='Capacity in bytes')
     cluster = ForeignKey('Cluster', on_delete=PROTECT, help_text='Cluster hosting this filesystem.')
+    directory = CharField(max_length=1024, help_text='Root directory under which we are allowed to write our data.')
+
+    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
+        if self.directory and not self.directory.endswith('/'):
+            raise ValueError('directory value must end with a trailing slash!')  # todo: ...and needs to start with slash?
+
+        super().save(force_insert, force_update, using, update_fields)
 
 
 class Cluster(NamedCommon):
     location = CharField(max_length=128, help_text='Human-readable location of the cluster.')
+    archive_site = BooleanField(help_text='TRUE if this cluster is an archive site, FALSE if not (f.e. a local cluster, or user-owned cluster).')
 
 
 class DataproductArchiveInfo(BasicCommon):
diff --git a/SAS/TMSS/src/tmss/tmssapp/models/specification.py b/SAS/TMSS/src/tmss/tmssapp/models/specification.py
index 5329fc542b8b7a85fa5f6f06b858856961d8a90a..11cfec223a0e92c7332dc7f2814a46a05148ca20 100644
--- a/SAS/TMSS/src/tmss/tmssapp/models/specification.py
+++ b/SAS/TMSS/src/tmss/tmssapp/models/specification.py
@@ -359,6 +359,16 @@ class Project(NamedCommonPK):
     filler = BooleanField(default=False, help_text='Use this project to fill up idle telescope time.')
     project_category = ForeignKey('ProjectCategory', null=True, on_delete=PROTECT, help_text='Project category.')
     period_category = ForeignKey('PeriodCategory', null=True, on_delete=PROTECT, help_text='Period category.')
+    archive_location = ForeignKey('Filesystem', null=True, on_delete=PROTECT, help_text='Ingest data to this LTA cluster only (NULLable). NULL means: no preference.')
+    archive_subdirectory = CharField(max_length=1024, help_text='Subdirectory in which this project will store its data in the LTA. The full directory is constructed by prefixing with archive_location→directory.')
+
+    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
+        if self.archive_subdirectory and not self.archive_subdirectory.endswith('/'):
+            raise ValueError('directory value must end with a trailing slash!')
+        if self.archive_subdirectory and self.archive_subdirectory.startswith('/'):
+            raise ValueError('directory value must be a relative path (and not start with a slash)!')
+
+        super().save(force_insert, force_update, using, update_fields)
 
     # JK, 29/07/20 - after discussion with Sander, it turns out that the ticket TMSS-277 was a misunderstanding.
     #  'default' does not refer to 'default values' that are supposed to be filled in by the backend.
diff --git a/SAS/TMSS/src/tmss/tmssapp/populate.py b/SAS/TMSS/src/tmss/tmssapp/populate.py
index adf8ed32faa68bd6a84331100b29be71faaca615..538afcae209e97d6036bfd7050f75d500814351b 100644
--- a/SAS/TMSS/src/tmss/tmssapp/populate.py
+++ b/SAS/TMSS/src/tmss/tmssapp/populate.py
@@ -156,7 +156,7 @@ def populate_resources(apps, schema_editor):
 
 
 def populate_misc(apps, schema_editor):
-    cluster = Cluster.objects.create(name="CEP4", location="CIT")
+    cluster = Cluster.objects.create(name="CEP4", location="CIT", archive_site=False)
     fs = Filesystem.objects.create(name="LustreFS", cluster=cluster, capacity=3.6e15)
 
 
diff --git a/SAS/TMSS/src/tmss/tmssapp/subtasks.py b/SAS/TMSS/src/tmss/tmssapp/subtasks.py
index 22c1e7bbbf157c9459b731daea0c7ecae1e93246..fd7f178571280a7e7c7c688bf72bcca2b3cf832c 100644
--- a/SAS/TMSS/src/tmss/tmssapp/subtasks.py
+++ b/SAS/TMSS/src/tmss/tmssapp/subtasks.py
@@ -546,6 +546,7 @@ def schedule_qafile_subtask(qafile_subtask: Subtask):
         qafile_subtask_dataproduct = Dataproduct.objects.create(filename="L%s_QA.h5" % (qa_input.producer.subtask_id, ),
                                                                 directory="/data/qa/qa_files",
                                                                 dataformat=Dataformat.objects.get(value=Dataformat.Choices.QA_HDF5.value),
+                                                                datatype=Datatype.objects.get(value=Datatype.Choices.QUALITY.value),   # todo: is this correct?
                                                                 producer=qafile_subtask.outputs.first(),
                                                                 specifications_doc="",
                                                                 specifications_template=DataproductSpecificationsTemplate.objects.first(), # ?????
@@ -596,6 +597,7 @@ def schedule_qaplots_subtask(qaplots_subtask: Subtask):
     obs_subtask = qafile_subtask.predecessors.first()
     qaplots_subtask_dataproduct = Dataproduct.objects.create(directory="/data/qa/plots/L%s" % (obs_subtask.id, ),
                                                              dataformat=Dataformat.objects.get(value=Dataformat.Choices.QA_PLOTS.value),
+                                                             datatype=Datatype.objects.get(value=Datatype.Choices.QUALITY.value),   # todo: is this correct?
                                                              producer=qaplots_subtask.outputs.first(),
                                                              specifications_doc="",
                                                              specifications_template=DataproductSpecificationsTemplate.objects.first(), # ?????
@@ -715,6 +717,7 @@ def schedule_observation_subtask(observation_subtask: Subtask):
             Dataproduct.objects.create(filename="L%d_SAP%03d_SB%03d_uv.MS" % (observation_subtask.id, sap_nr, sb_nr),
                                        directory=directory,
                                        dataformat=Dataformat.objects.get(value="MeasurementSet"),
+                                       datatype=Datatype.objects.get(value="visibilities"),  # todo: is this correct?
                                        producer=subtask_output,
                                        specifications_doc={"sap": [sap_nr]},  # todo: set correct value. This will be provided by the RA somehow
                                        specifications_template=dataproduct_specifications_template,
@@ -795,6 +798,7 @@ def schedule_pipeline_subtask(pipeline_subtask: Subtask):
             output_dp = Dataproduct.objects.create(filename=filename,
                                                    directory=input_dp.directory.replace(str(pipeline_subtask_input.producer.subtask.pk), str(pipeline_subtask.pk)),
                                                    dataformat=Dataformat.objects.get(value="MeasurementSet"),
+                                                   datatype=Datatype.objects.get(value="visibilities"),  # todo: is this correct?
                                                    producer=pipeline_subtask_output,
                                                    specifications_doc={},
                                                    specifications_template=dataproduct_specifications_template,
diff --git a/SAS/TMSS/src/tmss/tmssapp/views.py b/SAS/TMSS/src/tmss/tmssapp/views.py
index 9cf93ceffcf081c5742ca524341616b71a18ed82..1f9f0cf22f505d00cdd7a20c1e7fd068d4a3e5c1 100644
--- a/SAS/TMSS/src/tmss/tmssapp/views.py
+++ b/SAS/TMSS/src/tmss/tmssapp/views.py
@@ -10,6 +10,9 @@ from rest_framework.permissions import AllowAny
 from rest_framework.decorators import authentication_classes, permission_classes
 from django.apps import apps
 
+from datetime import datetime
+import dateutil.parser
+from lofar.sas.tmss.tmss.tmssapp.conversions import local_sidereal_time_for_utc_and_station, local_sidereal_time_for_utc_and_longitude
 
 def subtask_template_default_specification(request, subtask_template_pk:int):
     subtask_template = get_object_or_404(models.SubtaskTemplate, pk=subtask_template_pk)
@@ -27,19 +30,22 @@ def subtask_parset(request, subtask_pk:int):
     subtask = get_object_or_404(models.Subtask, pk=subtask_pk)
     parset = convert_to_parset(subtask)
     return HttpResponse(str(parset), content_type='text/plain')
-    
+
+
 def index(request):
     return render(request, os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), '../../frontend','tmss_webapp/build/index.html'))
     #return render(request, "../../../frontend/frontend_poc/build/index.html")
 
+
 def task_specify_observation(request, pk=None):
     task = get_object_or_404(models.TaskDraft, pk=pk)
     return HttpResponse("response", content_type='text/plain')
 
+# Allow everybody to GET our publicly available template-json-schema's
 @permission_classes([AllowAny])
 @authentication_classes([AllowAny])
-@swagger_auto_schema(responses={200: 'JSON schema',
-                                404: 'the schema with requested <name> and <version> is not available'},
+@swagger_auto_schema(responses={200: 'Get the JSON schema from the template with the requested <template>, <name> and <version>',
+                                404: 'the schema with requested <template>, <name> and <version> is not available'},
                      operation_description="Get the JSON schema for the given <template> with the given <name> and <version> as application/json content response.")
 def get_template_json_schema(request, template:str, name:str, version:str):
     template_model = apps.get_model("tmssapp", template)
@@ -48,3 +54,29 @@ def get_template_json_schema(request, template:str, name:str, version:str):
     return JsonResponse(schema, json_dumps_params={"indent":2})
 
 
+def utc(request):
+    return HttpResponse(datetime.utcnow().isoformat(), content_type='text/plain')
+
+
+def lst(request):
+    # Handling optional parameters via django paths in urls.py is a pain, we access them on the request directly instead.
+    timestamp = request.GET.get('timestamp', None)
+    station = request.GET.get('station', None)
+    longitude = request.GET.get('longitude', None)
+
+    # conversions
+    if timestamp:
+        timestamp = dateutil.parser.parse(timestamp)  #  isot to datetime
+    if longitude:
+        longitude = float(longitude)
+
+    if station:
+        lst_lon = local_sidereal_time_for_utc_and_station(timestamp, station)
+    elif longitude:
+        lst_lon = local_sidereal_time_for_utc_and_longitude(timestamp, longitude)
+    else:
+        # fall back to defaults
+        lst_lon = local_sidereal_time_for_utc_and_station(timestamp)
+
+    # todo: do we want to return a dict, so users can make sure their parameters were parsed correctly instead?
+    return HttpResponse(str(lst_lon), content_type='text/plain')
\ No newline at end of file
diff --git a/SAS/TMSS/src/tmss/urls.py b/SAS/TMSS/src/tmss/urls.py
index 7263809f600a50bbaad3265824bd44092058d56b..ef97811529808a8fec693b6b590ed7f8b045199f 100644
--- a/SAS/TMSS/src/tmss/urls.py
+++ b/SAS/TMSS/src/tmss/urls.py
@@ -28,6 +28,8 @@ from rest_framework.documentation import include_docs_urls
 from drf_yasg.views import get_schema_view
 from drf_yasg import openapi
 
+from datetime import datetime
+
 #
 # Django style patterns
 #
@@ -56,7 +58,10 @@ urlpatterns = [
     path('swagger/', swagger_schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
     path('redoc/', swagger_schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
     path('schemas/<str:template>/<str:name>/<str:version>', views.get_template_json_schema, name='get_template_json_schema'), #TODO: how to make trailing slash optional?
-    path('schemas/<str:template>/<str:name>/<str:version>/', views.get_template_json_schema, name='get_template_json_schema')]
+    path('schemas/<str:template>/<str:name>/<str:version>/', views.get_template_json_schema, name='get_template_json_schema'),
+    path(r'util/utc', views.utc, name="system-utc"),
+    path(r'util/lst', views.lst, name="conversion-lst")
+]
 
 
 #
diff --git a/SAS/TMSS/test/CMakeLists.txt b/SAS/TMSS/test/CMakeLists.txt
index b19ddcd546e283f0e176ecaf57711bb3b8b8f03c..769fce231ac3bc18470ae3c974456d4ec089ff68 100644
--- a/SAS/TMSS/test/CMakeLists.txt
+++ b/SAS/TMSS/test/CMakeLists.txt
@@ -32,6 +32,7 @@ if(BUILD_TESTING)
     lofar_add_test(t_adapter)
     lofar_add_test(t_tasks)
     lofar_add_test(t_scheduling)
+    lofar_add_test(t_conversions)
 
     # To get ctest running
     file(COPY testdata DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
diff --git a/SAS/TMSS/test/t_conversions.py b/SAS/TMSS/test/t_conversions.py
new file mode 100755
index 0000000000000000000000000000000000000000..ccd4025f6c4c21a43d63f5ccb6a55c3b764f0963
--- /dev/null
+++ b/SAS/TMSS/test/t_conversions.py
@@ -0,0 +1,133 @@
+#!/usr/bin/env python3
+
+# Copyright (C) 2018    ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This file is part of the LOFAR software suite.
+# The LOFAR software suite is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# The LOFAR software suite is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+
+# $Id:  $
+
+import os
+import unittest
+import datetime
+import logging
+import requests
+import dateutil.parser
+import astropy.coordinates
+
+logger = logging.getLogger(__name__)
+logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=logging.INFO)
+from lofar.sas.tmss.tmss.tmssapp.conversions import local_sidereal_time_for_utc_and_station, local_sidereal_time_for_utc_and_longitude
+
+# Do Mandatory setup step:
+# use setup/teardown magic for tmss test database, ldap server and django server
+# (ignore pycharm unused import statement, python unittests does use at RunTime the tmss_test_environment_unittest_setup module)
+from lofar.sas.tmss.test.tmss_test_environment_unittest_setup import *
+
+class SiderealTime(unittest.TestCase):
+
+    def test_local_sidereal_time_for_utc_and_longitude_returns_correct_result(self):
+        # test result against known correct value
+        lst = local_sidereal_time_for_utc_and_longitude(timestamp=datetime.datetime(year=2020, month=1, day=1, hour=12, minute=0, second=0))
+        self.assertEqual(str(lst), '19h09m54.9567s')
+
+    def test_local_sidereal_time_for_utc_and_longitude_considers_timestamp(self):
+        # test that the results differ for different timestamps
+        lst1 = local_sidereal_time_for_utc_and_longitude(timestamp=datetime.datetime(year=2020, month=1, day=1, hour=12, minute=0, second=0))
+        lst2 = local_sidereal_time_for_utc_and_longitude(timestamp=datetime.datetime(year=2020, month=1, day=2, hour=12, minute=0, second=0))
+        self.assertNotEqual(str(lst1), str(lst2))
+
+    def test_local_sidereal_time_for_utc_and_longitude_considers_longitude(self):
+        # test that the results differ for different longitudes
+        lst1 = local_sidereal_time_for_utc_and_longitude(timestamp=datetime.datetime(year=2020, month=1, day=1, hour=12, minute=0, second=0), longitude=6.789)
+        lst2 = local_sidereal_time_for_utc_and_longitude(timestamp=datetime.datetime(year=2020, month=1, day=1, hour=12, minute=0, second=0), longitude=6.123)
+        self.assertNotEqual(str(lst1), str(lst2))
+
+    def test_local_sidereal_time_for_utc_and_station_returns_correct_result(self):
+        # assert result against known correct value
+        lst = local_sidereal_time_for_utc_and_station(timestamp=datetime.datetime(year=2020, month=1, day=1, hour=12, minute=0, second=0))
+        self.assertEqual(str(lst), '19h09m55.0856s')
+
+    def test_local_sidereal_time_for_utc_and_station_considers_timestamp(self):
+        # test that the results differ for different timestamps
+        lst1 = local_sidereal_time_for_utc_and_station(timestamp=datetime.datetime(year=2020, month=1, day=1, hour=12, minute=0, second=0))
+        lst2 = local_sidereal_time_for_utc_and_station(timestamp=datetime.datetime(year=2020, month=1, day=2, hour=12, minute=0, second=0))
+        self.assertNotEqual(str(lst1), str(lst2))
+
+    def test_local_sidereal_time_for_utc_and_station_considers_station(self):
+        # test that the results differ for different stations
+        lst1 = local_sidereal_time_for_utc_and_station(timestamp=datetime.datetime(year=2020, month=1, day=1, hour=12, minute=0, second=0), station="CS002")
+        lst2 = local_sidereal_time_for_utc_and_station(timestamp=datetime.datetime(year=2020, month=1, day=1, hour=12, minute=0, second=0), station="DE602")
+        self.assertNotEqual(str(lst1), str(lst2))
+
+
+class UtilREST(unittest.TestCase):
+
+    def test_util_utc_returns_timestamp(self):
+
+        # assert local clock differs not too much from returned TMSS system clock
+        r = requests.get(BASE_URL + '/util/utc', auth=AUTH)
+        self.assertEqual(r.status_code, 200)
+        returned_datetime = dateutil.parser.parse(r.content.decode('utf8'))
+        current_datetime = datetime.datetime.utcnow()
+        delta = abs((returned_datetime - current_datetime).total_seconds())
+        self.assertTrue(delta < 60.0)
+
+    def test_util_lst_returns_longitude(self):
+
+        # assert returned value is a parseable hms value
+        for query in ['/util/lst',
+                      '/util/lst?timestamp=2020-01-01T12:00:00',
+                      '/util/lst?timestamp=2020-01-01T12:00:00&longitude=54.321',
+                      '/util/lst?timestamp=2020-01-01T12:00:00&station=DE609']:
+            r = requests.get(BASE_URL + query, auth=AUTH)
+            self.assertEqual(r.status_code, 200)
+            lon_str = r.content.decode('utf8')
+            lon_obj = astropy.coordinates.Longitude(lon_str)
+            self.assertEqual(str(lon_obj), lon_str)
+
+    def test_util_lst_considers_timestamp(self):
+
+        # assert returned value matches known result for given timestamp
+        r = requests.get(BASE_URL + '/util/lst?timestamp=2020-01-01T12:00:00', auth=AUTH)
+        self.assertEqual(r.status_code, 200)
+        lon_str = r.content.decode('utf8')
+        self.assertEqual('19h09m55.0856s', lon_str)
+
+    def test_util_lst_considers_station(self):
+
+        # assert returned value differs when a different station is given
+        r1 = requests.get(BASE_URL + '/util/lst', auth=AUTH)
+        r2 = requests.get(BASE_URL + '/util/lst?station=DE602', auth=AUTH)
+        self.assertEqual(r1.status_code, 200)
+        self.assertEqual(r2.status_code, 200)
+        lon_str1 = r1.content.decode('utf8')
+        lon_str2 = r2.content.decode('utf8')
+        self.assertNotEqual(lon_str1, lon_str2)
+
+    def test_util_lst_considers_longitude(self):
+        # assert returned value differs when a different station is given
+        r1 = requests.get(BASE_URL + '/util/lst', auth=AUTH)
+        r2 = requests.get(BASE_URL + '/util/lst?longitude=12.345', auth=AUTH)
+        self.assertEqual(r1.status_code, 200)
+        self.assertEqual(r2.status_code, 200)
+        lon_str1 = r1.content.decode('utf8')
+        lon_str2 = r2.content.decode('utf8')
+        self.assertNotEqual(lon_str1, lon_str2)
+
+
+if __name__ == "__main__":
+    os.environ['TZ'] = 'UTC'
+    unittest.main()
diff --git a/SAS/TMSS/test/t_conversions.run b/SAS/TMSS/test/t_conversions.run
new file mode 100755
index 0000000000000000000000000000000000000000..d7c74389715a9cd50f3c36c5e406607f77c048f2
--- /dev/null
+++ b/SAS/TMSS/test/t_conversions.run
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+# Run the unit test
+source python-coverage.sh
+python_coverage_test "*tmss*" t_conversions.py
+
diff --git a/SAS/TMSS/test/t_conversions.sh b/SAS/TMSS/test/t_conversions.sh
new file mode 100755
index 0000000000000000000000000000000000000000..c95892264d5c49a9a76e274e0b99c308fe8ae29c
--- /dev/null
+++ b/SAS/TMSS/test/t_conversions.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+./runctest.sh t_conversions
\ No newline at end of file
diff --git a/SAS/TMSS/test/t_tmssapp_scheduling_django_API.py b/SAS/TMSS/test/t_tmssapp_scheduling_django_API.py
index 15af1542750e986d1db4c2fa4a8d65a2a57e9c77..ec2a1bb407b065247fa6a087618968ac0606bdfc 100755
--- a/SAS/TMSS/test/t_tmssapp_scheduling_django_API.py
+++ b/SAS/TMSS/test/t_tmssapp_scheduling_django_API.py
@@ -385,6 +385,15 @@ class FilesystemTest(unittest.TestCase):
         self.assertLess(before, entry.updated_at)
         self.assertGreater(after, entry.updated_at)
 
+    def test_Filesystem_raises_ValueError_on_invalid_directory_name(self):
+
+        # setup
+        test_data = Filesystem_test_data(directory="/no/trailing/slash")
+
+        # assert
+        with self.assertRaises(ValueError):
+            entry = models.Filesystem.objects.create(**test_data)
+
 
 class ClusterTest(unittest.TestCase):
     def test_Cluster_gets_created_with_correct_creation_timestamp(self):
diff --git a/SAS/TMSS/test/t_tmssapp_specification_django_API.py b/SAS/TMSS/test/t_tmssapp_specification_django_API.py
index c08efe5c46113ec9dc0b6589fb38b5b9d838d4ce..c052cd53e66463b4fbf0d3e6167d13d160228952 100755
--- a/SAS/TMSS/test/t_tmssapp_specification_django_API.py
+++ b/SAS/TMSS/test/t_tmssapp_specification_django_API.py
@@ -249,6 +249,19 @@ class ProjectTest(unittest.TestCase):
         self.assertLess(before, entry.updated_at)
         self.assertGreater(after, entry.updated_at)
 
+    def test_Project_raises_ValueError_on_invalid_archive_subdirectory_name(self):
+
+        # setup
+        test_data_1 = Project_test_data(archive_subdirectory="no/trailing/slash")
+        test_data_2 = Project_test_data(archive_subdirectory="/with/leading/slash/")
+
+        # assert
+        with self.assertRaises(ValueError):
+            entry = models.Project.objects.create(**test_data_1)
+
+        with self.assertRaises(ValueError):
+            entry = models.Project.objects.create(**test_data_2)
+
 
 class ProjectQuotaTest(unittest.TestCase):
     def test_ProjectQuota_prevents_missing_project(self):
diff --git a/SAS/TMSS/test/tmss_test_data_django_models.py b/SAS/TMSS/test/tmss_test_data_django_models.py
index 4152551be8162a2fed0babea66341ff4f962ad07..c9b2556759ac555b8591ee65fcd7a60050328757 100644
--- a/SAS/TMSS/test/tmss_test_data_django_models.py
+++ b/SAS/TMSS/test/tmss_test_data_django_models.py
@@ -120,7 +120,7 @@ def Cycle_test_data() -> dict:
             "start": datetime.utcnow().isoformat(),
             "stop": datetime.utcnow().isoformat()}
 
-def Project_test_data() -> dict:
+def Project_test_data(archive_subdirectory="my_project/") -> dict:
     return  { #"cycles": [models.Cycle.objects.create(**Cycle_test_data())], # ManyToMany, use set()
               "name": 'my_project_' + str(uuid.uuid4()),
                "description": 'my description ' + str(uuid.uuid4()),
@@ -130,7 +130,8 @@ def Project_test_data() -> dict:
                "can_trigger": False,
                "private_data": True,
                "expert": True,
-               "filler": False}
+               "filler": False,
+               "archive_subdirectory": archive_subdirectory}
 
 def ResourceType_test_data() -> dict:
     return  {
@@ -374,7 +375,7 @@ def Subtask_test_data(task_blueprint: models.TaskBlueprint=None, subtask_templat
         stop_time = datetime.utcnow() + timedelta(minutes=10)
 
     if cluster is None:
-        cluster = models.Cluster.objects.create(name="dummy cluster", location="downstairs", tags=[])
+        cluster = models.Cluster.objects.create(name="dummy cluster", location="downstairs", archive_site=True, tags=[])
 
     if state is None:
         state = models.SubtaskState.objects.get(value='defining')
@@ -395,6 +396,7 @@ def Dataproduct_test_data(producer: models.SubtaskOutput=None,
                           filename: str="my_file.ext",
                           directory: str="/data/test-projects",
                           dataformat: models.Dataformat=None,
+                          datatype: models.Datatype=None,
                           specifications_doc: object=None,
                           specifications_template: models.DataproductSpecificationsTemplate=None,
                           feedback_doc: object = None,
@@ -406,6 +408,9 @@ def Dataproduct_test_data(producer: models.SubtaskOutput=None,
     if dataformat is None:
         dataformat = models.Dataformat.objects.get(value="MeasurementSet")
 
+    if datatype is None:
+        datatype = models.Datatype.objects.get(value="visibilities")
+
     if specifications_template is None:
         specifications_template = models.DataproductSpecificationsTemplate.objects.create(**DataproductSpecificationsTemplate_test_data())
 
@@ -421,6 +426,7 @@ def Dataproduct_test_data(producer: models.SubtaskOutput=None,
     return {"filename": filename,
             "directory": directory,
             "dataformat": dataformat,
+            "datatype": datatype,
             "deleted_since": None,
             "pinned_since": None,
             "specifications_doc": specifications_doc,
@@ -448,14 +454,16 @@ def DataproductTransform_test_data() -> dict:
                         "identity": True,
                         "tags": ['tmss', 'testing']}
 
-def Filesystem_test_data() -> dict:
+def Filesystem_test_data(directory="/") -> dict:
     return {"capacity": 1111111111,
                         "cluster": models.Cluster.objects.create(**Cluster_test_data()),
+                        "directory": directory,
                         "tags": ['tmss', 'testing']}
 
 def Cluster_test_data(name="default cluster") -> dict:
     return {"name": name,
             "location": "upstairs",
+            "archive_site": True,
             "tags": ['tmss', 'testing']}
 
 def DataproductArchiveInfo_test_data() -> dict:
diff --git a/SAS/TMSS/test/tmss_test_data_rest.py b/SAS/TMSS/test/tmss_test_data_rest.py
index f2bdc431238591c304d5d6cf1b9f8444c8d6a99f..d3e091124418e7cd138bc46095df73b8eb499eec 100644
--- a/SAS/TMSS/test/tmss_test_data_rest.py
+++ b/SAS/TMSS/test/tmss_test_data_rest.py
@@ -199,7 +199,8 @@ class TMSSRESTTestDataCreator():
                 "trigger_priority": 1000,
                 "can_trigger": False,
                 "private_data": True,
-                "cycles": []}
+                "cycles": [],
+                "archive_subdirectory": 'my_project/'}
 
     def ResourceType(self, description="my resource_type description"):
         return {
@@ -484,6 +485,7 @@ class TMSSRESTTestDataCreator():
         return {"name": name if name else "Cluster %s" % uuid.uuid4(),
                 "description": 'My one cluster',
                 "location": "upstairs",
+                "archive_site": False,
                 "tags": ['tmss', 'testing']}
     
     def Subtask(self, cluster_url=None, task_blueprint_url=None, specifications_template_url=None, specifications_doc=None, state:str="defining", start_time: datetime=None, stop_time: datetime=None):
@@ -535,7 +537,7 @@ class TMSSRESTTestDataCreator():
                     specifications_doc=None, specifications_template_url=None,
                     subtask_output_url=None,
                     dataproduct_feedback_doc=None, dataproduct_feedback_template_url=None,
-                    dataformat="MeasurementSet"):
+                    dataformat="MeasurementSet", datatype="visibilities"):
         if specifications_template_url is None:
             specifications_template_url = self.post_data_and_get_url(self.SubtaskTemplate(), '/dataproduct_specifications_template/')
     
@@ -554,6 +556,7 @@ class TMSSRESTTestDataCreator():
         return {"filename": filename,
                 "directory": directory,
                 "dataformat": "%s/dataformat/%s" % (self.django_api_url, dataformat),
+                "datatype": "%s/datatype/%s" % (self.django_api_url, datatype),
                 "deleted_since": None,
                 "pinned_since": None,
                 "specifications_doc": specifications_doc,
@@ -646,5 +649,6 @@ class TMSSRESTTestDataCreator():
                 "description": 'My one filesystem',
                 "capacity": 1111111111,
                 "cluster": cluster_url,
+                "directory": '/',
                 "tags": ['tmss', 'testing']}