From 2ad735738ad53a51fe3cdd3d3c29b9fab7c8bb13 Mon Sep 17 00:00:00 2001
From: Muthukrishnanmatriot
 <76949556+muthukrishnanmatriot@users.noreply.github.com>
Date: Thu, 26 Aug 2021 21:33:54 +0530
Subject: [PATCH] TMSS-936 & TMSS-941 - added On/Off switch and filter update

---
 .../authenticate/permission.stack.handler.js  |  10 +-
 .../src/components/DynamicScheduler.js        |  85 +++
 .../tmss_webapp/src/routes/Timeline/view.js   | 576 ++++++++++--------
 .../src/routes/Workflow/workflow.list.js      |   1 -
 .../tmss_webapp/src/services/util.service.js  |  31 +-
 5 files changed, 430 insertions(+), 273 deletions(-)
 create mode 100644 SAS/TMSS/frontend/tmss_webapp/src/components/DynamicScheduler.js

diff --git a/SAS/TMSS/frontend/tmss_webapp/src/authenticate/permission.stack.handler.js b/SAS/TMSS/frontend/tmss_webapp/src/authenticate/permission.stack.handler.js
index 1d1c2be92ec..709589985c0 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/authenticate/permission.stack.handler.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/authenticate/permission.stack.handler.js
@@ -44,7 +44,8 @@ const PermissionStackUtil = {
             task_blueprint: 'task_blueprint',
             reservation: 'reservation',
             task_relation_draft: 'task_relation_draft',
-            task_relation_blueprint: 'task_relation_blueprint'
+            task_relation_blueprint: 'task_relation_blueprint',
+            dynamicScheduler: 'setting/dynamic_scheduling_enabled'
         }
         const modules = Object.keys(module_url);
         for(const module of modules) {
@@ -115,7 +116,12 @@ const PermissionStackUtil = {
                         edit: allowedPermission?(_.includes(allowedPermission, 'PATCH')):false,
                         delete: allowedPermission?(_.includes(allowedPermission, 'DELETE')):false
                     };
-                }    
+                }
+                else if (module === 'dynamicScheduler') {
+                    permissionStack[module] = {
+                        setting: allowedPermission?(_.includes(allowedPermission, 'PATCH')):false,
+                    };
+                }
             }
         }
         permissionStack['workflow'] = {
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/components/DynamicScheduler.js b/SAS/TMSS/frontend/tmss_webapp/src/components/DynamicScheduler.js
new file mode 100644
index 00000000000..29df7378f83
--- /dev/null
+++ b/SAS/TMSS/frontend/tmss_webapp/src/components/DynamicScheduler.js
@@ -0,0 +1,85 @@
+import React, { Component } from 'react';
+import UtilService from '../services/util.service';
+import { CustomDialog } from '../layout/components/CustomDialog';
+import { Growl } from 'primereact/components/growl/Growl';
+import { ToggleButton } from 'primereact/togglebutton';
+
+export default class DynamicScheduler extends Component {
+    constructor(props) {
+        super(props);
+        this.dailyOptions= [];
+        this.state= {
+            dsStatus: false, // Dynamic Scheduler Status
+            showDialog: false,
+        }
+        this.currentStatus = null;
+        this.updateDSStatus = this.updateDSStatus.bind(this);
+        this.closeDialog = this.closeDialog.bind(this);
+        this.showConfirmDialog = this.showConfirmDialog.bind(this);
+    }
+
+    async componentDidMount(){
+        let response  = await UtilService.getDynamicSchedulerStatus();
+        var status = false;
+        if(response) {
+            status = response.value;
+        }
+        this.setState({dynamicScheduler: response, dsStatus: status});        
+    } 
+
+    /**
+     * Update Dynamic Scheduling
+     */
+    async updateDSStatus() {
+        let dynamicScheduler = this.state.dynamicScheduler;
+        dynamicScheduler.value = this.currentStatus;
+        let response = await UtilService.updateDynamicSchedulerStatus(dynamicScheduler);
+        if(response) {
+            this.growl.show({severity: 'success', summary: 'Success', detail: 'Dynamic Scheduling Switched '+((this.currentStatus === true)?'On' : 'Off')+' successfully!'}); 
+        }   else {
+            this.growl.show({severity: 'error', summary: 'Error', detail: 'Dynamic Scheduling is not updated successfully.'});
+        }
+        this.setState({dsStatus: this.currentStatus, showDialog: false}); 
+    }
+    
+    /**
+     * Show confirmation dialog to enable/disable Dynamic Scheduling
+     * @param {*} e 
+     */
+    async showConfirmDialog(e) {
+        this.currentStatus = e.value;
+        await this.setState({showDialog: true})
+    }
+
+    /**
+     * Close the Confirmation dialog
+     */
+    closeDialog() {
+        this.setState({showDialog: false});
+    }
+    
+    render() {
+        return (
+            <>
+            <Growl ref={(el) => this.growl = el} />
+            <div className="p-field p-grid">
+                <label htmlFor="autodeletion" style={{marginRight: '10px', marginLeft: '50px'}}>Dynamic Scheduling : </label>
+                <div  data-testid="autodeletion" >
+                <ToggleButton onLabel="On" offLabel="Off" onIcon="pi pi-check" offIcon="pi pi-times" 
+                checked={this.state.dsStatus} onChange={(e) => this.showConfirmDialog(e)} 
+                tooltip={`Click to ${this.state.dsStatus? "'Switch Off'" : "'Switch On'"} the Dynamic Scheduling`}
+                tooltipOptions={this.tooltipOptions}/>
+                
+                    
+                </div>
+            </div>
+
+            <CustomDialog type="confirmation" visible={this.state.showDialog} width={'35vw'}
+                    header={'Confirmation'} message={`Are you sure want to switch ${this.currentStatus === true ? 'On' : 'Off'} the Dynamic Scheduling?` } 
+                    content={''} showIcon={true}
+                    onClose={this.closeDialog} onCancel={this.closeDialog} onSubmit={this.updateDSStatus}
+                     />
+            </>
+        );
+    }
+}
\ No newline at end of file
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js
index 1faf0cf5704..2dd9e702b34 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js
@@ -9,6 +9,7 @@ import { InputSwitch } from 'primereact/inputswitch';
 
 import AppLoader from '../../layout/components/AppLoader';
 import PageHeader from '../../layout/components/PageHeader';
+import { CustomDialog } from '../../layout/components/CustomDialog';
 import Timeline from '../../components/Timeline';
 
 import ScheduleService from '../../services/schedule.service';
@@ -30,6 +31,7 @@ import TimelineListTabs from './list.tabs';
 import TimelineCommonUtils from './common.utils';
 import AuthStore from '../../authenticate/auth.store';
 import AuthUtil from '../../utils/auth.util';
+import DynamicScheduler from '../../components/DynamicScheduler';
 //import { TRUE } from 'node-sass';
 
 
@@ -90,7 +92,8 @@ export class TimelineView extends Component {
             showReservation: this.timelineUIAttributes.showReservation || false,     // Flag to show reservations in normal timeline view
             userrole: AuthStore.getState(),
             suStatusList: [],
-            taskStatusList: []
+            taskStatusList: [],
+            showDialog: false,
         }
         this.STATUS_BEFORE_SCHEDULED = ['defining', 'defined', 'schedulable'];  // Statuses before scheduled to get station_group
         this.allStationsGroup = [];
@@ -123,6 +126,8 @@ export class TimelineView extends Component {
         this.setGroupByProject = this.setGroupByProject.bind(this);
         this.changeViewBlocks = this.changeViewBlocks.bind(this);
         this.showReservationBlocks = this.showReservationBlocks.bind(this);
+        this.showDymanicSchedulerPopup = this.showDymanicSchedulerPopup.bind(this);
+        this.close = this.close.bind(this);
     }
 
     async componentDidMount() {
@@ -1099,7 +1104,22 @@ export class TimelineView extends Component {
         this.setState({suStatusList: suStatusList, taskStatusList: taskStatusList});
     }
 
+    /**
+     * Show Dynamic Scheduling popup
+     */
+    showDymanicSchedulerPopup(){
+        this.setState({showDialog: true});
+    }
+
+    /**
+     * Close Dynamic Scheduling popup
+     */
+    close() {
+        this.setState({showDialog: false});
+    }
+    
     render() {
+        const  {dynamicScheduler}  = this.state.userrole.userRolePermission;
         if (this.state.redirect) {
             return <Redirect to={{ pathname: this.state.redirect }}></Redirect>
         }
@@ -1124,290 +1144,308 @@ export class TimelineView extends Component {
         let mouseOverItem = this.state.mouseOverItem;
         return (
             <React.Fragment>
-                <TieredMenu className="app-header-menu" model={this.state.menuOptions} popup ref={el => this.optionsMenu = el} />
-                <PageHeader location={this.props.location} title={'Scheduling Units - Timeline View'}
-                    actions={[
-                        { icon: 'fa-bars', title: '',
-                            type: 'button', actOn: 'mouseOver', props: { callback: this.showOptionMenu }, },
-                        { icon: 'fa-calendar-alt', title: 'Week View', props: { pathname: `/su/timelineview/week` } }
-                    ]}
-                />
-                { this.state.isLoading ? <AppLoader /> :
-                    <div className="p-grid">
-                        {/* SU List Panel */}
-                        <div className={isSUListVisible && (isSUDetsVisible || isReservDetsVisible || isTaskDetsVisible ||
-                            (canExtendSUList && !canShrinkSUList) ? "col-lg-4 col-md-4 col-sm-12" :
-                            ((canExtendSUList && canShrinkSUList) ? "col-lg-5 col-md-5 col-sm-12" : "col-lg-6 col-md-6 col-sm-12"))}
-                            style={isSUListVisible ? { position: "inherit", borderRight: "3px solid #efefef", paddingTop: "10px" } : { display: 'none' }}>
-                            <TimelineListTabs suBlueprintList={this.state.suBlueprintList}
-                                suListFilterCallback={this.suListFilterCallback}
-                                reservationList={this.getReservationList()}
-                                suStatusList={this.state.suStatusList}
-                                taskStatusList={this.state.taskStatusList}
-                                ></TimelineListTabs>
-                        </div>
-                        {/* Timeline Panel */}
-                        <div className={isSUListVisible ? ((isSUDetsVisible || isReservDetsVisible) ? "col-lg-5 col-md-5 col-sm-12" :
-                            (!canExtendSUList && canShrinkSUList) ? "col-lg-6 col-md-6 col-sm-12" :
-                                ((canExtendSUList && canShrinkSUList) ? "col-lg-7 col-md-7 col-sm-12" : "col-lg-8 col-md-8 col-sm-12")) :
-                            ((isSUDetsVisible || isReservDetsVisible || isTaskDetsVisible) ? "col-lg-9 col-md-9 col-sm-12" : "col-lg-12 col-md-12 col-sm-12")}
-                        // style={{borderLeft: "3px solid #efefef"}}
-                        >
-                            {/* Panel Resize buttons */}
-                            {isSUListVisible &&
-                                <div className="resize-div">
-                                    <button className="p-link resize-btn" disabled={!this.state.canShrinkSUList}
-                                        title="Shrink List/Expand Timeline"
-                                        onClick={(e) => { this.resizeSUList(-1) }}>
-                                        <i className="pi pi-step-backward"></i>
-                                    </button>
-                                    <button className="p-link resize-btn" disabled={!this.state.canExtendSUList}
-                                        title="Expand List/Shrink Timeline"
-                                        onClick={(e) => { this.resizeSUList(1) }}>
-                                        <i className="pi pi-step-forward"></i>
-                                    </button>
+                {dynamicScheduler &&
+                    <>
+                        <TieredMenu className="app-header-menu" model={this.state.menuOptions} popup ref={el => this.optionsMenu = el} />
+                        <PageHeader location={this.props.location} title={'Scheduling Units - Timeline View'}
+                            actions={[
+                                { icon: 'fa-cog',  title: dynamicScheduler.setting? 'Switch On/Off the Dynamic Scheduling': `Don't have permission to Switch On/Off the Dynamic Scheduling`,
+                                    type: 'button', actOn: 'click', props: { callback: this.showDymanicSchedulerPopup }, 
+                                    disabled: dynamicScheduler.setting?!dynamicScheduler.setting:true, },
+                                { icon: 'fa-bars', title: '',
+                                    type: 'button', actOn: 'mouseOver', props: { callback: this.showOptionMenu }, },
+                                { icon: 'fa-calendar-alt', title: 'Week View', props: { pathname: `/su/timelineview/week` } }
+                            ]}
+                        />
+                        { this.state.isLoading ? <AppLoader /> :
+                            <div className="p-grid">
+                                {/* SU List Panel */}
+                                <div className={isSUListVisible && (isSUDetsVisible || isReservDetsVisible || isTaskDetsVisible ||
+                                    (canExtendSUList && !canShrinkSUList) ? "col-lg-4 col-md-4 col-sm-12" :
+                                    ((canExtendSUList && canShrinkSUList) ? "col-lg-5 col-md-5 col-sm-12" : "col-lg-6 col-md-6 col-sm-12"))}
+                                    style={isSUListVisible ? { position: "inherit", borderRight: "3px solid #efefef", paddingTop: "10px" } : { display: 'none' }}>
+                                    <TimelineListTabs suBlueprintList={this.state.suBlueprintList}
+                                        suListFilterCallback={this.suListFilterCallback}
+                                        reservationList={this.getReservationList()}
+                                        suStatusList={this.state.suStatusList}
+                                        taskStatusList={this.state.taskStatusList}
+                                        ></TimelineListTabs>
                                 </div>
-                            }
-                            <div className={isSUListVisible ? "resize-div su-visible" : "resize-div su-hidden"}>
-                                {isSUListVisible &&
-                                    <button className="p-link resize-btn"
-                                        title="Hide List"
-                                        onClick={(e) => { this.showListPanel(false) }}>
-                                        <i className="pi pi-eye-slash"></i>
-                                    </button>
-                                }
-                                {!isSUListVisible &&
-                                    <button className="p-link resize-btn"
-                                        title="Show List"
-                                        onClick={(e) => { this.showListPanel(true) }}>
-                                        <i className="pi pi-eye"> Show List</i>
-                                    </button>
-                                }
-                            </div>
-                            <div className={`timeline-view-toolbar p-grid ${this.state.stationView && 'alignTimeLineHeader'}`}>
-                                <div className="sub-header col-lg-2">
-                                    <label >Station View</label>
-                                    <InputSwitch checked={this.state.stationView} onChange={(e) => { this.setStationView(e) }} />
-                                </div>
-                                {this.state.stationView &&
-                                <>
-                                    <div className="sub-header col-lg-2">
-                                        <label>Show</label>
-                                        <Button className="p-button-rounded toggle-btn" 
-                                            tooltip={this.state.isStationTasksVisible?"Show Scheduling Units":"Show Tasks"}
-                                            style={{minWidth: "50px"}}
-                                            label={this.state.isStationTasksVisible?"SUs":"Tasks"} 
-                                            onClick={e => this.changeViewBlocks()} />
-                                    </div>
-                                    <div className="sub-header col-lg-4">
-                                        <label style={{ marginLeft: '20px' }}>Stations Group</label>
-                                        <MultiSelect data-testid="stations" id="stations" optionLabel="value" optionValue="value"
-                                            style={{ top: '2px', width: '175px' }}
-                                            tooltip="Select Stations"
-                                            value={this.state.selectedStationGroup}
-                                            options={this.mainStationGroupOptions}
-                                            placeholder="Select Group"
-                                            onChange={(e) => this.setSelectedStationGroup(e.value)}
-                                        />
-                                    </div>
-                                </>
-                                }
-                                {!this.state.stationView &&
-                                    <>
-                                    <div className="sub-header col-lg-5">
-                                        <div className={`sub-header-content ${isSUListVisible?"col-lg-12":"col-lg-8"}`} style={{padding: '0px !important'}}>
-                                        <fieldset>
-                                            <label style={{ marginLeft: '0px' }}>Show :</label>
-                                            <input type="radio" value="su" name="Only SUs" className="timeline-toolbar-radio" inputId="suOnly" onClick={(e) => this.showTimelineItems(e.target.value)} checked={this.state.showSUs && !this.state.showTasks} />
-                                            <label htmlFor="suOnly">Only SU</label>
-                                            <input type="radio" value="task" name="Only Tasks" className="timeline-toolbar-radio" inputId="taskOnly" onChange={(e) => this.showTimelineItems(e.target.value)} checked={!this.state.showSUs && this.state.showTasks} />
-                                            <label htmlFor="suOnly">Only Task</label>
-                                            <input type="radio" value="suTask" name="Both" className="timeline-toolbar-radio" inputId="bothSuTask" onChange={(e) => this.showTimelineItems(e.target.value)} checked={this.state.showSUs && this.state.showTasks} />
-                                            <label htmlFor="suOnly">Both</label>
-                                        </fieldset>
+                                {/* Timeline Panel */}
+                                <div className={isSUListVisible ? ((isSUDetsVisible || isReservDetsVisible) ? "col-lg-5 col-md-5 col-sm-12" :
+                                    (!canExtendSUList && canShrinkSUList) ? "col-lg-6 col-md-6 col-sm-12" :
+                                        ((canExtendSUList && canShrinkSUList) ? "col-lg-7 col-md-7 col-sm-12" : "col-lg-8 col-md-8 col-sm-12")) :
+                                    ((isSUDetsVisible || isReservDetsVisible || isTaskDetsVisible) ? "col-lg-9 col-md-9 col-sm-12" : "col-lg-12 col-md-12 col-sm-12")}
+                                // style={{borderLeft: "3px solid #efefef"}}
+                                >
+                                    {/* Panel Resize buttons */}
+                                    {isSUListVisible &&
+                                        <div className="resize-div">
+                                            <button className="p-link resize-btn" disabled={!this.state.canShrinkSUList}
+                                                title="Shrink List/Expand Timeline"
+                                                onClick={(e) => { this.resizeSUList(-1) }}>
+                                                <i className="pi pi-step-backward"></i>
+                                            </button>
+                                            <button className="p-link resize-btn" disabled={!this.state.canExtendSUList}
+                                                title="Expand List/Shrink Timeline"
+                                                onClick={(e) => { this.resizeSUList(1) }}>
+                                                <i className="pi pi-step-forward"></i>
+                                            </button>
                                         </div>
-                                        {this.state.showTasks &&
-                                            <div className={`sub-header-content ${isSUListVisible?"col-lg-12":"col-lg-3"}`} style={{padding: '0px !important', marginLeft: `${isSUListVisible?"50px":"0px"}`}}>
-                                            <MultiSelect data-testid="tasks" id="tasks" optionLabel="value" optionValue="value"
-                                                style={{ width: '120px', height: '25px', marginRight: '10px' }}
-                                                tooltip={this.state.selectedTaskTypes.length>0?
-                                                            `Showing tasks of task type(s) ${this.state.selectedTaskTypes.join(', ')}`:
-                                                            "Select task type(s) to show in the timeline"}
-                                                maxSelectedLabels="1"
-                                                selectedItemsLabel="{0} Task Types"
-                                                value={this.state.selectedTaskTypes}
-                                                options={this.state.taskTypes}
-                                                placeholder="Task Type"
-                                                onChange={(e) => {this.setSelectedTaskTypes(e.value)}}
-                                            />
-                                            </div>
+                                    }
+                                    <div className={isSUListVisible ? "resize-div su-visible" : "resize-div su-hidden"}>
+                                        {isSUListVisible &&
+                                            <button className="p-link resize-btn"
+                                                title="Hide List"
+                                                onClick={(e) => { this.showListPanel(false) }}>
+                                                <i className="pi pi-eye-slash"></i>
+                                            </button>
+                                        }
+                                        {!isSUListVisible &&
+                                            <button className="p-link resize-btn"
+                                                title="Show List"
+                                                onClick={(e) => { this.showListPanel(true) }}>
+                                                <i className="pi pi-eye"> Show List</i>
+                                            </button>
                                         }
                                     </div>
-                                    <div className="sub-header col-lg-2" style={{paddingTop: "15px !important"}}>
-                                        {this.state.groupByProject &&
-                                            <Button className="p-button-rounded toggle-btn" label="Group By SU" onClick={e => this.setGroupByProject(false)} />}
-                                        {!this.state.groupByProject &&
-                                            <Button className="p-button-rounded toggle-btn" label="Group By Project" onClick={e => this.setGroupByProject(true)} />}
-                                    </div>
-                                    </>
-                                }
-                                <div className="sub-header col-lg-3">
-                                    {!this.state.stationView && 
-                                        <Button className="p-button-rounded toggle-btn" 
-                                        tooltip={this.state.showReservation?"Hide Reservations":"Show Reservations"}
-                                        style={{minWidth: "50px"}}
-                                        label={this.state.showReservation?"Hide Reservation":"Show Reservation"} 
-                                        onClick={e => this.showReservationBlocks()} />
-                                    }
-                                    { this.state.stationView && 
-                                        <label style={{ marginLeft: '20px' }}>Reservation</label>
-                                    }
-                                    { (this.state.stationView || this.state.showReservation) &&
+                                    <div className={`timeline-view-toolbar p-grid ${this.state.stationView && 'alignTimeLineHeader'}`}>
+                                        <div className="sub-header col-lg-2">
+                                            <label >Station View</label>
+                                            <InputSwitch checked={this.state.stationView} onChange={(e) => { this.setStationView(e) }} />
+                                        </div>
+                                        {this.state.stationView &&
                                         <>
-                                        <MultiSelect data-testid="reserv-reasons" id="reserv-reasons" 
-                                            optionLabel="name" optionValue="name"
-                                            style={{ top: '2px', marginLeft:'5px', minWidth: '100px' }}
-                                            panelStyle={{right: '0px'}}
-                                            tooltip="Select Reservation Reason(s)"
-                                            value={this.state.reservationFilter}
-                                            options={this.reservationReasons}
-                                            maxSelectedLabels="1"
-                                            filter showClear={true} filterBy="name"
-                                            placeholder="Reason"
-                                            onChange={(e) => this.setReservationFilter(e.value)}
-                                        />
+                                            <div className="sub-header col-lg-2">
+                                                <label>Show</label>
+                                                <Button className="p-button-rounded toggle-btn" 
+                                                    tooltip={this.state.isStationTasksVisible?"Show Scheduling Units":"Show Tasks"}
+                                                    style={{minWidth: "50px"}}
+                                                    label={this.state.isStationTasksVisible?"SUs":"Tasks"} 
+                                                    onClick={e => this.changeViewBlocks()} />
+                                            </div>
+                                            <div className="sub-header col-lg-4">
+                                                <label style={{ marginLeft: '20px' }}>Stations Group</label>
+                                                <MultiSelect data-testid="stations" id="stations" optionLabel="value" optionValue="value"
+                                                    style={{ top: '2px', width: '175px' }}
+                                                    tooltip="Select Stations"
+                                                    value={this.state.selectedStationGroup}
+                                                    options={this.mainStationGroupOptions}
+                                                    placeholder="Select Group"
+                                                    onChange={(e) => this.setSelectedStationGroup(e.value)}
+                                                />
+                                            </div>
                                         </>
-                                    }
-                                </div>
+                                        }
+                                        {!this.state.stationView &&
+                                            <>
+                                            <div className="sub-header col-lg-5">
+                                                <div className={`sub-header-content ${isSUListVisible?"col-lg-12":"col-lg-8"}`} style={{padding: '0px !important'}}>
+                                                <fieldset>
+                                                    <label style={{ marginLeft: '0px' }}>Show :</label>
+                                                    <input type="radio" value="su" name="Only SUs" className="timeline-toolbar-radio" inputId="suOnly" onClick={(e) => this.showTimelineItems(e.target.value)} checked={this.state.showSUs && !this.state.showTasks} />
+                                                    <label htmlFor="suOnly">Only SU</label>
+                                                    <input type="radio" value="task" name="Only Tasks" className="timeline-toolbar-radio" inputId="taskOnly" onChange={(e) => this.showTimelineItems(e.target.value)} checked={!this.state.showSUs && this.state.showTasks} />
+                                                    <label htmlFor="suOnly">Only Task</label>
+                                                    <input type="radio" value="suTask" name="Both" className="timeline-toolbar-radio" inputId="bothSuTask" onChange={(e) => this.showTimelineItems(e.target.value)} checked={this.state.showSUs && this.state.showTasks} />
+                                                    <label htmlFor="suOnly">Both</label>
+                                                </fieldset>
+                                                </div>
+                                                {this.state.showTasks &&
+                                                    <div className={`sub-header-content ${isSUListVisible?"col-lg-12":"col-lg-3"}`} style={{padding: '0px !important', marginLeft: `${isSUListVisible?"50px":"0px"}`}}>
+                                                    <MultiSelect data-testid="tasks" id="tasks" optionLabel="value" optionValue="value"
+                                                        style={{ width: '120px', height: '25px', marginRight: '10px' }}
+                                                        tooltip={this.state.selectedTaskTypes.length>0?
+                                                                    `Showing tasks of task type(s) ${this.state.selectedTaskTypes.join(', ')}`:
+                                                                    "Select task type(s) to show in the timeline"}
+                                                        maxSelectedLabels="1"
+                                                        selectedItemsLabel="{0} Task Types"
+                                                        value={this.state.selectedTaskTypes}
+                                                        options={this.state.taskTypes}
+                                                        placeholder="Task Type"
+                                                        onChange={(e) => {this.setSelectedTaskTypes(e.value)}}
+                                                    />
+                                                    </div>
+                                                }
+                                            </div>
+                                            <div className="sub-header col-lg-2" style={{paddingTop: "15px !important"}}>
+                                                {this.state.groupByProject &&
+                                                    <Button className="p-button-rounded toggle-btn" label="Group By SU" onClick={e => this.setGroupByProject(false)} />}
+                                                {!this.state.groupByProject &&
+                                                    <Button className="p-button-rounded toggle-btn" label="Group By Project" onClick={e => this.setGroupByProject(true)} />}
+                                            </div>
+                                            </>
+                                        }
+                                        <div className="sub-header col-lg-3">
+                                            {!this.state.stationView && 
+                                                <Button className="p-button-rounded toggle-btn" 
+                                                tooltip={this.state.showReservation?"Hide Reservations":"Show Reservations"}
+                                                style={{minWidth: "50px"}}
+                                                label={this.state.showReservation?"Hide Reservation":"Show Reservation"} 
+                                                onClick={e => this.showReservationBlocks()} />
+                                            }
+                                            { this.state.stationView && 
+                                                <label style={{ marginLeft: '20px' }}>Reservation</label>
+                                            }
+                                            { (this.state.stationView || this.state.showReservation) &&
+                                                <>
+                                                <MultiSelect data-testid="reserv-reasons" id="reserv-reasons" 
+                                                    optionLabel="name" optionValue="name"
+                                                    style={{ top: '2px', marginLeft:'5px', minWidth: '100px' }}
+                                                    panelStyle={{right: '0px'}}
+                                                    tooltip="Select Reservation Reason(s)"
+                                                    value={this.state.reservationFilter}
+                                                    options={this.reservationReasons}
+                                                    maxSelectedLabels="1"
+                                                    filter showClear={true} filterBy="name"
+                                                    placeholder="Reason"
+                                                    onChange={(e) => this.setReservationFilter(e.value)}
+                                                />
+                                                </>
+                                            }
+                                        </div>
 
-                            </div>
+                                    </div>
 
-                            <Timeline ref={(tl) => { this.timeline = tl }}
-                                defaultStartTime={this.state.currentStartTime}
-                                defaultEndTime={this.state.currentEndTime}
-                                group={this.state.group}
-                                items={this.state.items}
-                                currentUTC={this.state.currentUTC}
-                                rowHeight={this.state.stationView ? 50 : 50}
-                                sidebarWidth={!this.state.showSUs ? 250 : 200}
-                                itemClickCallback={this.onItemClick}
-                                itemMouseOverCallback={this.onItemMouseOver}
-                                itemMouseOutCallback={this.onItemMouseOut}
-                                dateRangeCallback={this.dateRangeCallback}
-                                showSunTimings={!this.state.stationView}
-                                timelineCommonUtils={this.timelineCommonUtils}
-                                timelineUIAttributes={this.timelineUIAttributes}
-                                // stackItems ={this.state.stationView}
-                                stackItems
-                                className="timeline-toolbar-margin-top-0"></Timeline>
-                        </div>
-                        {/* Details Panel */}
-                        {this.state.isSUDetsVisible &&
-                            <div className="col-lg-3 col-md-3 col-sm-12"
-                                style={{ borderLeft: "1px solid #efefef", marginTop: "0px", backgroundColor: "#f2f2f2" }}>
-                                {this.state.isSummaryLoading ? <AppLoader /> :
-                                    <SchedulingUnitSummary schedulingUnit={suBlueprint} suTaskList={this.state.suTaskList}
-                                        viewInNewWindow
-                                        constraintsTemplate={this.state.suConstraintTemplate}
-                                        stationGroup={this.state.stationGroup}
-                                        closeCallback={this.closeSUDets}></SchedulingUnitSummary>
+                                    <Timeline ref={(tl) => { this.timeline = tl }}
+                                        defaultStartTime={this.state.currentStartTime}
+                                        defaultEndTime={this.state.currentEndTime}
+                                        group={this.state.group}
+                                        items={this.state.items}
+                                        currentUTC={this.state.currentUTC}
+                                        rowHeight={this.state.stationView ? 50 : 50}
+                                        sidebarWidth={!this.state.showSUs ? 250 : 200}
+                                        itemClickCallback={this.onItemClick}
+                                        itemMouseOverCallback={this.onItemMouseOver}
+                                        itemMouseOutCallback={this.onItemMouseOut}
+                                        dateRangeCallback={this.dateRangeCallback}
+                                        showSunTimings={!this.state.stationView}
+                                        timelineCommonUtils={this.timelineCommonUtils}
+                                        timelineUIAttributes={this.timelineUIAttributes}
+                                        // stackItems ={this.state.stationView}
+                                        stackItems
+                                        className="timeline-toolbar-margin-top-0"></Timeline>
+                                </div>
+                                {/* Details Panel */}
+                                {this.state.isSUDetsVisible &&
+                                    <div className="col-lg-3 col-md-3 col-sm-12"
+                                        style={{ borderLeft: "1px solid #efefef", marginTop: "0px", backgroundColor: "#f2f2f2" }}>
+                                        {this.state.isSummaryLoading ? <AppLoader /> :
+                                            <SchedulingUnitSummary schedulingUnit={suBlueprint} suTaskList={this.state.suTaskList}
+                                                viewInNewWindow
+                                                constraintsTemplate={this.state.suConstraintTemplate}
+                                                stationGroup={this.state.stationGroup}
+                                                closeCallback={this.closeSUDets}></SchedulingUnitSummary>
+                                        }
+                                    </div>
                                 }
-                            </div>
-                        }
-                        {this.state.isTaskDetsVisible &&
-                            <div className="col-lg-3 col-md-3 col-sm-12"
-                                style={{ borderLeft: "1px solid #efefef", marginTop: "0px", backgroundColor: "#f2f2f2" }}>
-                                {this.state.isSummaryLoading ? <AppLoader /> :
-                                    <div>Yet to be developed <i className="fa fa-times" onClick={this.closeSUDets}></i></div>
+                                {this.state.isTaskDetsVisible &&
+                                    <div className="col-lg-3 col-md-3 col-sm-12"
+                                        style={{ borderLeft: "1px solid #efefef", marginTop: "0px", backgroundColor: "#f2f2f2" }}>
+                                        {this.state.isSummaryLoading ? <AppLoader /> :
+                                            <div>Yet to be developed <i className="fa fa-times" onClick={this.closeSUDets}></i></div>
+                                        }
+                                    </div>
                                 }
-                            </div>
-                        }
-                        {this.state.isReservDetsVisible &&
-                            <div className="col-lg-3 col-md-3 col-sm-12"
-                                style={{ borderLeft: "1px solid #efefef", marginTop: "0px", backgroundColor: "#f2f2f2" }}>
-                                {this.state.isSummaryLoading ? <AppLoader /> :
-                                    <ReservationSummary reservation={reservation} viewInNewWindow={true}
-                                        closeCallback={this.closeSUDets}></ReservationSummary>
+                                {this.state.isReservDetsVisible &&
+                                    <div className="col-lg-3 col-md-3 col-sm-12"
+                                        style={{ borderLeft: "1px solid #efefef", marginTop: "0px", backgroundColor: "#f2f2f2" }}>
+                                        {this.state.isSummaryLoading ? <AppLoader /> :
+                                            <ReservationSummary reservation={reservation} viewInNewWindow={true}
+                                                closeCallback={this.closeSUDets}></ReservationSummary>
+                                        }
+                                    </div>
                                 }
                             </div>
-                        }
-                    </div>
 
-                }
-                {/* SU Item Tooltip popover with SU status color */}
-                <OverlayPanel className="timeline-popover" ref={(el) => this.popOver = el} dismissable>
-                    {(mouseOverItem && (["SCHEDULE", "TASK", "STATION_TASK"].indexOf(mouseOverItem.type) >= 0)) &&
-                        <div className={`p-grid su-${mouseOverItem.status}`} style={{ width: '350px' }}>
-                            <h3 className={`col-12 su-${mouseOverItem.status}-icon`}>{mouseOverItem.type === 'SCHEDULE' ? 'Scheduling Unit ' : 'Task '}Overview</h3>
-                            <hr></hr>
-                            <label className={`col-5 su-${mouseOverItem.status}-icon`}>Project:</label>
-                            <div className="col-7">{mouseOverItem.project}</div>
-                            <label className={`col-5 su-${mouseOverItem.status}-icon`}>Scheduling Unit:</label>
-                            <div className="col-7">{mouseOverItem.suName}</div>
-                            {mouseOverItem.type === 'SCHEDULE' &&
-                                <>
+                        }
+                        {/* SU Item Tooltip popover with SU status color */}
+                        <OverlayPanel className="timeline-popover" ref={(el) => this.popOver = el} dismissable>
+                            {(mouseOverItem && (["SCHEDULE", "TASK", "STATION_TASK"].indexOf(mouseOverItem.type) >= 0)) &&
+                                <div className={`p-grid su-${mouseOverItem.status}`} style={{ width: '350px' }}>
+                                    <h3 className={`col-12 su-${mouseOverItem.status}-icon`}>{mouseOverItem.type === 'SCHEDULE' ? 'Scheduling Unit ' : 'Task '}Overview</h3>
+                                    <hr></hr>
+                                    <label className={`col-5 su-${mouseOverItem.status}-icon`}>Project:</label>
+                                    <div className="col-7">{mouseOverItem.project}</div>
+                                    <label className={`col-5 su-${mouseOverItem.status}-icon`}>Scheduling Unit:</label>
+                                    <div className="col-7">{mouseOverItem.suName}</div>
+                                    {mouseOverItem.type === 'SCHEDULE' &&
+                                        <>
 
-                                    <label className={`col-5 su-${mouseOverItem.status}-icon`}>Scheduler:</label>
-                                    <div className="col-7">{mouseOverItem.scheduleMethod}</div>
-                                    <label className={`col-5 su-${mouseOverItem.status}-icon`}>Friends:</label>
-                                    <div className="col-7">{mouseOverItem.friends ? mouseOverItem.friends : "-"}</div>
-                                </>}
-                            { (mouseOverItem.type === 'TASK' || mouseOverItem.type === 'STATION_TASK') &&
-                                <>
-                                    <label className={`col-5 su-${mouseOverItem.status}-icon`}>Task Name:</label>
+                                            <label className={`col-5 su-${mouseOverItem.status}-icon`}>Scheduler:</label>
+                                            <div className="col-7">{mouseOverItem.scheduleMethod}</div>
+                                            <label className={`col-5 su-${mouseOverItem.status}-icon`}>Friends:</label>
+                                            <div className="col-7">{mouseOverItem.friends ? mouseOverItem.friends : "-"}</div>
+                                        </>}
+                                    { (mouseOverItem.type === 'TASK' || mouseOverItem.type === 'STATION_TASK') &&
+                                        <>
+                                            <label className={`col-5 su-${mouseOverItem.status}-icon`}>Task Name:</label>
+                                            <div className="col-7">{mouseOverItem.name}</div>
+                                        </>}
+                                    <label className={`col-5 su-${mouseOverItem.status}-icon`}>Start Time:</label>
+                                    <div className="col-7">{mouseOverItem.start_time.format(UIConstants.CALENDAR_DATETIME_FORMAT)}</div>
+                                    <label className={`col-5 su-${mouseOverItem.status}-icon`}>End Time:</label>
+                                    <div className="col-7">{mouseOverItem.end_time.format(UIConstants.CALENDAR_DATETIME_FORMAT)}</div>
+                                    {mouseOverItem.type === 'SCHEDULE' &&
+                                        <>
+                                            <label className={`col-5 su-${mouseOverItem.status}-icon`}>Antenna Set:</label>
+                                            <div className="col-7">{mouseOverItem.antennaSet}</div>
+                                        </>}
+                                    <label className={`col-5 su-${mouseOverItem.status}-icon`}>Stations:</label>
+                                    <div className="col-7">{mouseOverItem.stations.groups}:{mouseOverItem.stations.counts}</div>
+                                    <label className={`col-5 su-${mouseOverItem.status}-icon`}>Status:</label>
+                                    <div className="col-7">{mouseOverItem.status}</div>
+                                    <label className={`col-5 su-${mouseOverItem.status}-icon`}>Duration:</label>
+                                    <div className="col-7">{mouseOverItem.duration}</div>
+                                </div>
+                            }
+                            {(mouseOverItem && mouseOverItem.type === "RESERVATION") &&
+                                <div className={`p-grid`} style={{ width: '350px', backgroundColor: mouseOverItem.bgColor, color: mouseOverItem.color }}>
+                                    <h3 className={`col-12`}>Reservation Overview</h3>
+                                    <hr></hr>
+                                    <label className={`col-5`} style={{ color: mouseOverItem.color }}>Name:</label>
                                     <div className="col-7">{mouseOverItem.name}</div>
-                                </>}
-                            <label className={`col-5 su-${mouseOverItem.status}-icon`}>Start Time:</label>
-                            <div className="col-7">{mouseOverItem.start_time.format(UIConstants.CALENDAR_DATETIME_FORMAT)}</div>
-                            <label className={`col-5 su-${mouseOverItem.status}-icon`}>End Time:</label>
-                            <div className="col-7">{mouseOverItem.end_time.format(UIConstants.CALENDAR_DATETIME_FORMAT)}</div>
-                            {mouseOverItem.type === 'SCHEDULE' &&
-                                <>
-                                    <label className={`col-5 su-${mouseOverItem.status}-icon`}>Antenna Set:</label>
-                                    <div className="col-7">{mouseOverItem.antennaSet}</div>
-                                </>}
-                            <label className={`col-5 su-${mouseOverItem.status}-icon`}>Stations:</label>
-                            <div className="col-7">{mouseOverItem.stations.groups}:{mouseOverItem.stations.counts}</div>
-                            <label className={`col-5 su-${mouseOverItem.status}-icon`}>Status:</label>
-                            <div className="col-7">{mouseOverItem.status}</div>
-                            <label className={`col-5 su-${mouseOverItem.status}-icon`}>Duration:</label>
-                            <div className="col-7">{mouseOverItem.duration}</div>
-                        </div>
-                    }
-                    {(mouseOverItem && mouseOverItem.type === "RESERVATION") &&
-                        <div className={`p-grid`} style={{ width: '350px', backgroundColor: mouseOverItem.bgColor, color: mouseOverItem.color }}>
-                            <h3 className={`col-12`}>Reservation Overview</h3>
-                            <hr></hr>
-                            <label className={`col-5`} style={{ color: mouseOverItem.color }}>Name:</label>
-                            <div className="col-7">{mouseOverItem.name}</div>
-                            <label className={`col-5`} style={{ color: mouseOverItem.color }}>Description:</label>
-                            <div className="col-7">{mouseOverItem.desc}</div>
-                            <label className={`col-5`} style={{ color: mouseOverItem.color }}>Type:</label>
-                            <div className="col-7">{mouseOverItem.activity_type}</div>
-                            <label className={`col-5`} style={{ color: mouseOverItem.color }}>Stations:</label>
-                            {/* <div className="col-7"><ListBox options={mouseOverItem.stations} /></div> */}
-                            <div className="col-7 station-list">
-                                {mouseOverItem.stations.map((station, index) => (
-                                    <div key={`stn-${index}`}>{station}</div>
-                                ))}
+                                    <label className={`col-5`} style={{ color: mouseOverItem.color }}>Description:</label>
+                                    <div className="col-7">{mouseOverItem.desc}</div>
+                                    <label className={`col-5`} style={{ color: mouseOverItem.color }}>Type:</label>
+                                    <div className="col-7">{mouseOverItem.activity_type}</div>
+                                    <label className={`col-5`} style={{ color: mouseOverItem.color }}>Stations:</label>
+                                    {/* <div className="col-7"><ListBox options={mouseOverItem.stations} /></div> */}
+                                    <div className="col-7 station-list">
+                                        {mouseOverItem.stations.map((station, index) => (
+                                            <div key={`stn-${index}`}>{station}</div>
+                                        ))}
+                                    </div>
+                                    <label className={`col-5`} style={{ color: mouseOverItem.color }}>Project:</label>
+                                    <div className="col-7">{mouseOverItem.project ? mouseOverItem.project : "-"}</div>
+                                    <label className={`col-5`} style={{ color: mouseOverItem.color }}>Start Time:</label>
+                                    <div className="col-7">{mouseOverItem.start_time.format(UIConstants.CALENDAR_DATETIME_FORMAT)}</div>
+                                    <label className={`col-5`} style={{ color: mouseOverItem.color }}>End Time:</label>
+                                    <div className="col-7">{mouseOverItem.duration!=="Unknown"?mouseOverItem.end_time.format(UIConstants.CALENDAR_DATETIME_FORMAT):"Unknown"}</div>
+                                    {/* <label className={`col-5`} style={{color: mouseOverItem.color}}>Stations:</label>
+                                <div className="col-7">{mouseOverItem.stations.groups}:{mouseOverItem.stations.counts}</div> */}
+                                    <label className={`col-5`} style={{ color: mouseOverItem.color }}>Duration:</label>
+                                    <div className="col-7">{mouseOverItem.duration}</div>
+                                    <label className={`col-5`} style={{ color: mouseOverItem.color }}>Planned:</label>
+                                    <div className="col-7">{mouseOverItem.planned ? 'Yes' : 'No'}</div>
+                                </div>
+                            }
+                        </OverlayPanel>
+                        {!this.state.isLoading &&
+                            <Websocket url={process.env.REACT_APP_WEBSOCKET_URL} onOpen={this.onConnect} onMessage={this.handleData} onClose={this.onDisconnect} />}
+                        {this.state.showDialog &&
+                            <div className="p-grid" data-testid="confirm_dialog">
+                                <CustomDialog type="success" visible={this.state.showDialog} width="30vw" showIcon={false}
+                                    header="Dynamic Scheduling Settings" message={<DynamicScheduler />} 
+                                    content={''} 
+                                    actions={ [ 
+                                    {id:"no", title: 'Close', callback: this.close} ]}
+                                    onClose={this.close}
+                                    />
                             </div>
-                            <label className={`col-5`} style={{ color: mouseOverItem.color }}>Project:</label>
-                            <div className="col-7">{mouseOverItem.project ? mouseOverItem.project : "-"}</div>
-                            <label className={`col-5`} style={{ color: mouseOverItem.color }}>Start Time:</label>
-                            <div className="col-7">{mouseOverItem.start_time.format(UIConstants.CALENDAR_DATETIME_FORMAT)}</div>
-                            <label className={`col-5`} style={{ color: mouseOverItem.color }}>End Time:</label>
-                            <div className="col-7">{mouseOverItem.duration!=="Unknown"?mouseOverItem.end_time.format(UIConstants.CALENDAR_DATETIME_FORMAT):"Unknown"}</div>
-                            {/* <label className={`col-5`} style={{color: mouseOverItem.color}}>Stations:</label>
-                        <div className="col-7">{mouseOverItem.stations.groups}:{mouseOverItem.stations.counts}</div> */}
-                            <label className={`col-5`} style={{ color: mouseOverItem.color }}>Duration:</label>
-                            <div className="col-7">{mouseOverItem.duration}</div>
-                            <label className={`col-5`} style={{ color: mouseOverItem.color }}>Planned:</label>
-                            <div className="col-7">{mouseOverItem.planned ? 'Yes' : 'No'}</div>
-                        </div>
-                    }
-                </OverlayPanel>
-                {!this.state.isLoading &&
-                    <Websocket url={process.env.REACT_APP_WEBSOCKET_URL} onOpen={this.onConnect} onMessage={this.handleData} onClose={this.onDisconnect} />}
+                        }
+                    </>
+                }
             </React.Fragment>
 
         );
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Workflow/workflow.list.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Workflow/workflow.list.js
index 2d8c808db2d..d0167fada52 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Workflow/workflow.list.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Workflow/workflow.list.js
@@ -36,7 +36,6 @@ class WorkflowList extends Component{
                 suName:"Scheduling Unit Name",
                 su: {
                     name: "Scheduling Unit ID",
-                    filter: "range",
                     format: UIConstants.CALENDAR_TIME_FORMAT
                 },
                 status: {
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/services/util.service.js b/SAS/TMSS/frontend/tmss_webapp/src/services/util.service.js
index cdb5e1876a5..4529a11408a 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/services/util.service.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/services/util.service.js
@@ -229,7 +229,36 @@ const UtilService = {
             console.error('[UtilService.getProjectRoles]', error);
             return [];
         }
-    }
+    },
+    /**
+     * Get Dynamic Schediling On/Off Status
+     * @returns JSON object
+     */
+    getDynamicSchedulerStatus: async function() {
+      try {
+        const url = `/api/setting/dynamic_scheduling_enabled`;
+        const response = await axios.get(url);
+        return response.data;
+      } catch (error) {
+        console.error('[getDynamicSchedulerStatus]',"Mistake", error);
+        return null;
+      }
+    },
+    /**
+     * Update Switch On/Off status of Dynamic Scheduling
+     * @param {Object} JSON object 
+     * @returns 
+     */
+    updateDynamicSchedulerStatus: async function (response) {
+      try {
+        const url = `/api/setting/dynamic_scheduling_enabled`;
+        response = await axios.patch(url, response);
+        return response.data;
+      } catch (error) {
+        console.error('[updateDynamicSchedulerStatus]',"Mistake", error);
+        return null
+      }
+  },
 }
 
 export default UtilService;
\ No newline at end of file
-- 
GitLab