From fe15d74d0ea37cbae5296f678814d6943d3b1657 Mon Sep 17 00:00:00 2001
From: /nithya <nithya.s@matriotsolutions.com>
Date: Tue, 27 Apr 2021 08:50:10 +0530
Subject: [PATCH] TMSS-620

Updated TMSS-621,stored sorting Order in Project and Cycle List
---
 .../tmss_webapp/src/components/ViewTable.js   |  86 +++---
 .../tmss_webapp/src/routes/Cycle/list.js      | 246 +++++++++--------
 .../tmss_webapp/src/routes/Project/list.js    | 249 ++++++++++--------
 .../tmss_webapp/src/services/util.service.js  |  13 +-
 4 files changed, 353 insertions(+), 241 deletions(-)

diff --git a/SAS/TMSS/frontend/tmss_webapp/src/components/ViewTable.js b/SAS/TMSS/frontend/tmss_webapp/src/components/ViewTable.js
index fd303672460..262d43b1d38 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/components/ViewTable.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/components/ViewTable.js
@@ -289,7 +289,7 @@ function CalendarColumnFilter({
     <div className="table-filter" onClick={e => { e.stopPropagation() }}>
       <Calendar value={filterValue} appendTo={document.body} dateFormat="yy-mm-dd" onChange={(e) => {
         const value = moment(e.value).format('YYYY-MM-DD')
-        setValue(value); 
+        setValue(value);
         setFilter(e.value);
       }} showIcon></Calendar>
       {value && <i onClick={() => { setFilter(undefined); setValue('') }} className="tb-cal-reset fa fa-times" />}
@@ -599,8 +599,8 @@ const IndeterminateCheckbox = React.forwardRef(
 )
 
 // Our table component
-function Table({ columns, data, defaultheader, optionalheader, tablename, defaultSortColumn, defaultpagesize, columnOrders, showAction }) {
-
+function Table(props) {
+  const { columns, data, defaultheader, optionalheader, tablename, defaultSortColumn, defaultpagesize, columnOrders, showAction, toggleBySorting, onColumnToggle } = props;
   const filterTypes = React.useMemo(
     () => ({
       // Add a new fuzzyTextFilterFn filter type.
@@ -630,6 +630,7 @@ function Table({ columns, data, defaultheader, optionalheader, tablename, defaul
     []
   )
 
+  let tblinstance;
   const {
     getTableProps,
     getTableBodyProps,
@@ -650,7 +651,7 @@ function Table({ columns, data, defaultheader, optionalheader, tablename, defaul
     selectedFlatRows,
     setColumnOrder,
     exportData,
-  } = useTable(
+  } = tblinstance = useTable(
     {
       columns,
       data,
@@ -673,8 +674,8 @@ function Table({ columns, data, defaultheader, optionalheader, tablename, defaul
   );
   React.useEffect(() => {
     setHiddenColumns(
-    //  columns.filter(column => !column.isVisible).map(column => column.accessor)
-    columns.filter(column => !column.isVisible).map(column => column.id)
+      //  columns.filter(column => !column.isVisible).map(column => column.accessor)
+      columns.filter(column => !column.isVisible).map(column => column.id)
     );
     // console.log('columns List', visibleColumns.map((d) => d.id));
     if (columnOrders && columnOrders.length) {
@@ -684,7 +685,7 @@ function Table({ columns, data, defaultheader, optionalheader, tablename, defaul
         setColumnOrder(['Select', ...columnOrders]);
       }
     }
-    
+
   }, [setHiddenColumns, columns]);
 
   let op = useRef(null);
@@ -722,16 +723,32 @@ function Table({ columns, data, defaultheader, optionalheader, tablename, defaul
     setcustompagevalue();
   };
 
-  const onToggleChange = (e) => {
+  const onToggleChange = (e) => {  
+    let t = tblinstance;
     let lsToggleColumns = [];
+    let selectedColumn = null;
+    let sortedColumn = {};
     allColumns.forEach(acolumn => {
       let jsonobj = {};
       let visible = (acolumn.Header === e.target.id) ? ((acolumn.isVisible) ? false : true) : acolumn.isVisible
       jsonobj['Header'] = acolumn.Header;
       jsonobj['isVisible'] = visible;
       lsToggleColumns.push(jsonobj)
-    })
-    localStorage.setItem(tablename, JSON.stringify(lsToggleColumns))
+      selectedColumn = (acolumn.Header === e.target.id) ? jsonobj : selectedColumn;
+      if (acolumn.isSorted) {
+        sortedColumn['Header'] = acolumn.Header;
+        sortedColumn['isVisible'] = visible;
+      }
+    });
+    localStorage.setItem(tablename, JSON.stringify(lsToggleColumns));   
+    if (onColumnToggle) {
+      let columnTobeSorted = onColumnToggle(selectedColumn, sortedColumn);
+      columnTobeSorted.Header = columnTobeSorted.Header || "";
+
+      if(columnTobeSorted.Header.trim().length>0){
+        tblinstance.toggleSortBy(columnTobeSorted.Header, columnTobeSorted.desc);
+      }
+    }
   }
 
   filteredData = _.map(rows, 'values');
@@ -748,6 +765,10 @@ function Table({ columns, data, defaultheader, optionalheader, tablename, defaul
     parentCBonSelection(selectedRows)
   }
 
+  const onSortBy = () => {
+    sessionStorage.setItem("sortedData", tbldata);
+  }
+
   return (
     <>
       <div style={{ display: 'flex', justifyContent: 'space-between' }}>
@@ -773,7 +794,7 @@ function Table({ columns, data, defaultheader, optionalheader, tablename, defaul
                           <div key={column.id} style={{ 'display': column.id !== 'actionpath' ? 'block' : 'none' }}>
                             <input type="checkbox" {...column.getToggleHiddenProps()}
                               id={(defaultheader[column.id]) ? defaultheader[column.id] : (optionalheader[column.id] ? optionalheader[column.id] : column.id)}
-                              onClick={onToggleChange}
+                              onClick={(e) => onToggleChange(e)}
                             /> {
                               (defaultheader[column.id]) ? defaultheader[column.id] : (optionalheader[column.id] ? optionalheader[column.id] : column.id)}
                           </div>
@@ -827,8 +848,8 @@ function Table({ columns, data, defaultheader, optionalheader, tablename, defaul
             {headerGroups.map(headerGroup => (
               <tr {...headerGroup.getHeaderGroupProps()}>
                 {headerGroup.headers.map(column => (
-                  <th>
-                    <div {...column.getHeaderProps(column.getSortByToggleProps())}>
+                  <th onClick={() => toggleBySorting({ 'id': column.id, desc: (column.isSortedDesc != undefined ? !column.isSortedDesc : false) })}>
+                    <div {...column.getHeaderProps(column.getSortByToggleProps())} >
                       {column.Header !== 'actionpath' && column.render('Header')}
                       {column.Header !== 'Action' ?
                         column.isSorted ? (column.isSortedDesc ? <i className="pi pi-sort-down" aria-hidden="true"></i> : <i className="pi pi-sort-up" aria-hidden="true"></i>) : ""
@@ -910,7 +931,8 @@ filterGreaterThan.autoRemove = val => typeof val !== 'number'
 function ViewTable(props) {
   const history = useHistory();
   // Data to show in table
-  tbldata = props.data;
+  console.log("sessionStorage", JSON.parse(sessionStorage.getItem("sortedData")));
+  tbldata = JSON.parse(sessionStorage.getItem("sortedData")) || props.data;
   showCSV = (props.showCSV) ? props.showCSV : false;
 
   parentCallbackFunction = props.filterCallback;
@@ -932,7 +954,7 @@ function ViewTable(props) {
     defaultSortColumn = [{}];
   }
   let defaultpagesize = (typeof props.defaultpagesize === 'undefined' || props.defaultpagesize == null) ? 10 : props.defaultpagesize;
-  let columns = [];
+  let columns = [];  
   let defaultdataheader = Object.keys(defaultheader[0]);
   let optionaldataheader = Object.keys(optionalheader[0]);
 
@@ -966,16 +988,17 @@ function ViewTable(props) {
       isVisible: true,
     });
   }
-
-  if (props.showaction === 'true') {
-    columns.push({
+ 
+  if (props.showaction) {
+      columns.push({
       Header: 'Action',
       id: 'Action',
       accessor: props.keyaccessor,
       Cell: props => <button className='p-link' onClick={navigateTo(props)} ><i className="fa fa-eye" style={{ cursor: 'pointer' }}></i></button>,
       disableFilters: true,
       disableSortBy: true,
-      isVisible: defaultdataheader.includes(props.keyaccessor),
+      //isVisible: defaultdataheader.includes(props.keyaccessor),
+      isVisible:true
     })
   }
 
@@ -989,7 +1012,7 @@ function ViewTable(props) {
           }
         })
       } else {
-        window.open(cellProps.cell.row.values['actionpath'] , '_blank');
+        window.open(cellProps.cell.row.values['actionpath'], '_blank');
       }
     }
     // Object.entries(props.paths[0]).map(([key,value]) =>{})
@@ -1032,17 +1055,11 @@ function ViewTable(props) {
 
   let togglecolumns = localStorage.getItem(tablename);
   if (togglecolumns) {
-        togglecolumns = JSON.parse(togglecolumns);
-        columns.forEach(column => {
-            let tcolumn = _.find(togglecolumns, {Header: column.Header});
-            column['isVisible'] = (tcolumn)? tcolumn.isVisible: column.isVisible;
-        });
-        /*columns.forEach(column => {
-            togglecolumns.filter(tcol => {
-            column.isVisible = (tcol.Header === column.Header) ? tcol.isVisible : column.isVisible;
-            return tcol;
-        });
-      });*/
+    togglecolumns = JSON.parse(togglecolumns);
+    columns.forEach(column => {
+      let tcolumn = _.find(togglecolumns, { Header: column.Header });
+      column['isVisible'] = (tcolumn) ? tcolumn.isVisible : column.isVisible;
+    });  
   }
 
   function updatedCellvalue(key, value, properties) {
@@ -1063,13 +1080,13 @@ function ViewTable(props) {
         return retval;
       } else if (typeof value == "boolean") {
         return value.toString();
-      }else if (typeof value == "string") {
+      } else if (typeof value == "string") {
         const format = properties ? properties.format : 'YYYY-MM-DD HH:mm:ss';
         const dateval = moment(value, moment.ISO_8601).format(format);
         if (dateval !== 'Invalid date') {
           return dateval;
         }
-     }
+      }
     } catch (err) {
       console.error('Error', err)
     }
@@ -1079,7 +1096,8 @@ function ViewTable(props) {
   return (
     <div>
       <Table columns={columns} data={tbldata} defaultheader={defaultheader[0]} optionalheader={optionalheader[0]} showAction={props.showaction}
-        defaultSortColumn={defaultSortColumn} tablename={tablename} defaultpagesize={defaultpagesize} columnOrders={props.columnOrders} />
+        defaultSortColumn={defaultSortColumn} tablename={tablename} defaultpagesize={defaultpagesize} columnOrders={props.columnOrders} toggleBySorting={(sortData) => props.toggleBySorting(sortData)}
+        onColumnToggle={props.onColumnToggle} />
     </div>
   )
 }
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/list.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/list.js
index cf1858492dc..eed504c4ca7 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/list.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Cycle/list.js
@@ -8,9 +8,12 @@ import UnitConversion from '../../utils/unit.converter';
 import AppLoader from '../../layout/components/AppLoader';
 import PageHeader from '../../layout/components/PageHeader';
 import UIConstants from '../../utils/ui.constants';
+import UtilService from '../../services/util.service';
+/* eslint-disable no-unused-expressions */
 
-class CycleList extends Component{
-	 constructor(props){
+class CycleList extends Component {
+    lsTableName = "cycle_list";
+    constructor(props) {
         super(props)
         this.state = {
             cyclelist: [],
@@ -20,85 +23,92 @@ class CycleList extends Component{
             isLoading: true
         }
         this.projectCategory = ['regular', 'user_shared_support'];
-        this.periodCategory = ['long_term'];       
-        this.defaultcolumns = [ {   id:"Cycle Code",
-                                    start: {
-                                        name: "Start Date",
-                                        filter: "date",
-                                        format: UIConstants.CALENDAR_DEFAULTDATE_FORMAT
-                                    },
-                                    stop: {
-                                        name: "End Date",
-                                        filter: "date",
-                                        format: UIConstants.CALENDAR_DEFAULTDATE_FORMAT
-                                    },
-                                    duration:{
-                                        name: "Duration (Days)",
-                                        filter: "range",
-                                        format: UIConstants.CALENDAR_TIME_FORMAT
-                                    },
-                                    totalProjects:{ 
-                                        name:'No.of Projects',
-                                        filter:"range"
-                                    },
-                                    observingTime:{
-                                        name: "Lofar Observing Time (Hrs)",
-                                        filter:"range"
-                                    },
-                                    processingTime:{ 
-                                        name:"Lofar Processing Time (Hrs)",
-                                        filter:"range"
-                                    },
-                                    ltaResources: {
-                                        name:"Lofar LTA Resources(TB)",
-                                        filter:"range"
-                                    },
-                                    support:{
-                                        name:"Lofar Support (Hrs)",
-                                        filter:"range"
-                                    },
-                                    longterm : {
-                                        name:"Long Term Projects",
-                                        filter:"range"
-                                    }} ];
-        this.optionalcolumns = [{   regularProjects:{                              
-                                        name: "No.of Regular Projects",
-                                        filter:"range"
-                                    },   
-                                    observingTimeDDT:{
-                                        name: "Lofar Observing Time Commissioning (Hrs)",
-                                        filter:"range"
-                                    },
-                                    observingTimePrioA:{
-                                        name:"Lofar Observing Time Prio A (Hrs)",
-                                        filter:"range"
-                                    },
-                                    observingTimePrioB:{
-                                        name:"Lofar Observing Time Prio B (Hrs)",
-                                        filter:"range"
-                                    },
-                                    actionpath: "actionpath" }];
+        this.periodCategory = ['long_term'];
+        this.defaultcolumns = [{
+            id: "Cycle Code",
+            start: {
+                name: "Start Date",
+                filter: "date",
+                format: UIConstants.CALENDAR_DEFAULTDATE_FORMAT
+            },
+            stop: {
+                name: "End Date",
+                filter: "date",
+                format: UIConstants.CALENDAR_DEFAULTDATE_FORMAT
+            },
+            duration: {
+                name: "Duration (Days)",
+                filter: "range",
+                format: UIConstants.CALENDAR_TIME_FORMAT
+            },
+            totalProjects: {
+                name: 'No.of Projects',
+                filter: "range"
+            },
+            observingTime: {
+                name: "Lofar Observing Time (Hrs)",
+                filter: "range"
+            },
+            processingTime: {
+                name: "Lofar Processing Time (Hrs)",
+                filter: "range"
+            },
+            ltaResources: {
+                name: "Lofar LTA Resources(TB)",
+                filter: "range"
+            },
+            support: {
+                name: "Lofar Support (Hrs)",
+                filter: "range"
+            },
+            longterm: {
+                name: "Long Term Projects",
+                filter: "range"
+            }
+        }];
+        this.optionalcolumns = [{
+            regularProjects: {
+                name: "No.of Regular Projects",
+                filter: "range"
+            },
+            observingTimeDDT: {
+                name: "Lofar Observing Time Commissioning (Hrs)",
+                filter: "range"
+            },
+            observingTimePrioA: {
+                name: "Lofar Observing Time Prio A (Hrs)",
+                filter: "range"
+            },
+            observingTimePrioB: {
+                name: "Lofar Observing Time Prio B (Hrs)",
+                filter: "range"
+            },
+            actionpath: "actionpath"
+        }];
 
-        this.columnclassname = [{   "Cycle Code":"filter-input-75",
-                                    "Duration (Days)" : "filter-input-50",
-                                    "No.of Projects" : "filter-input-50",
-                                    "Lofar Observing Time (Hrs)" : "filter-input-75",
-                                    "Lofar Processing Time (Hrs)" : "filter-input-75",
-                                    "Lofar LTA Resources(TB)" : "filter-input-75",
-                                    "Lofar Support (Hrs)" : "filter-input-50",
-                                    "Long Term Projects" : "filter-input-50",
-                                    "No.of Regular Projects" : "filter-input-50",
-                                    "Lofar Observing Time Commissioning (Hrs)" : "filter-input-75",
-                                    "Lofar Observing Time Prio A (Hrs)" : "filter-input-75",
-                                    "Lofar Observing Time Prio B (Hrs)" : "filter-input-75" }];
-                                                                         
-      //  this.defaultSortColumn = [{id: "Cycle Code", desc: false}];  
-         this.defaultSortColumn = [{name: "Start Date", desc: true}];                         
+        this.columnclassname = [{
+            "Cycle Code": "filter-input-75",
+            "Duration (Days)": "filter-input-50",
+            "No.of Projects": "filter-input-50",
+            "Lofar Observing Time (Hrs)": "filter-input-75",
+            "Lofar Processing Time (Hrs)": "filter-input-75",
+            "Lofar LTA Resources(TB)": "filter-input-75",
+            "Lofar Support (Hrs)": "filter-input-50",
+            "Long Term Projects": "filter-input-50",
+            "No.of Regular Projects": "filter-input-50",
+            "Lofar Observing Time Commissioning (Hrs)": "filter-input-75",
+            "Lofar Observing Time Prio A (Hrs)": "filter-input-75",
+            "Lofar Observing Time Prio B (Hrs)": "filter-input-75"
+        }];
+
+        this.defaultSortColumn = [{ id: "Start Date", desc: true }];
+        this.toggleBySorting = this.toggleBySorting.bind(this);
+        this.setToggleBySorting = this.setToggleBySorting.bind(this);
     }
     getUnitConvertedQuotaValue(cycle, cycleQuota, resourceName) {
-        const quota = _.find(cycleQuota, {'cycle_id': cycle.name, 'resource_type_id': resourceName});
+        const quota = _.find(cycleQuota, { 'cycle_id': cycle.name, 'resource_type_id': resourceName });
         const unitQuantity = this.state.resources.find(i => i.name === resourceName).quantity_value;
-        return UnitConversion.getUIResourceUnit(unitQuantity, quota?quota.value:0);
+        return UnitConversion.getUIResourceUnit(unitQuantity, quota ? quota.value : 0);
     }
     getCycles(cycles = [], cycleQuota) {
         const promises = [];
@@ -111,7 +121,7 @@ class CycleList extends Component{
                 const longterm = projects.filter(project => this.periodCategory.includes(project.period_category_value));
                 cycle.duration = UnitConversion.getUIResourceUnit('days', cycle.duration);
                 cycle.totalProjects = cycle.projects ? cycle.projects.length : 0;
-                cycle.id = cycle.name ;
+                cycle.id = cycle.name;
                 cycle.regularProjects = regularProjects.length;
                 cycle.longterm = longterm.length;
                 cycle.observingTime = this.getUnitConvertedQuotaValue(cycle, cycleQuota, 'LOFAR Observing Time');
@@ -121,18 +131,17 @@ class CycleList extends Component{
                 cycle.observingTimeDDT = this.getUnitConvertedQuotaValue(cycle, cycleQuota, 'LOFAR Observing Time Commissioning');
                 cycle.observingTimePrioA = this.getUnitConvertedQuotaValue(cycle, cycleQuota, 'LOFAR Observing Time prio A');
                 cycle.observingTimePrioB = this.getUnitConvertedQuotaValue(cycle, cycleQuota, 'LOFAR Observing Time prio B');
-                
                 cycle['actionpath'] = `/cycle/view/${cycle.id}`;
                 return cycle;
             });
             this.setState({
-                cyclelist : results,
+                cyclelist: results,
                 isLoading: false
             });
         });
     }
 
-    componentDidMount(){ 
+    componentDidMount() {
         const promises = [CycleService.getAllCycleQuotas(), CycleService.getResources()]
         Promise.all(promises).then(responses => {
             const cycleQuota = responses[0];
@@ -140,13 +149,46 @@ class CycleList extends Component{
             CycleService.getAllCycles().then(cyclelist => {
                 this.getCycles(cyclelist, cycleQuota)
             });
-        });  
+        });
+        this.setToggleBySorting();
+    }
+
+    setToggleBySorting() {      
+        let sortData = UtilService.localStore({ type: 'get', key: 'cycleSortData' });
+        this.defaultSortColumn = this.defaultSortColumn || [];
+        sortData ? this.defaultSortColumn = [{ ...sortData }] : UtilService.localStore({ type: 'set', key: 'cycleSortData', value: [...this.defaultSortColumn] });
+    }
+
+    toggleBySorting(sortData) {     
+        UtilService.localStore({ type: 'set', key: 'cycleSortData', value: sortData });
+    }
+
+    getFirstVisibleColumn = () => {        
+        const columns = UtilService.localStore({ type: 'get', key: this.lsTableName });
+        let selected = {};
+        for (let i = 0; i < columns.length; i++) {
+            if (columns[i].Header.toLowerCase() !== 'action' && columns[i].isVisible) {
+                selected = columns[i];
+                break;
+            }
+        }        
+        return selected;
     }
-	
-	render(){
+
+    onColumnToggle = (selectedColumn, sortedColumn) => {      
+        let visibleColumn = {};
+        if (selectedColumn.Header === sortedColumn.Header && !selectedColumn.isVisible) {
+            visibleColumn = this.getFirstVisibleColumn();
+            localStorage.setItem('cycleSortData', JSON.stringify(this.defaultSortColumn));
+        }
+        visibleColumn.Header = visibleColumn.Header || "";
+        return { Header: visibleColumn.Header, desc: visibleColumn.Header.toLowerCase() === 'start date'? true:false };
+    }
+
+    render() {
         return (
             <>
-           { /*<div className="p-grid">
+                { /*<div className="p-grid">
                     <div className="p-col-10 p-lg-10 p-md-10">
                         <h2>Cycle - List </h2>
                     </div>
@@ -163,7 +205,7 @@ class CycleList extends Component{
                     showaction - {true/false} -> to show the action column
                     paths - specify the path for navigation - Table will set "id" value for each row in action button
                 */}
-                <PageHeader location={this.props.location} title={'Cycle - List'} actions={[{icon:'fa-plus-square',title:'Click to Add Cycle', props:{ pathname: '/cycle/create'}}]}/>
+                <PageHeader location={this.props.location} title={'Cycle - List'} actions={[{ icon: 'fa-plus-square', title: 'Click to Add Cycle', props: { pathname: '/cycle/create' } }]} />
                 {/*
                     * Call View table to show table data, the parameters are,
                     data - Pass API data
@@ -171,27 +213,25 @@ class CycleList extends Component{
                     showaction - {true/false} -> to show the action column
                     paths - specify the path for navigation - Table will set "id" value for each row in action button
                 */}
-                 
-                {this.state.isLoading? <AppLoader /> : (this.state.cyclelist && this.state.cyclelist.length) ?
-                
-                    <ViewTable 
-                        data={this.state.cyclelist} 
-                        defaultcolumns={this.defaultcolumns} 
+
+                {this.state.isLoading ? <AppLoader /> : (this.state.cyclelist && this.state.cyclelist.length) ?
+
+                    <ViewTable
+                        data={this.state.cyclelist}
+                        defaultcolumns={this.defaultcolumns}
                         optionalcolumns={this.optionalcolumns}
-                        columnclassname = {this.columnclassname}
-                        defaultSortColumn= {this.defaultSortColumn}
-                        showaction="true"
+                        columnclassname={this.columnclassname}
+                        defaultSortColumn={this.defaultSortColumn}
+                        showaction={true}
                         paths={this.state.paths}
-                        tablename="cycle_list"
-                 />  : <></>
-                 } 
-                
-
-                
+                        tablename={this.lsTableName}
+                        toggleBySorting={(sortData) => this.toggleBySorting(sortData)}
+                        onColumnToggle={this.onColumnToggle}
+                    /> : <></>
+                }
             </>
         )
     }
 }
 
-export default CycleList
-
+export default CycleList
\ No newline at end of file
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/list.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/list.js
index 3a36213f676..d1200792127 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/list.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/list.js
@@ -1,114 +1,119 @@
-import React, {Component} from 'react';
+import React, { Component } from 'react';
 import ProjectService from '../../services/project.service';
 import ViewTable from '../../components/ViewTable';
 import AppLoader from '../../layout/components/AppLoader';
 import PageHeader from '../../layout/components/PageHeader';
 import CycleService from '../../services/cycle.service';
+import UtilService from '../../services/util.service';
+/* eslint-disable no-unused-expressions */
 
-export class ProjectList extends Component{
-    constructor(props){
+export class ProjectList extends Component {
+    lsTableName = 'project_list';
+    constructor(props) {
         super(props)
         this.state = {
             projectlist: [],
-            defaultcolumns: [ {
-                name:"Name / Project Code",
-                status:{
-                    name:"Status",
-                    filter:"select"
+            defaultcolumns: [{
+                name: "Name / Project Code",
+                status: {
+                    name: "Status",
+                    filter: "select"
                 },
-                project_category_value:{
-                    name:"Category of Project",
-                    filter:"select"
+                project_category_value: {
+                    name: "Category of Project",
+                    filter: "select"
                 },
-                description:"Description",
-                archive_location_label:{
-                    name:"LTA Storage Location",
-                    filter:"select"
+                description: "Description",
+                archive_location_label: {
+                    name: "LTA Storage Location",
+                    filter: "select"
                 },
-                archive_subdirectory:"LTA Storage Path",
-             }],
-            optionalcolumns:  [{
-                priority_rank:{
-                    name:"Project Priority", 
-                    filter:"range"
+                archive_subdirectory: "LTA Storage Path",
+            }],
+            optionalcolumns: [{
+                priority_rank: {
+                    name: "Project Priority",
+                    filter: "range"
                 },
-                trigger_priority:{
-                    name:"Trigger Priority",
-                    filter:"range"
+                trigger_priority: {
+                    name: "Trigger Priority",
+                    filter: "range"
                 },
-                period_category_value:{
-                    name:"Category of Period",
-                    filter:"select"
+                period_category_value: {
+                    name: "Category of Period",
+                    filter: "select"
                 },
-                cycles_ids:{
-                    name:"Cycles",
-                    filter:"select"
+                cycles_ids: {
+                    name: "Cycles",
+                    filter: "select"
                 },
-                can_trigger:{
-                    name:"Trigger Allowed",
-                    filter:"switch"
+                can_trigger: {
+                    name: "Trigger Allowed",
+                    filter: "switch"
                 },
-                LOFAR_Observing_Time:{
-                    name:"Observing time (Hrs)",
-                    filter:"range"
+                LOFAR_Observing_Time: {
+                    name: "Observing time (Hrs)",
+                    filter: "range"
                 },
-                LOFAR_Observing_Time_prio_A:{
-                    name:"Observing time prio A (Hrs)",
-                    filter:"range"
+                LOFAR_Observing_Time_prio_A: {
+                    name: "Observing time prio A (Hrs)",
+                    filter: "range"
                 },
-                LOFAR_Observing_Time_prio_B:{
-                    name:"Observing time prio B (Hrs)",
-                    filter:"range"
+                LOFAR_Observing_Time_prio_B: {
+                    name: "Observing time prio B (Hrs)",
+                    filter: "range"
                 },
-                CEP_Processing_Time:{
-                    name:"Processing time (Hrs)",
-                    filter:"range"
+                CEP_Processing_Time: {
+                    name: "Processing time (Hrs)",
+                    filter: "range"
                 },
-                LTA_Storage:{
-                    name:"LTA storage (TB)",
-                    filter:"range"
+                LTA_Storage: {
+                    name: "LTA storage (TB)",
+                    filter: "range"
                 },
-                Number_of_triggers:{
-                    name:"Number of Triggers",
-                    filter:"range"
+                Number_of_triggers: {
+                    name: "Number of Triggers",
+                    filter: "range"
                 },
-                auto_pin:{
-                    name:"Prevent automatic deletion after ingest",
-                    filter:"switch"
+                auto_pin: {
+                    name: "Prevent automatic deletion after ingest",
+                    filter: "switch"
                 },
-                actionpath:"actionpath"
-               
+                actionpath: "actionpath"
+
             }],
             columnclassname: [{
-                "Observing time (Hrs)":"filter-input-50",
-                "Observing time prio A (Hrs)":"filter-input-50",
-                "Observing time prio B (Hrs)":"filter-input-50",
-                "Processing time (Hrs)":"filter-input-50",
-                "LTA storage (TB)":"filter-input-50",
-                "Status":"filter-input-50",
-                "Trigger Allowed":"filter-input-50",
-                "Number of Triggers":"filter-input-50",
-                "Project Priority":"filter-input-50",
-                "Trigger Priority":"filter-input-50",
-                "Category of Period":"filter-input-50",
-                "Cycles":"filter-input-100",
-                "LTA Storage Location":"filter-input-100",
-                "LTA Storage Path":"filter-input-100"
+                "Observing time (Hrs)": "filter-input-50",
+                "Observing time prio A (Hrs)": "filter-input-50",
+                "Observing time prio B (Hrs)": "filter-input-50",
+                "Processing time (Hrs)": "filter-input-50",
+                "LTA storage (TB)": "filter-input-50",
+                "Status": "filter-input-50",
+                "Trigger Allowed": "filter-input-50",
+                "Number of Triggers": "filter-input-50",
+                "Project Priority": "filter-input-50",
+                "Trigger Priority": "filter-input-50",
+                "Category of Period": "filter-input-50",
+                "Cycles": "filter-input-100",
+                "LTA Storage Location": "filter-input-100",
+                "LTA Storage Path": "filter-input-100"
             }],
-            defaultSortColumn: [{id: "Name / Project Code", desc: false}],
+            defaultSortColumn: [{ id: "Name / Project Code", desc: false }],
             isprocessed: false,
             isLoading: true
         }
         this.getPopulatedProjectList = this.getPopulatedProjectList.bind(this);
+        this.toggleBySorting = this.toggleBySorting.bind(this);
+        this.setToggleBySorting = this.setToggleBySorting.bind(this);
     }
 
     getPopulatedProjectList(cycleId) {
-        Promise.all([ProjectService.getFileSystem(), ProjectService.getCluster()]).then(async(response) => {
+        Promise.all([ProjectService.getFileSystem(), ProjectService.getCluster()]).then(async (response) => {
             const options = {};
             response[0].map(fileSystem => {
-                const cluster =  response[1].filter(clusterObj => { return (clusterObj.id === fileSystem.cluster_id && clusterObj.archive_site);});
+                const cluster = response[1].filter(clusterObj => { return (clusterObj.id === fileSystem.cluster_id && clusterObj.archive_site); });
                 if (cluster.length) {
-                    fileSystem.label =`${cluster[0].name} - ${fileSystem.name}`
+                    fileSystem.label = `${cluster[0].name} - ${fileSystem.name}`
                     options[fileSystem.url] = fileSystem;
                 }
                 return fileSystem;
@@ -116,7 +121,7 @@ export class ProjectList extends Component{
             let projects = [];
             if (cycleId) {
                 projects = await CycleService.getProjectsByCycle(cycleId);
-            }   else {
+            } else {
                 projects = await ProjectService.getProjectList();
             }
             projects = await ProjectService.getUpdatedProjectQuota(projects);
@@ -133,16 +138,51 @@ export class ProjectList extends Component{
         });
     }
 
-    componentDidMount(){  
+    componentDidMount() {
         // Show Project for the Cycle, This request will be coming from Cycle View. Otherwise it is consider as normal Project List.
         let cycle = this.props.cycle;
         this.getPopulatedProjectList(cycle);
+        this.setToggleBySorting();
+    }
+
+    setToggleBySorting() {        
+        let sortData = UtilService.localStore({ type: 'get', key: 'proSortData' });
+        this.defaultSortColumn = this.defaultSortColumn || [];
+        sortData ? this.setState({ defaultSortColumn: [{ ...sortData }] }) : UtilService.localStore({ type: 'set', key: 'proSortData', value: [...this.defaultSortColumn] });
+    }
+
+    toggleBySorting(sortData) {
+        UtilService.localStore({ type: 'set', key: 'proSortData', value: sortData });
+    }
+
+    getFirstVisibleColumn = () => {
+        //localStorage.setItem(tablename, JSON.stringify(lsToggleColumns));
+        const columns = UtilService.localStore({ type: 'get', key: this.lsTableName });
+        let selected = {};
+        for (let i = 0; i < columns.length; i++) {
+
+            if (columns[i].Header.toLowerCase() !== 'action' && columns[i].isVisible) {
+                selected = columns[i];
+                break;
+            }
+        }      
+        return selected;
     }
-   
-    render(){
-        return(
+
+    onColumnToggle = (selectedColumn, sortedColumn) => {    
+        let visibleColumn = {};
+        if (selectedColumn.Header === sortedColumn.Header && !selectedColumn.isVisible) {
+            visibleColumn = this.getFirstVisibleColumn();
+            localStorage.setItem('proSortData', JSON.stringify(this.defaultSortColumn));
+        }
+        visibleColumn.Header = visibleColumn.Header || "";
+        return { Header: visibleColumn.Header, desc: false };
+    }
+
+    render() {
+        return (
             <>
-               {/*<div className="p-grid">
+                {/*<div className="p-grid">
                     <div className="p-col-10 p-lg-10 p-md-10">
                         <h2>Project - List </h2>
                     </div>
@@ -152,27 +192,29 @@ export class ProjectList extends Component{
                         </Link>
                     </div>
                 </div> */}
-              { (this.props.cycle) ? 
-                <>
-                </>
-                :
-                <PageHeader location={this.props.location} title={'Project - List'} 
-                actions={[{icon: 'fa-plus-square',title:'Click to Add Project', props:{pathname: '/project/create' }}]}
-                />
-               }
-                {this.state.isLoading? <AppLoader /> : (this.state.isprocessed && this.state.projectlist.length>0) ?
-                    <ViewTable 
-                        data={this.state.projectlist} 
-                        defaultcolumns={this.state.defaultcolumns} 
+                { (this.props.cycle) ?
+                    <>
+                    </>
+                    :
+                    <PageHeader location={this.props.location} title={'Project - List'}
+                        actions={[{ icon: 'fa-plus-square', title: 'Click to Add Project', props: { pathname: '/project/create' } }]}
+                    />
+                }
+                {this.state.isLoading ? <AppLoader /> : (this.state.isprocessed && this.state.projectlist.length > 0) ?
+                    <ViewTable
+                        data={this.state.projectlist}
+                        defaultcolumns={this.state.defaultcolumns}
                         optionalcolumns={this.state.optionalcolumns}
                         columnclassname={this.state.columnclassname}
                         defaultSortColumn={this.state.defaultSortColumn}
-                        showaction="true"
+                        showaction={true}
                         paths={this.state.paths}
                         keyaccessor="name"
                         unittest={this.state.unittest}
-                        tablename="project_list"
-                    />
+                        tablename={this.lsTableName}
+                        toggleBySorting={(sortData) => this.toggleBySorting(sortData)}
+                        onColumnToggle={this.onColumnToggle}
+                    />                   
                     : <div>No project found </div>
                 }
             </>
@@ -180,10 +222,11 @@ export class ProjectList extends Component{
     }
 
     // Set table data for Unit test
-    unittestDataProvider(){
-        if(this.props.testdata){
+    unittestDataProvider() {
+        if (this.props.testdata) {
             this.setState({
-                projectlist: [{can_trigger: true,
+                projectlist: [{
+                    can_trigger: true,
                     created_at: "2020-07-27T01:29:57.348499",
                     cycles: ["http://localhost:3000/api/cycle/Cycle%204/"],
                     cycles_ids: ["Cycle 4"],
@@ -194,16 +237,16 @@ export class ProjectList extends Component{
                     observing_time: "155852.10",
                     priority_rank: 10,
                     private_data: true,
-                    project_quota:   ["http://localhost:3000/api/project_quota/6/", "http://localhost:3000/api/project_quota/7/"],
-                    project_quota_ids:   [6, 7],
+                    project_quota: ["http://localhost:3000/api/project_quota/6/", "http://localhost:3000/api/project_quota/7/"],
+                    project_quota_ids: [6, 7],
                     tags: ["Lofar TMSS Project"],
                     trigger_priority: 20,
                     triggers_allowed: "56",
                     updated_at: "2020-07-27T01:29:57.348522",
                     url: "http://localhost:3000/api/project/Lofar-TMSS-Commissioning/"
-                    }],
-                    isprocessed: true,
-                    unittest: true,
+                }],
+                isprocessed: true,
+                unittest: true,
             })
         }
     }
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 036165fc713..012b0d7cee1 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/services/util.service.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/services/util.service.js
@@ -161,7 +161,18 @@ const UtilService = {
           schema["items"] = resolvedItems;
       }
       return schema;
-  }
+  },
+  localStore:function(data){
+    debugger;
+    const {type,key,value}=data;
+    if(type=='set'){
+      localStorage.setItem(key,JSON.stringify(value));
+    }else if(type=='get'){
+      return JSON.parse(localStorage.getItem(key));
+    }else if(type=='remove'){
+      localStorage.removeItem(key);
+    }
+}
 }
 
 export default UtilService;
\ No newline at end of file
-- 
GitLab