diff --git a/SAS/TMSS/frontend/tmss_webapp/src/authenticate/login.js b/SAS/TMSS/frontend/tmss_webapp/src/authenticate/login.js
index fd5b4b041eccc5f155117b6e072092358b35657e..dc664ca93ed31e31f1a3240ecad5698848b5ce62 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/authenticate/login.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/authenticate/login.js
@@ -20,6 +20,7 @@ export class Login extends Component {
         };
         this.login = this.login.bind(this);
         this.setCredentials = this.setCredentials.bind(this);
+        this.formSubmit = this.formSubmit.bind(this);
     }
 
     /**
@@ -45,6 +46,16 @@ export class Login extends Component {
         this.setState(state);
     }
 
+    /**
+     * Function to call login function on Enter key press.
+     * @param {React.KeyboardEvent} event 
+     */
+    formSubmit(event) {
+        if (event.key === "Enter" && this.state.username && this.state.password) {
+            this.login();
+        }
+    }
+
     /**
      * Login function called on click of 'Login' button. 
      * If authenticated, callback parent component function.
@@ -88,7 +99,8 @@ export class Login extends Component {
                                                 <div className="form-field">
                                                     <span className="p-float-label">
                                                         <InputText id="" className={`${this.state.errors.username?"input-error ":""} form-control`} 
-                                                                    value={this.state.username} onChange={(e) => this.setCredentials('username', e.target.value)} />
+                                                                    value={this.state.username} onChange={(e) => this.setCredentials('username', e.target.value)}
+                                                                    onKeyUp={this.formSubmit} />
                                                         <label htmlFor="username"><i className="fa fa-user"></i>Enter Username</label>
                                                     </span>
                                                     <label className={this.state.errors.username?"error":""}>
@@ -98,7 +110,8 @@ export class Login extends Component {
                                                 <div className="form-field">
                                                     <span className="p-float-label">
                                                         <InputText id="password" className={`${this.state.errors.password?"input-error ":""} form-control`} 
-                                                                type="password" value={this.state.password} onChange={(e) => this.setCredentials('password', e.target.value )} />
+                                                                type="password" value={this.state.password} onChange={(e) => this.setCredentials('password', e.target.value )} 
+                                                                onKeyUp={this.formSubmit} />
                                                         <label htmlFor="password"><i className="fa fa-key"></i>Enter Password</label>
                                                     </span>
                                                     <label className={this.state.errors.password?"error":""}>
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/layout/components/PageHeader.js b/SAS/TMSS/frontend/tmss_webapp/src/layout/components/PageHeader.js
index bc835979e1806deb5d4df907004effcde76e032a..06521dd203b56cbe59f48143d249bf0fcca8581b 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/layout/components/PageHeader.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/layout/components/PageHeader.js
@@ -3,7 +3,6 @@ import { routes } from '../../routes';
 import {matchPath, Link} from 'react-router-dom';
 
 export default ({ title, subTitle, actions, ...props}) => {
-    debugger;
     const [page, setPage] = useState({});
 
     useEffect(() => {
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 ca9d501d3d3fda31040dc2a22d8341cf41ef9917..c8740a6360c5acfd00d664ef044a02afb7c503a7 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js
@@ -17,7 +17,10 @@ import UtilService from '../../services/util.service';
 
 class SchedulingUnitList extends Component{
     lsKeySortColumn = "SchedulingUnitListSortData";
-    defaultSortColumn= [{id: "Name", desc: false}];    
+    defaultSortColumn= [{id: "Name", desc: false}]; 
+    SU_NOT_STARTED_STATUSES = ['defined', 'schedulable', 'scheduled'];
+    SU_ACTIVE_STATUSES = ['started', 'observing', 'observed', 'processing', 'processed', 'ingesting'];
+    SU_END_STATUSES = ['finished', 'error', 'cancelled'];
     constructor(props){
        super(props);
        this. setToggleBySorting();
@@ -155,6 +158,10 @@ class SchedulingUnitList extends Component{
         this.onRowSelection = this.onRowSelection.bind(this);
         this.reloadData = this.reloadData.bind(this);
         this.addTargetColumns = this.addTargetColumns.bind(this);
+        this.confirmCancelSchedulingUnit = this.confirmCancelSchedulingUnit.bind(this);
+        this.cancelSchedulingUnit = this.cancelSchedulingUnit.bind(this);
+        this.getSUCancelConfirmContent = this.getSUCancelConfirmContent.bind(this);
+        this.getSUCancelStatusContent = this.getSUCancelStatusContent.bind(this);
     }
 
     /**
@@ -587,6 +594,125 @@ class SchedulingUnitList extends Component{
         this.componentDidMount();
     }
 
+    /**
+     * Prepare Scheduling Unit(s) details to show on confirmation dialog before cancelling
+     */
+     getSUCancelConfirmContent() {
+        let selectedSUs = [], ignoredSUs = [];
+        for (const obj of this.selectedRows) {
+            if (obj.type  === "Blueprint" && this.SU_END_STATUSES.indexOf(obj.status) < 0) {
+                selectedSUs.push({
+                    suId: obj.id, suName: obj.name,
+                    suType: obj.type, status: obj.status
+                });
+            }   else {
+                ignoredSUs.push({
+                    suId: obj.id, suName: obj.name,
+                    suType: obj.type, status: obj.status
+                });
+            }
+        }
+        return <>
+            <div style={{marginTop: '1em'}}>
+                <b>Scheduling Unit(s) that can be cancelled</b>
+                <DataTable value={selectedSUs} resizableColumns columnResizeMode="expand" className="card" style={{ paddingLeft: '0em' }}>
+                    <Column field="suId" header="Scheduling Unit Id"></Column>
+                    <Column field="suName" header="Scheduling Unit Name"></Column>
+                    <Column field="suType" header="Type"></Column>
+                    <Column field="status" header="Status"></Column>
+                </DataTable>
+            </div>
+            {ignoredSUs.length > 0 &&
+            <div style={{marginTop: '1em'}}>
+                <b>Scheduling Unit(s) that will be ignored</b>
+                <DataTable value={ignoredSUs} resizableColumns columnResizeMode="expand" className="card" style={{ paddingLeft: '0em' }}>
+                    <Column field="suId" header="Scheduling Unit Id"></Column>
+                    <Column field="suName" header="Scheduling Unit Name"></Column>
+                    <Column field="suType" header="Type"></Column>
+                    <Column field="status" header="Status"></Column>
+                </DataTable>
+            </div>
+            }
+        </>
+    }
+
+    /**
+     * Prepare Scheduling Unit(s) details to show status of cancellationn
+     */
+    getSUCancelStatusContent() {
+        let cancelledSchedulingUnits = this.state.cancelledSchedulingUnits;
+        return <>
+            <DataTable value={cancelledSchedulingUnits} resizableColumns columnResizeMode="expand" className="card" style={{ paddingLeft: '0em' }}>
+                <Column field="suId" header="Scheduling Unit Id"></Column>
+                <Column field="suName" header="Scheduling Unit Name"></Column>
+                <Column field="type" header="Type"></Column>
+                <Column field="status" header="Status"></Column>
+            </DataTable>
+        </>
+    }
+
+    /**
+     * Function to get confirmation before cancelling all selected scheduling unit blueprints if the status is 
+     * not one of the end statuses. 
+     * If no selected scheduling unit is cancellable, show info to select a cancellable scheduling unit.
+     * 
+     */
+    confirmCancelSchedulingUnit() {
+        let selectedBlueprints = this.selectedRows.filter(schedulingUnit => {
+                                        return schedulingUnit.type === 'Blueprint' && 
+                                        this.SU_END_STATUSES.indexOf(schedulingUnit.status)<0});
+        if (selectedBlueprints.length === 0) {
+            appGrowl.show({ severity: 'info', summary: 'Select Row', 
+                            detail: 'Select atleast one cancellable Scheduling Unit Blueprint to cancel.' });
+        } else {
+            let dialog = this.state.dialog;
+            dialog.type = "confirmation";
+            dialog.header = "Confirm to Cancel Scheduling Unit(s)";
+            dialog.actions = [{ id: 'yes', title: 'Yes', callback: this.cancelSchedulingUnit, className:(this.props.project)?"dialog-btn": "" },
+                                { id: 'no', title: 'No', callback: this.closeDialog, className:(this.props.project)?"dialog-btn": "" }];
+            dialog.detail = "Cancelling the scheduling unit means it will no longer be executed / will be aborted. This action cannot be undone. Already finished/cancelled scheduling unit(s) will be ignored. Do you want to proceed?";
+            dialog.content = this.getSUCancelConfirmContent;
+            dialog.submit = this.cancelSchedulingUnit;
+            dialog.width = '55vw';
+            dialog.showIcon = false;
+            this.setState({ dialog: dialog, dialogVisible: true });
+        }
+    }
+    
+    /**
+     * Function to cancel all selected Scheduling Unit blueprints if its status is not one of the end statuses
+     * and update their status on successful cancellation.
+     */
+    async cancelSchedulingUnit() {
+        let schedulingUnits = this.state.scheduleunit;
+        let selectedBlueprints = this.selectedRows.filter(su => {return su.type === 'Blueprint'});
+        let cancelledSchedulingUnits = []
+        for (const selectedSU of selectedBlueprints) {
+            if (this.SU_END_STATUSES.indexOf(selectedSU.status) < 0) {
+                const cancelledSU = await ScheduleService.cancelSchedulingUnit(selectedSU.id);
+                let schedulingUnit = _.find(schedulingUnits, {'id': selectedSU.id, type: 'Blueprint'});
+                if (cancelledSU) {
+                    schedulingUnit.status = cancelledSU.status;
+                }
+                cancelledSchedulingUnits.push({
+                    suId: schedulingUnit.id, suName: schedulingUnit.name, type: schedulingUnit.type,
+                    status: schedulingUnit.status.toLowerCase()==='cancelled'?'Cancelled': 'Error Occured'
+                });
+            }
+        }
+        let dialog = this.state.dialog;
+        dialog.type = "confirmation";
+        dialog.header = "Cancel Scheduling Unit(s) Status";
+        dialog.actions = [{ id: 'no', title: 'Ok', callback: this.closeDialog, className:(this.props.project)?"dialog-btn": "" }];
+        dialog.detail = ""
+        dialog.content = this.getSUCancelStatusContent;
+        dialog.submit = this.closeDialog;
+        dialog.width = '55vw';
+        dialog.showIcon = false;
+        this.selectedRows = [];
+        this.setState({ scheduleunit: schedulingUnits, cancelledSchedulingUnits: cancelledSchedulingUnits, dialog: dialog, dialogVisible: true });
+    }
+    
     /**
      * Callback function to close the dialog prompted.
      */
@@ -616,9 +742,14 @@ class SchedulingUnitList extends Component{
                     <div >
                         <span className="p-float-label">
                             {this.state.scheduleunit && this.state.scheduleunit.length > 0 &&
+                            <>
+                                <a href="#" onClick={this.confirmCancelSchedulingUnit}  title="Cancel selected Scheduling Unit(s)">
+                                    <i class="fa fa-ban" aria-hidden="true" ></i>
+                                </a>
                                 <a href="#" onClick={this.checkAndDeleteSchedulingUnit}  title="Delete selected Scheduling Unit(s)">
                                     <i class="fa fa-trash" aria-hidden="true" ></i>
                                 </a>
+                            </>
                             }
                         </span>
                     </div>                           
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 5bd338d371491e9d414c05a521374235f113afc5..d476f34454dd12c2749043281a47aad07806f378 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js
@@ -30,12 +30,16 @@ class ViewSchedulingUnit extends Component {
     lsKeySortColumn = 'SortDataViewSchedulingUnit';
     defaultSortColumn = [];
     ignoreSorting = ['status logs'];
+    SU_NOT_STARTED_STATUSES = ['defined', 'schedulable', 'scheduled'];
+    SU_ACTIVE_STATUSES = ['started', 'observing', 'observed', 'processing', 'processed', 'ingesting'];
+    SU_END_STATUSES = ['finished', 'error', 'cancelled'];
+    TASK_END_STATUSES = ['finished', 'error', 'cancelled'];
     constructor(props) {
         super(props);
         this.setToggleBySorting();
         this.state = {
             scheduleunit: null,
-            schedule_unit_task: [],
+            schedulingUnitTasks: [],
             isLoading: true,
             showStatusLogs: false,
             showTaskRelationDialog: false,
@@ -152,16 +156,22 @@ class ViewSchedulingUnit extends Component {
         this.selectedRows = [];
 
         this.confirmDeleteTasks = this.confirmDeleteTasks.bind(this);
+        this.confirmCancelTasks = this.confirmCancelTasks.bind(this);
         this.onRowSelection = this.onRowSelection.bind(this);
         this.deleteTasks = this.deleteTasks.bind(this);
         this.deleteSchedulingUnit = this.deleteSchedulingUnit.bind(this);
-        this.getTaskDialogContent = this.getTaskDialogContent.bind(this);
+        this.getTaskDeleteDialogContent = this.getTaskDeleteDialogContent.bind(this);
+        this.getTaskCancelConfirmContent = this.getTaskCancelConfirmContent.bind(this);
+        this.getTaskCancelStatusContent = this.getTaskCancelStatusContent.bind(this);
         this.getSUDialogContent = this.getSUDialogContent.bind(this);
         this.checkAndCreateBlueprint = this.checkAndCreateBlueprint.bind(this);
         this.createBlueprintTree = this.createBlueprintTree.bind(this);
         this.closeDialog = this.closeDialog.bind(this);
         this.showTaskRelationDialog = this.showTaskRelationDialog.bind(this);
         this.showDeleteSUConfirmation = this.showDeleteSUConfirmation.bind(this);
+        this.showCancelSUConfirmation = this.showCancelSUConfirmation.bind(this);
+        this.cancelSchedulingUnit = this.cancelSchedulingUnit.bind(this);
+        this.cancelTasks = this.cancelTasks.bind(this);
     }
 
     componentDidUpdate(prevProps, prevState) {
@@ -263,7 +273,7 @@ class ViewSchedulingUnit extends Component {
                         scheduleunitId: schedule_id,
                         scheduleunit: schedulingUnit,
                         scheduleunitType: schedule_type,
-                        schedule_unit_task: tasks,
+                        schedulingUnitTasks: tasks,
                         isLoading: false,
                         stationGroup: targetObservation ? targetObservation.specifications_doc.station_groups : [],
                         redirect: null,
@@ -308,6 +318,12 @@ class ViewSchedulingUnit extends Component {
                 actOn: 'click', props: { callback: this.checkAndCreateBlueprint },
             });
         } else {
+            this.actions.unshift({
+                icon: 'fa-ban', type: 'button', actOn: 'click', 
+                title: this.SU_END_STATUSES.indexOf(this.state.scheduleunit.status.toLowerCase())>=0?'Cannot Cancel Scheduling Unit':'Cancel Scheduling Unit', 
+                disabled:this.SU_END_STATUSES.indexOf(this.state.scheduleunit.status.toLowerCase())>=0, 
+                props: { callback: this.showCancelSUConfirmation }
+            });
             this.actions.unshift({ icon: 'fa-sitemap', title: 'View Workflow', props: { pathname: `/schedulingunit/${this.props.match.params.id}/workflow` } });
             this.actions.unshift({ icon: 'fa-lock', title: 'Cannot edit blueprint' });
         }
@@ -458,7 +474,7 @@ class ViewSchedulingUnit extends Component {
      * Callback function to close the dialog prompted.
      */
     closeDialog() {
-        this.setState({ dialogVisible: false });
+        this.setState({ dialogVisible: false, cancelledTasks: [] });
     }
 
     onRowSelection(selectedRows) {
@@ -476,7 +492,7 @@ class ViewSchedulingUnit extends Component {
             dialog.type = "confirmation";
             dialog.header = "Confirm to Delete Task(s)";
             dialog.detail = "Do you want to delete the selected Task(s)?";
-            dialog.content = this.getTaskDialogContent;
+            dialog.content = this.getTaskDeleteDialogContent;
             dialog.actions = [{ id: 'yes', title: 'Yes', callback: this.deleteTasks },
             { id: 'no', title: 'No', callback: this.closeDialog }];
             dialog.onSubmit = this.deleteTasks;
@@ -501,9 +517,9 @@ class ViewSchedulingUnit extends Component {
     }
 
     /**
-     * Prepare Task(s) details to show on confirmation dialog
+     * Prepare Task(s) details to show on confirmation dialog before deleting
      */
-    getTaskDialogContent() {
+    getTaskDeleteDialogContent() {
         let selectedTasks = [];
         for (const obj of this.selectedRows) {
             selectedTasks.push({
@@ -576,6 +592,158 @@ class ViewSchedulingUnit extends Component {
         }
     }
 
+    /**
+     * Show confirmation dialog before cancelling the scheduling unit.
+     */
+    showCancelSUConfirmation() {
+        let dialog = this.state.dialog;
+        dialog.type = "confirmation";
+        dialog.header = "Confirm to Cancel Scheduling Unit";
+        dialog.actions = [{ id: 'yes', title: 'Yes', callback: this.cancelSchedulingUnit },
+                            { id: 'no', title: 'No', callback: this.closeDialog }];
+        if (this.SU_NOT_STARTED_STATUSES.indexOf(this.state.scheduleunit.status) >= 0) {
+            dialog.detail = "Cancelling this scheduling unit means it will no longer be executed. This action cannot be undone. Do you want to proceed?";
+        }   else if (this.SU_ACTIVE_STATUSES.indexOf(this.state.scheduleunit.status) >= 0) {
+            dialog.detail = "Cancelling this scheduling unit means it will be aborted. This action cannot be undone. Do you want to proceed?";
+        }
+        dialog.submit = this.cancelSchedulingUnit;
+        dialog.width = '40vw';
+        dialog.showIcon = true;
+        this.setState({ dialog: dialog, dialogVisible: true });
+    }
+
+    /**
+     * Function to cancel the scheduling unit and update its status and status of tasks if succeeeded.
+     */
+    async cancelSchedulingUnit() {
+        let schedulingUnit = this.state.scheduleunit;
+        let cancelledSU = await ScheduleService.cancelSchedulingUnit(schedulingUnit.id);
+        if (!cancelledSU) {
+            appGrowl.show({ severity: 'error', summary: 'error', detail: 'Error while cancelling Scheduling Unit' });
+            this.setState({ dialogVisible: false });
+        } else {
+            schedulingUnit.status = cancelledSU.status;
+            let actions = this.state.actions;
+            let cancelAction = _.find(actions, ['icon', 'fa-ban']);
+            cancelAction.disabled = true;
+            const cancelActionIndex = _.findIndex(actions, {'icon': 'fa-ban'});
+            actions.splice(cancelActionIndex, 1, cancelAction);
+            const cancelledSUTasks = cancelledSU.task_blueprints;
+            let suTasks = this.state.schedulingUnitTasks;
+            for (let suTask of suTasks) {
+                const cancelledSUTask = _.find(cancelledSUTasks, {'id': suTask.id});
+                suTask.status = cancelledSUTask.status;
+            }
+            appGrowl.show({ severity: 'success', summary: 'Success', detail: 'Scheduling Unit is cancelled successfully' });
+            this.setState({ dialogVisible: false, scheduleunit: schedulingUnit,
+                            schedulingUnitTasks:suTasks, actions: actions});
+        }
+    }
+
+    /**
+     * Prepare Task(s) details to show on confirmation dialog before cancelling
+     */
+    getTaskCancelConfirmContent() {
+        let selectedTasks = [];
+        for (const obj of this.selectedRows) {
+            if (this.TASK_END_STATUSES.indexOf(obj.status) < 0) {
+                selectedTasks.push({
+                    id: obj.id, suId: this.state.scheduleunit.id, suName: this.state.scheduleunit.name,
+                    taskId: obj.id, controlId: obj.subTaskID, taskName: obj.name, status: obj.status
+                });
+            }
+        }
+        return <>
+            <DataTable value={selectedTasks} resizableColumns columnResizeMode="expand" className="card" style={{ paddingLeft: '0em' }}>
+                <Column field="suId" header="Scheduling Unit Id"></Column>
+                <Column field="suName" header="Scheduling Unit Name"></Column>
+                <Column field="taskId" header="Task Id"></Column>
+                <Column field="controlId" header="Control Id"></Column>
+                <Column field="taskName" header="Task Name"></Column>
+                <Column field="status" header="Status"></Column>
+            </DataTable>
+        </>
+    }
+
+    /**
+     * Prepare Task(s) details to show status of Task cancellationn
+     */
+    getTaskCancelStatusContent() {
+        let cancelledTasks = this.state.cancelledTasks;
+        return <>
+            <DataTable value={cancelledTasks} resizableColumns columnResizeMode="expand" className="card" style={{ paddingLeft: '0em' }}>
+                <Column field="suId" header="Scheduling Unit Id"></Column>
+                <Column field="suName" header="Scheduling Unit Name"></Column>
+                <Column field="taskId" header="Task Id"></Column>
+                <Column field="controlId" header="Control Id"></Column>
+                <Column field="taskName" header="Task Name"></Column>
+                <Column field="status" header="Status"></Column>
+            </DataTable>
+        </>
+    }
+
+    /**
+     * Function to get confirmation before cancelling all selected task blueprints if the task status is 
+     * not one of the end statuses. If no selected task is cancellable, show info to select a cancellable task.
+     * 
+     */
+    confirmCancelTasks() {
+        let selectedBlueprints = this.selectedRows.filter(task => {
+                                        return task.tasktype === 'Blueprint' && 
+                                        this.TASK_END_STATUSES.indexOf(task.status)<0});
+        if (selectedBlueprints.length === 0) {
+            appGrowl.show({ severity: 'info', summary: 'Select Row', 
+                            detail: 'Select atleast one cancellable Task Blueprint to cancel.' });
+        } else {
+            let dialog = this.state.dialog;
+            dialog.type = "confirmation";
+            dialog.header = "Confirm to Cancel Task(s)";
+            dialog.actions = [{ id: 'yes', title: 'Yes', callback: this.cancelTasks },
+                                { id: 'no', title: 'No', callback: this.closeDialog }];
+            dialog.detail = "Cancelling the task means it will no longer be executed / will be aborted. This action cannot be undone. Do you want to proceed?";
+            dialog.content = this.getTaskCancelConfirmContent;
+            dialog.submit = this.cancelTasks;
+            dialog.width = '55vw';
+            dialog.showIcon = false;
+            this.setState({ dialog: dialog, dialogVisible: true });
+        }
+    }
+    
+    /**
+     * Function to cancel all selected task blueprints if the task status is not one of the end statuses
+     * and update their status on successful cancellation.
+     */
+    async cancelTasks() {
+        let schedulingUnitTasks = this.state.schedulingUnitTasks;
+        let selectedBlueprints = this.selectedRows.filter(task => {return task.tasktype === 'Blueprint'});
+        let cancelledTasks = []
+        for (const selectedTask of selectedBlueprints) {
+            if (this.TASK_END_STATUSES.indexOf(selectedTask.status) < 0) {
+                const cancelledTask = await TaskService.cancelTask(selectedTask.id);
+                let task = _.find(schedulingUnitTasks, {'id': selectedTask.id, tasktype: 'Blueprint'});
+                if (cancelledTask) {
+                    task.status = cancelledTask.status;
+                }
+                cancelledTasks.push({
+                    id: task.id, suId: this.state.scheduleunit.id, suName: this.state.scheduleunit.name,
+                    taskId: task.id, controlId: task.subTaskID, taskName: task.name, 
+                    status: task.status.toLowerCase()==='cancelled'?'Cancelled': 'Error Occured'
+                });
+            }
+        }
+        let dialog = this.state.dialog;
+        dialog.type = "confirmation";
+        dialog.header = "Cancel Task(s) Status";
+        dialog.actions = [{ id: 'no', title: 'Ok', callback: this.closeDialog }];
+        dialog.detail = ""
+        dialog.content = this.getTaskCancelStatusContent;
+        dialog.submit = this.closeDialog;
+        dialog.width = '55vw';
+        dialog.showIcon = false;
+        this.selectedRows = [];
+        this.setState({ schedulingUnitTasks: schedulingUnitTasks, cancelledTasks: cancelledTasks, dialog: dialog, dialogVisible: true });
+    }
+
     render() {
         if (this.state.redirect) {
             return <Redirect to={{ pathname: this.state.redirect }}></Redirect>
@@ -670,17 +838,22 @@ class ViewSchedulingUnit extends Component {
                 <div className="delete-option">
                     <div >
                         <span className="p-float-label">
-                            {this.state.schedule_unit_task && this.state.schedule_unit_task.length > 0 &&
-                                <a href="#" onClick={this.confirmDeleteTasks} title="Delete selected Task(s)">
-                                    <i class="fa fa-trash" aria-hidden="true" ></i>
-                                </a>
+                            {this.state.schedulingUnitTasks && this.state.schedulingUnitTasks.length > 0 &&
+                                <>
+                                    <a href="#" onClick={this.confirmCancelTasks} title="Cancel selected Task(s)">
+                                        <i class="fa fa-ban" aria-hidden="true" ></i>
+                                    </a>
+                                    <a href="#" onClick={this.confirmDeleteTasks} title="Delete selected Task(s)">
+                                        <i class="fa fa-trash" aria-hidden="true" ></i>
+                                    </a>
+                                </>
                             }
                         </span>
                     </div>
                 </div>
-                {this.state.isLoading ? <AppLoader /> : (this.state.schedule_unit_task.length > 0) ?
+                {this.state.isLoading ? <AppLoader /> : (this.state.schedulingUnitTasks.length > 0) ?
                     <ViewTable
-                        data={this.state.schedule_unit_task}
+                        data={this.state.schedulingUnitTasks}
                         defaultcolumns={this.state.defaultcolumns}
                         optionalcolumns={this.state.optionalcolumns}
                         columnclassname={this.state.columnclassname}
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/list.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/list.js
index 4e217041ca0662dc7a9522dbcd78e08808ac481e..3b7d0f0060f6eb6a7e89f54253bdc8a2efdc82bb 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/list.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/list.js
@@ -21,6 +21,7 @@ export class TaskList extends Component {
     lsKeySortColumn = "TaskListSortData";
     // The following values should be lower case
     ignoreSorting = ['status logs'];
+    TASK_END_STATUSES = ['finished', 'error', 'cancelled'];
     constructor(props) {
         super(props);
         this.state = {
@@ -129,15 +130,20 @@ export class TaskList extends Component {
                 "Data size on Disk": "filter-input-50",
                 "Subtask Content": "filter-input-75",
                 "BluePrint / Task Draft link": "filter-input-50",
-            }]
+            }],
+            actions: []
         };
         this.selectedRows = [];
         this.subtaskTemplates = [];
         this.confirmDeleteTasks = this.confirmDeleteTasks.bind(this);
+        this.confirmCancelTasks = this.confirmCancelTasks.bind(this);
         this.onRowSelection = this.onRowSelection.bind(this);
         this.deleteTasks = this.deleteTasks.bind(this);
+        this.cancelTasks = this.cancelTasks.bind(this);
         this.closeDialog = this.closeDialog.bind(this);
-        this.getTaskDialogContent = this.getTaskDialogContent.bind(this);
+        this.getTaskDeleteDialogContent = this.getTaskDeleteDialogContent.bind(this);
+        this.getTaskCancelConfirmContent = this.getTaskCancelConfirmContent.bind(this);
+        this.getTaskCancelStatusContent = this.getTaskCancelStatusContent.bind(this);
     }
 
     subtaskComponent = (task) => {
@@ -260,7 +266,12 @@ export class TaskList extends Component {
                 tasks = await this.formatDataProduct(tasks);
                 allTasks = [...allTasks, ...tasks];
             }
-            this.setState({ tasks: allTasks, isLoading: false });
+            const actions = [{icon: 'fa fa-ban', title: 'Cancel Task(s)',
+                                type: 'button', actOn: 'click', props: { callback: this.confirmCancelTasks }},
+                             {icon: 'fa fa-trash', title: 'Delete Task(s)',
+                                type: 'button', actOn: 'click', props: { callback: this.confirmDeleteTasks }}
+                            ];
+            this.setState({ tasks: allTasks, isLoading: false, actions: actions });
         });
     }
 
@@ -282,9 +293,9 @@ export class TaskList extends Component {
     }
 
     /**
-     * Prepare Task(s) details to show on confirmation dialog
+     * Prepare Task(s) details to show on confirmation dialog before deleting
      */
-    getTaskDialogContent() {
+    getTaskDeleteDialogContent() {
         let selectedTasks = [];
         for (const obj of this.selectedRows) {
             selectedTasks.push({
@@ -310,7 +321,7 @@ export class TaskList extends Component {
             dialog.type = "confirmation";
             dialog.header = "Confirm to Delete Task(s)";
             dialog.detail = "Do you want to delete the selected Task(s)?";
-            dialog.content = this.getTaskDialogContent;
+            dialog.content = this.getTaskDeleteDialogContent;
             dialog.actions = [{ id: 'yes', title: 'Yes', callback: this.deleteTasks },
             { id: 'no', title: 'No', callback: this.closeDialog }];
             dialog.onSubmit = this.deleteTasks;
@@ -341,11 +352,136 @@ export class TaskList extends Component {
         }
     }
 
+    /**
+     * Prepare Task(s) details to show on confirmation dialog before cancelling
+     */
+    getTaskCancelConfirmContent() {
+        let selectedTasks = [], ignoredTasks = [];
+        for (const obj of this.selectedRows) {
+            if (this.TASK_END_STATUSES.indexOf(obj.status) < 0) {
+                selectedTasks.push({
+                    id: obj.id, suId: obj.schedulingUnitId, suName: obj.schedulingUnitName,
+                    taskId: obj.id, controlId: obj.subTaskID, taskName: obj.name, status: obj.status
+                });
+            }   else {
+                ignoredTasks.push({
+                    id: obj.id, suId: obj.schedulingUnitId, suName: obj.schedulingUnitName,
+                    taskId: obj.id, controlId: obj.subTaskID, taskName: obj.name, status: obj.status
+                });
+            }
+        }
+        return <>
+            <div style={{marginTop: '1em'}}>
+                <b>Task(s) that can be cancelled</b>
+                <DataTable value={selectedTasks} resizableColumns columnResizeMode="expand" className="card" style={{ paddingLeft: '0em' }}>
+                    <Column field="suId" header="Scheduling Unit Id"></Column>
+                    <Column field="suName" header="Scheduling Unit Name"></Column>
+                    <Column field="taskId" header="Task Id"></Column>
+                    <Column field="controlId" header="Control Id"></Column>
+                    <Column field="taskName" header="Task Name"></Column>
+                    <Column field="status" header="Status"></Column>
+                </DataTable>
+            </div>
+            {ignoredTasks.length > 0 &&
+            <div style={{marginTop: '1em'}}>
+                <b>Task(s) that will be ignored</b>
+                <DataTable value={ignoredTasks} resizableColumns columnResizeMode="expand" className="card" style={{ paddingLeft: '0em' }}>
+                    <Column field="suId" header="Scheduling Unit Id"></Column>
+                    <Column field="suName" header="Scheduling Unit Name"></Column>
+                    <Column field="taskId" header="Task Id"></Column>
+                    <Column field="controlId" header="Control Id"></Column>
+                    <Column field="taskName" header="Task Name"></Column>
+                    <Column field="status" header="Status"></Column>
+                </DataTable>
+            </div>
+            }
+        </>
+    }
+
+    /**
+     * Prepare Task(s) details to show status of Task cancellationn
+     */
+    getTaskCancelStatusContent() {
+        let cancelledTasks = this.state.cancelledTasks;
+        return <>
+            <DataTable value={cancelledTasks} resizableColumns columnResizeMode="expand" className="card" style={{ paddingLeft: '0em' }}>
+                <Column field="suId" header="Scheduling Unit Id"></Column>
+                <Column field="suName" header="Scheduling Unit Name"></Column>
+                <Column field="taskId" header="Task Id"></Column>
+                <Column field="controlId" header="Control Id"></Column>
+                <Column field="taskName" header="Task Name"></Column>
+                <Column field="status" header="Status"></Column>
+            </DataTable>
+        </>
+    }
+
+    /**
+     * Function to get confirmation before cancelling all selected task blueprints if the task status is 
+     * not one of the end statuses. If no selected task is cancellable, show info to select a cancellable task.
+     * 
+     */
+    confirmCancelTasks() {
+        let selectedBlueprints = this.selectedRows.filter(task => {
+                                        return task.tasktype === 'Blueprint' && 
+                                        this.TASK_END_STATUSES.indexOf(task.status)<0});
+        if (selectedBlueprints.length === 0) {
+            appGrowl.show({ severity: 'info', summary: 'Select Row', 
+                            detail: 'Select atleast one cancellable Task Blueprint to cancel.' });
+        } else {
+            let dialog = this.state.dialog;
+            dialog.type = "confirmation";
+            dialog.header = "Confirm to Cancel Task(s)";
+            dialog.actions = [{ id: 'yes', title: 'Yes', callback: this.cancelTasks },
+                                { id: 'no', title: 'No', callback: this.closeDialog }];
+            dialog.detail = "Cancelling the task means, it will no longer be executed / will be aborted. This action cannot be undone. Already finished/cancelled task(s) will be ignored. Do you want to proceed?";
+            dialog.content = this.getTaskCancelConfirmContent;
+            dialog.submit = this.cancelTasks;
+            dialog.width = '55vw';
+            dialog.showIcon = false;
+            this.setState({ dialog: dialog, dialogVisible: true });
+        }
+    }
+    
+    /**
+     * Function to cancel all selected task blueprints if the task status is not one of the end statuses
+     * and update their status on successful cancellation.
+     */
+    async cancelTasks() {
+        let tasks = this.state.tasks;
+        let selectedBlueprints = this.selectedRows.filter(task => {return task.tasktype === 'Blueprint'});
+        let cancelledTasks = []
+        for (const selectedTask of selectedBlueprints) {
+            if (this.TASK_END_STATUSES.indexOf(selectedTask.status) < 0) {
+                const cancelledTask = await TaskService.cancelTask(selectedTask.id);
+                let task = _.find(tasks, {'id': selectedTask.id, tasktype: 'Blueprint'});
+                if (cancelledTask) {
+                    task.status = cancelledTask.status;
+                }
+                cancelledTasks.push({
+                    id: task.id, suId: task.schedulingUnitId, suName: task.schedulingUnitName,
+                    taskId: task.id, controlId: task.subTaskID, taskName: task.name, 
+                    status: task.status.toLowerCase()==='cancelled'?'Cancelled': 'Error Occured'
+                });
+            }
+        }
+        let dialog = this.state.dialog;
+        dialog.type = "confirmation";
+        dialog.header = "Cancel Task(s) Status";
+        dialog.actions = [{ id: 'no', title: 'Ok', callback: this.closeDialog }];
+        dialog.detail = ""
+        dialog.content = this.getTaskCancelStatusContent;
+        dialog.submit = this.closeDialog;
+        dialog.width = '55vw';
+        dialog.showIcon = false;
+        this.selectedRows = [];
+        this.setState({ tasks: tasks, cancelledTasks: cancelledTasks, dialog: dialog, dialogVisible: true });
+    }
+
     /**
      * Callback function to close the dialog prompted.
      */
     closeDialog() {
-        this.setState({ dialogVisible: false });
+        this.setState({ dialogVisible: false, cancelledTasks: [] });
     }
 
     onRowSelection(selectedRows) {
@@ -360,18 +496,9 @@ export class TaskList extends Component {
 
         return (
             <React.Fragment>
-                <PageHeader location={this.props.location} title={'Task - List'} />
+                <PageHeader location={this.props.location} title={'Task - List'} actions={this.state.actions}/>
                 {this.state.isLoading ? <AppLoader /> :
                     <>
-                        <div className="delete-option">
-                            <div >
-                                <span className="p-float-label">
-                                    <a href="#" onClick={this.confirmDeleteTasks} title="Delete selected Task(s)">
-                                        <i class="fa fa-trash" aria-hidden="true" ></i>
-                                    </a>
-                                </span>
-                            </div>
-                        </div>
                         <ViewTable
                             data={this.state.tasks}
                             defaultcolumns={this.state.defaultcolumns}
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 bde2f9d803f8bb2cc98f7fa7bb4a3bbe2aa11a1b..6427470c7d4e01cde703a45ac8e644467c7cf764 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/view.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/view.js
@@ -17,28 +17,27 @@ import { Column } from 'primereact/column';
 
 export class TaskView extends Component {
    // DATE_FORMAT = 'YYYY-MMM-DD HH:mm:ss';
+    TASK_NOT_STARTED_STATUSES = ['defined', 'schedulable', 'scheduled'];
+    TASK_ACTIVE_STATUSES = ['started', 'observing', 'observed', 'processing', 'processed', 'ingesting'];
+    TASK_END_STATUSES = ['finished', 'error', 'cancelled'];
+    
     constructor(props) {
         super(props);
         this.state = {
             isLoading: true,
             confirmDialogVisible: false,
-            hasBlueprint: true
+            hasBlueprint: true,
+            dialog: {}
         };
-        this.showIcon = false;
-        this.dialogType = "confirmation";
-        this.dialogHeader = "";
-        this.dialogMsg = "";
-        this.dialogContent = "";
-        this.callBackFunction = "";
-        this.dialogWidth = '40vw';
-        this.onClose = this.close;
-        this.onCancel =this.close;
 
         this.setEditorFunction = this.setEditorFunction.bind(this);
         this.deleteTask = this.deleteTask.bind(this);
-        this.showConfirmation = this.showConfirmation.bind(this);
-        this.close = this.close.bind(this);
-        this.getDialogContent = this.getDialogContent.bind(this);
+        this.showDeleteConfirmation = this.showDeleteConfirmation.bind(this);
+        this.closeDialog = this.closeDialog.bind(this);
+        this.getTaskDeleteDialogContent = this.getTaskDeleteDialogContent.bind(this);
+        this.showCancelConfirmation = this.showCancelConfirmation.bind(this);
+        this.cancelTask = this.cancelTask.bind(this);
+        
         
         if (this.props.match.params.id) {
             this.state.taskId  = this.props.match.params.id;
@@ -127,23 +126,22 @@ export class TaskView extends Component {
     /**
      * Show confirmation dialog
      */
-    showConfirmation() {
-        this.dialogType = "confirmation";
-        this.dialogHeader = "Confirm to Delete Task";
-        this.showIcon = false;
-        this.dialogMsg = "Do you want to delete this Task?";
-        this.dialogWidth = '55vw';
-        this.dialogContent = this.getDialogContent;
-        this.callBackFunction = this.deleteTask;
-        this.onClose = this.close;
-        this.onCancel =this.close;
-        this.setState({confirmDialogVisible: true});
+    showDeleteConfirmation() {
+        let dialog = this.state.dialog;
+        dialog.type = "confirmation";
+        dialog.header = "Confirm to Delete Task";
+        dialog.showIcon = false;
+        dialog.detail = "Do you want to delete this Task?";
+        dialog.width = '55vw';
+        dialog.content = this.getTaskDeleteDialogContent;
+        dialog.onSubmit = this.deleteTask;
+        this.setState({dialog: dialog, confirmDialogVisible: true});
     }
 
     /**
      * Prepare Task details to show on confirmation dialog
      */
-    getDialogContent() {
+    getTaskDeleteDialogContent() {
         let selectedTasks = [{suId: this.state.schedulingUnit.id, suName: this.state.schedulingUnit.name, taskId: this.state.task.id, 
             controlId: this.state.task.subTaskID, taskName: this.state.task.name, status: this.state.task.status}];
         return  <> 
@@ -158,7 +156,7 @@ export class TaskView extends Component {
                 </>
     }
 
-    close() {
+    closeDialog() {
         this.setState({confirmDialogVisible: false});
     }
 
@@ -185,6 +183,43 @@ export class TaskView extends Component {
         }
     }
 
+    /**
+     * Show confirmation dialog before cancelling the task.
+     */
+     showCancelConfirmation() {
+        let dialog = this.state.dialog;
+        dialog.type = "confirmation";
+        dialog.header = "Confirm to Cancel Task";
+        dialog.actions = [{ id: 'yes', title: 'Yes', callback: this.cancelTask },
+                            { id: 'no', title: 'No', callback: this.closeDialog }];
+        if (this.TASK_NOT_STARTED_STATUSES.indexOf(this.state.task.status) >= 0) {
+            dialog.detail = "Cancelling this task means it will no longer be executed. This action cannot be undone. Do you want to proceed?";
+        }   else if (this.TASK_ACTIVE_STATUSES.indexOf(this.state.task.status) >= 0) {
+            dialog.detail = "Cancelling this task means it will be aborted. This action cannot be undone. Do you want to proceed?";
+        }
+        dialog.submit = this.cancelTask;
+        dialog.width = '40vw';
+        dialog.showIcon = true;
+        this.setState({ dialog: dialog, confirmDialogVisible: true });
+    }
+
+    /**
+     * Function to cancel the task and update its status.
+     */
+    async cancelTask() {
+        let task = this.state.task;
+        let cancelledTask = await TaskService.cancelTask(task.id);
+        if (!cancelledTask) {
+            appGrowl.show({ severity: 'error', summary: 'error', detail: 'Error while cancelling Scheduling Unit' });
+            this.setState({ dialogVisible: false });
+        } else {
+            task.status = cancelledTask.status;
+            let actions = this.state.actions;
+            appGrowl.show({ severity: 'success', summary: 'Success', detail: 'Scheduling Unit is cancelled successfully' });
+            this.setState({ confirmDialogVisible: false, task: task, actions: actions});
+        }
+    }
+
     render() {
         if (this.state.redirect) {
             return <Redirect to={ {pathname: this.state.redirect} }></Redirect>
@@ -212,9 +247,16 @@ export class TaskView extends Component {
         }   else {
             actions = [{    icon: 'fa-lock',
                             title: 'Cannot edit blueprint'}];
+            if (this.state.task) {
+                actions.push({icon: 'fa-ban', type: 'button', actOn: 'click', 
+                                    title: this.TASK_END_STATUSES.indexOf(this.state.task.status.toLowerCase())>=0?'Cannot Cancel Task':'Cancel Task', 
+                                    disabled:this.TASK_END_STATUSES.indexOf(this.state.task.status.toLowerCase())>=0, 
+                                    props: { callback: this.showCancelConfirmation }
+                                });
+            }
         }
         actions.push({icon: 'fa fa-trash',title:this.state.hasBlueprint? 'Cannot delete Draft when Blueprint exists':'Delete Task',  
-                        type: 'button',  disabled: this.state.hasBlueprint, actOn: 'click', props:{ callback: this.showConfirmation}});
+                        type: 'button',  disabled: this.state.hasBlueprint, actOn: 'click', props:{ callback: this.showDeleteConfirmation}});
         actions.push({  icon: 'fa-window-close', link: this.props.history.goBack,
                         title:'Click to Close Task', props : { pathname:'/schedulingunit' }});
 
@@ -283,8 +325,10 @@ export class TaskView extends Component {
                             <span className="col-lg-4 col-md-4 col-sm-12">{this.state.task.end_time?moment(this.state.task.end_time,moment.ISO_8601).format(UIConstants.CALENDAR_DATETIME_FORMAT):""}</span>
                         </div>
                         <div className="p-grid">
-                            <label className="col-lg-2 col-md-2 col-sm-12">Tags</label>
-                            <Chips className="col-lg-4 col-md-4 col-sm-12 chips-readonly" disabled value={this.state.task.tags}></Chips>
+                            {/* <label className="col-lg-2 col-md-2 col-sm-12">Tags</label>
+                            <Chips className="col-lg-4 col-md-4 col-sm-12 chips-readonly" disabled value={this.state.task.tags}></Chips> */}
+                            <label className="col-lg-2 col-md-2 col-sm-12">Status</label>
+                            <span className="col-lg-4 col-md-4 col-sm-12">{this.state.task.status}</span>
                             {this.state.schedulingUnit &&
                             <>
                                 <label className="col-lg-2 col-md-2 col-sm-12">Scheduling Unit</label>
@@ -339,10 +383,10 @@ export class TaskView extends Component {
                         </div>
                     </React.Fragment>
                 }
-                 <CustomDialog type={this.dialogType} visible={this.state.confirmDialogVisible} width={this.dialogWidth}
-                    header={this.dialogHeader} message={this.dialogMsg} 
-                    content={this.dialogContent} onClose={this.onClose} onCancel={this.onCancel} onSubmit={this.callBackFunction}
-                    showIcon={this.showIcon} actions={this.actions}>
+                 <CustomDialog type="confirmation" visible={this.state.confirmDialogVisible} width={this.state.dialog.width}
+                    header={this.state.dialog.header} message={this.state.dialog.detail} 
+                    content={this.state.dialog.content} onClose={this.closeDialog} onCancel={this.closeDialog} onSubmit={this.callBackFunction}
+                    showIcon={this.state.dialog.showIcon} actions={this.state.dialog.actions}>
                 </CustomDialog>
             </React.Fragment>
         );
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 6314ec54e7d3c3ed3952451453f255df559605d0..019b5c4b0595e58f4ab8b0223455f8f6d9871085 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/services/schedule.service.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/services/schedule.service.js
@@ -693,6 +693,16 @@ const ScheduleService = {
             console.error(error);
             return false;
         }
+    },
+    cancelSchedulingUnit: async(id) => {
+        let cancelledSU = null;
+        try {
+            const url = `/api/scheduling_unit_blueprint_extended/${id}/cancel/`;
+            cancelledSU = (await axios.post(url, {})).data;
+        } catch(error) {
+            console.error(error);
+        }
+        return cancelledSU;
     }
 }
 
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 fd4b6d769ecc53b022be3da580317ebbae11a24d..e1f3d57b8cc4a2e92d3d717c5e68c1915042e87c 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/services/task.service.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/services/task.service.js
@@ -266,6 +266,21 @@ const TaskService = {
             console.error(error);
             return false;
         }
+    },
+    /**
+     * Cancel task 
+     * @param {*} type 
+     * @param {*} id 
+     */
+    cancelTask: async function(id) {
+        try {
+            const url = `/api/task_blueprint/${id}/cancel`;
+            await axios.post(url, {});
+            return true;
+        } catch(error) {
+            console.error(error);
+            return false;
+        }
     }
 }