Skip to content
Snippets Groups Projects
Select Git revision
  • master default protected
  • L2SS-1914-fix_job_dispatch
  • TMSS-3170
  • TMSS-3167
  • TMSS-3161
  • TMSS-3158-Front-End-Only-Allow-Changing-Again
  • TMSS-3133
  • TMSS-3319-Fix-Templates
  • test-fix-deploy
  • TMSS-3134
  • TMSS-2872
  • defer-state
  • add-custom-monitoring-points
  • TMSS-3101-Front-End-Only
  • TMSS-984-choices
  • SDC-1400-Front-End-Only
  • TMSS-3079-PII
  • TMSS-2936
  • check-for-max-244-subbands
  • TMSS-2927---Front-End-Only-PXII
  • Before-Remove-TMSS
  • LOFAR-Release-4_4_318 protected
  • LOFAR-Release-4_4_317 protected
  • LOFAR-Release-4_4_316 protected
  • LOFAR-Release-4_4_315 protected
  • LOFAR-Release-4_4_314 protected
  • LOFAR-Release-4_4_313 protected
  • LOFAR-Release-4_4_312 protected
  • LOFAR-Release-4_4_311 protected
  • LOFAR-Release-4_4_310 protected
  • LOFAR-Release-4_4_309 protected
  • LOFAR-Release-4_4_308 protected
  • LOFAR-Release-4_4_307 protected
  • LOFAR-Release-4_4_306 protected
  • LOFAR-Release-4_4_304 protected
  • LOFAR-Release-4_4_303 protected
  • LOFAR-Release-4_4_302 protected
  • LOFAR-Release-4_4_301 protected
  • LOFAR-Release-4_4_300 protected
  • LOFAR-Release-4_4_299 protected
40 results

ViewTable.js

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    ViewTable.js 91.27 KiB
    import React, { useRef, useState } from "react";
    import {  useFlexLayout , useResizeColumns, useSortBy, useTable, useFilters, useGlobalFilter, useAsyncDebounce, usePagination, useRowSelect, useColumnOrder } from 'react-table'
    import matchSorter from 'match-sorter'
    import _, { filter } from 'lodash';
    import moment from 'moment';
    import { useHistory } from "react-router-dom";
    import { OverlayPanel } from 'primereact/overlaypanel';
    import { InputMask } from 'primereact/inputmask';
    import { InputText } from 'primereact/inputtext';
    import { Calendar } from 'primereact/calendar';
    import { Paginator } from 'primereact/paginator';
    import { TriStateCheckbox } from 'primereact/tristatecheckbox';
    import { Slider } from 'primereact/slider';
    import { Button } from "react-bootstrap";
    import { Link } from "react-router-dom";
    import { InputNumber } from "primereact/inputnumber";
    import { MultiSelect } from 'primereact/multiselect';
    import { RadioButton } from 'primereact/radiobutton';
    import { useExportData } from "react-table-plugins";
    import { ProgressBar } from 'primereact/progressbar';
    
    import "flatpickr/dist/flatpickr.css";
    import Flatpickr from "react-flatpickr";
    import confirmDatePlugin from "flatpickr/dist/plugins/confirmDate/confirmDate";
    import shortcutButtonsPlugin from "shortcut-buttons-flatpickr";
    import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
    import UtilService from '../../src/services/util.service'
    import Papa from "papaparse";
    import JsPDF from "jspdf";
    import "jspdf-autotable";
    import TableUtil from "../utils/table.util";
    import Validator from  "../utils/validator"
    
    let doServersideFilter = false;
    let tbldata = [], filteredData = [];
    let data = [];
    let selectedRows = [];
    let isunittest = false;
    let showTopTotal = true;
    let showGlobalFilter = true;
    let showColumnFilter = true;
    let allowColumnSelection = true;
    let allowRowSelection = false;
    let columnclassname = [];
    let parentCallbackFunction, parentCBonSelection;
    let showCSV = false;
    let multiSelectOption = {};
    let filterCallback = null;
    let tableOptionsState = null;
    let tableToolTipsState = {};
    let setLoaderFunction = null;
    let showFilterOption = null;
    let hasFilters = false;
    let loadingStatus = false;
    let tmpTableData = null;
    let currentTableName = null;
    let storeFilter = false;
    let storage_array = [];
    let dragged = null;
    let reorder = [];
    //let confirmDatePlugin = new confirmDatePlugin();
    // Define a default UI for filtering
    
    const getItemStyle = ({ isDragging, isDropAnimating }, draggableStyle) => ({
      ...draggableStyle,
      // some basic styles to make the items look a bit nicer
      userSelect: "none",
      cursor: isDragging? 'move': 'move',
      ...(!isDragging && { transform: "translate(0,0)" }),
      ...(isDropAnimating && { transitionDuration: "0.001s" })
    
      // styles we need to apply on draggables
    });
    
    function GlobalFilter({
      preGlobalFilteredRows,
      globalFilter,
      setGlobalFilter,
    }) {
      const [value, setValue] = React.useState(globalFilter)
      const onChange = useAsyncDebounce(value => { setGlobalFilter(value || undefined) }, 200)
      return (
        <span style={{ marginLeft: "-10px" }}>
          <input
            value={value || ""}
            onChange={e => {
              setValue(e.target.value);
              onChange(e.target.value);
            }}
          /> {" "}<i className="fa fa-search"></i>
        </span>
      )
    }
    
    // Define a default UI for filtering
    function DefaultColumnFilter({
      column: { filterValue, preFilteredRows, setFilter, filteredRows, Header },
    }) {
      const [value, setValue] = useState('');
      const [filtered, setFiltered] = useState(false);
      React.useEffect(() => {
        if (!filterValue && value) {
          setValue('');     
        }
        if (storeFilter) {
          const filterValue = TableUtil.getFilter(currentTableName, Header);
          if (filterValue) {
              setFiltered(true);
          }
          if(!value){
              setValue(filterValue);
              setFilter(filterValue);
          }
        }
      }, [filterValue, value]); 
      
      // Function to call the server side filtering
      const callServerFilter = (event, isCleared) => {
          hasFilters = true;
          if (isCleared) {
              hasFilters = false;
              if (filtered) {
                  _.remove(tableOptionsState.filters, function(filter) { return filter.id === Header });
                  filterCallback(tableOptionsState, setLoaderFunction);
              }
          }   else {
              filterCallback(tableOptionsState, setLoaderFunction);
          }
      }; 
      return (
        <>
            <div className="table-filter" onClick={e => { e.stopPropagation() }} style={{marginRight: '5px'}}>
                <input 
                  title={(tableToolTipsState[Header])?tableToolTipsState[Header]:"Enter few characters and press ‘Enter’ key to search"}
                  value={value}   //***TO REMOVE - INCOMING CHANGE WAS value={filterValue || ''}
                  onChange={e => {
                    setValue(e.target.value);
                    setFilter(e.target.value || undefined) // Set undefined to remove the filter entirely
                    if(storeFilter) {
                      TableUtil.saveFilter(currentTableName, Header, e.target.value);
                    }
                  }}
                  onKeyUp={(e) => {
                    if (e.key === "Enter" && doServersideFilter) {
                      setFiltered(true);
                      callServerFilter(e);
                    }
                  }}
                />
                {value && 
                  <i className="table-reset fa fa-times" style={{cursor: 'pointer'}}
                    title="Clear the filter"
                    onClick={(e) => {
                      setFilter(undefined); setValue(''); setFiltered(false);
                      if (doServersideFilter) {
                        setFilter(undefined); 
                        setValue('');
                        callServerFilter(e, true);
                      }
                      if(storeFilter){
                        TableUtil.saveFilter(currentTableName, Header, '');
                      }
                    }} />
                }
            </div>
                  
          </>
      )
    }
    
    const setStoreData = (id, value) => { 
      debugger
      let localstorage_key = window.location.pathname.split('/')[1];
      let storage =  UtilService.localStore({ type: 'get', key: localstorage_key }); 
      if(storage && storage.length > 0) {
                  storage.forEach(function(value, index) {
                    if(value.name === id) {
                      value.name =  id
                      value.value = value
                    }
                  });
                  const selected = _.filter(storage, function (filter) {
                    if ( filter.name === id) {
                      return true;
                    }
                  })
                  if(selected.length <= 0) {
                    storage.push({name: id, value: value})
                  }
                } else {
                  storage = [{name: id, value: value}]
                }
                UtilService.localStore({ type: 'set', key: localstorage_key, value: storage });
    }
    
    
    /* 
    Generate and download csv 
    */
    function getExportFileBlob({ columns, data, fileType, fileName }) {
      if (fileType === "csv") {
        // CSV download
        const headerNames = columns.map((col) => col.exportValue);
        // remove actionpath column in csv export
        var index = headerNames.indexOf('actionpath');
        if (index > -1) {
          headerNames.splice(index, 1);
        }
        const csvString = Papa.unparse({ fields: headerNames, data });
        return new Blob([csvString], { type: "text/csv" });
      } //PDF download
      else if (fileType === "pdf") {
        const headerNames = columns.map((column) => column.exportValue);
        const doc = new JsPDF();
        var index = headerNames.indexOf('Action');
        if (index > -1) {
          headerNames.splice(index, 1);
        }
        doc.autoTable({
          head: [headerNames],
          body: data,
        });
        doc.save(`${fileName}.pdf`);
        return false;
      }
    }
    
    /**
     * Custom filter UI for selecting a unique option from a list.
     * option values are getting from  callback funtion or from the table data.
     * @param {*} param0 
     * @returns 
     */
    function SelectColumnFilter({
      column: { filterValue, setFilter, preFilteredRows, id, Header },
    }) {
      const [value, setValue] = useState('');
      const [filtered, setFiltered] = useState(false);
      const [rowData, setRowData] = useState(null);
      React.useEffect(() => {
        if (!filterValue && value) {
          setValue('');
        }
        if (storeFilter) {
          const filterValue = TableUtil.getFilter(currentTableName, Header);
          setValue(filterValue);
          setFilter(filterValue);
        }
      }, [filterValue, value]);
    
      const options = React.useMemo(() => {
        let options = null;
        if (showFilterOption) {
          options = new Set(showFilterOption(id));
        } 
        if (options === null || options.size === 0) {
          options = new Set();
          if (preFilteredRows || rowData) {
              preFilteredRows = preFilteredRows ? preFilteredRows : rowData;
              setRowData(preFilteredRows);
              preFilteredRows.forEach(row => {
                options.add(row.values[id])
              });
          }
        } 
        return [...options.values()]
      }, [id, preFilteredRows]);
    
      // Function to call the server side filtering
      const callServerFilter = (event, isCleared) => {
        hasFilters = true;
        _.remove(tableOptionsState.filters, function(filter) { return filter.id === Header });
        if (isCleared) {
            hasFilters = false;
            //if (filtered) {
                filterCallback(tableOptionsState, setLoaderFunction);
            //}
        }   else {
            tableOptionsState.filters.push({id: Header, value: event.target.value});
            filterCallback(tableOptionsState, setLoaderFunction);
        }
      };
    
      // Render a multi-select box
      return (
        <div onClick={e => { e.stopPropagation() }}>
          <select
            title={(tableToolTipsState[Header])?tableToolTipsState[Header]:"Select a value from list to search"}
            // className= {columnclassname[0][Header]}
            style={{
              height: '24.2014px',
              border: '1px solid lightgrey',
            }}
            value={value}
            onChange={e => {
              setValue(e.target.value);
              setFilter(e.target.value || undefined);
              if (doServersideFilter) {
                if (e.target.value === '' || e.target.value === 'All') {
                  hasFilters = false;
                  setFiltered(false);
                  setFilter(undefined); 
                  setValue('');
                  callServerFilter(e, true);
                } else {
                  setFiltered(true);
                  callServerFilter(e, false);
                }
              }
              if(storeFilter) {
                TableUtil.saveFilter(currentTableName, Header, e.target.value);
              }
            }}
          >
            <option value="">All</option>
            {options.map((option, i) => (
              <option key={i} value={option}>
                {_.startCase(option)}
              </option>
            ))}
          </select>
        </div>
      )
    }
    
    // Multi-Select Custom Filter and set unique options value
    function MultiSelectColumnFilter({
      column: { filterValue, setFilter, preFilteredRows, id, Header },
    }) {
      const [value, setValue] = useState('');
      const [filtertype, setFiltertype] = useState('Any');
      // Set Any / All Filter type
      const setSelectTypeOption = (option) => {
        setFiltertype(option);
        multiSelectOption[Header] = option
        if (value !== '') {
          if (storeFilter) {
            TableUtil.saveFilter(currentTableName, `${Header}-FilterOption`, option);
          }
          setFilter(value);
        }
      };
    
      React.useEffect(() => {
        if (!filterValue && value) {
          setValue('');
          setFiltertype('Any');
        }
        if (storeFilter) {
          const filterValue = TableUtil.getFilter(currentTableName, Header);
          const filterType = TableUtil.getFilter(currentTableName, `${Header}-FilterOption`);
          if(filterValue && !value){
            setValue(filterValue);
            setFilter(filterValue);
            setFiltertype(filterType);
            multiSelectOption[Header] = filterType;
          }
        }
      }, [filterValue, value, filtertype]);
    
      multiSelectOption[Header] = filtertype;
      const options = React.useMemo(() => {
        let options = new Set();
        if (showFilterOption) {
          return showFilterOption(id);
        } 
        preFilteredRows.forEach(row => {
          row.values[id].split(',').forEach(value => {
            if (value !== '') {
              let hasValue = false;
              options.forEach(option => {
                if (option.name === value) {
                  hasValue = true;
                }
              });
              if (!hasValue) {
                let option = { 'name': value, 'value': value };
                options.add(option);
              }
            }
          });
        });
        return [...options.values()]
      }, [id, preFilteredRows]);
    
      // Render a multi-select box
      return (
        <div onClick={e => { e.stopPropagation() }} >
          <div className="p-field-radiobutton">
            <RadioButton inputId="filtertype1" name="filtertype" value="Any" onChange={(e) => setSelectTypeOption(e.value)} checked={filtertype === 'Any'} />
            <label htmlFor="filtertype1">Any</label>
          </div>
          <div className="p-field-radiobutton">
            <RadioButton inputId="filtertype2" name="filtertype" value="All" onChange={(e) => setSelectTypeOption(e.value)} checked={filtertype === 'All'} />
            <label htmlFor="filtertype2">All</label>
          </div>
          <div style={{ position: 'relative' }} >
            <MultiSelect data-testid="multi-select" id="multi-select" optionLabel="value" optionValue="value" filter={true}
              value={value}
              options={options}
              onChange={e => {
                setValue(e.target.value);
                setFilter(e.target.value || undefined);
                setFiltertype(filtertype);
                if(storeFilter) {
                  if (e.target.value.length > 0) {
                    TableUtil.saveFilter(currentTableName, Header, e.target.value);
                    TableUtil.saveFilter(currentTableName, `${Header}-FilterOption`, filtertype);
                  } else {
                    TableUtil.clearColumnFilter(currentTableName, Header);
                    TableUtil.clearColumnFilter(currentTableName, `${Header}-FilterOption`);
                  }
                }
              }}
              maxSelectedLabels="1"
              selectedItemsLabel="{0} Selected"
              className="multi-select"
              tooltip={(tableToolTipsState[Header])?tableToolTipsState[Header]:"Select one or more value from list to search"}
            />
          </div>
        </div>
      )
    }
    
    // Multi-Select Custom Filter and set unique options value
    function MultiSelectFilter({
      column: { filterValue, setFilter, preFilteredRows, id, Header },
    }) {
      const [value, setValue] = useState('');
      const [filtertype, setFiltertype] = useState('Any');
      const [filtered, setFiltered] = useState(false);
    
      function callSearchFunc(e) {
        callServerFilter(e);
      }
      
      React.useEffect(() => {
        if (!filterValue && value) {
          setValue('');
          setFiltertype('Any');
        }
        if (storeFilter) {
          const filterValue = TableUtil.getFilter(currentTableName, Header);
          if(filterValue && !value){
            setValue(filterValue);
            setFilter(filterValue);
            setFiltertype(filtertype);
          }
        }
      }, [filterValue, value, filtertype]);
    
      multiSelectOption[Header] = filtertype;
      const options = React.useMemo(() => {
        let options = new Set();
        if (showFilterOption) {
          return showFilterOption(id);
        } 
        preFilteredRows.forEach(row => {
          row.values[id].split(',').forEach(value => {
            if (value !== '') {
              let hasValue = false;
              options.forEach(option => {
                if (option.name === value) {
                  hasValue = true;
                }
              });
              if (!hasValue) {
                let option = { 'name': value, 'value': value };
                options.add(option);
              }
            }
          });
        });
        return [...options.values()]
      }, [id, preFilteredRows]);
    
        // Function to call the server side filtering
        const callServerFilter = (event, isCleared) => {
          hasFilters = true;
          //_.remove(tableOptionsState.filters, function(filter) { return filter.id === Header });
          //tableOptionsState.filters.push({id: Header, value: event.target.value});
          if (isCleared) {
              hasFilters = false;
              if (filtered) {
                  _.remove(tableOptionsState.filters, function(filter) { return filter.id === Header });
                  filterCallback(tableOptionsState, setLoaderFunction);
              }
          }   else {
              filterCallback(tableOptionsState, setLoaderFunction);
          }
      }; 
    
      // Render a multi-select box
      return (
        <div onClick={e => { e.stopPropagation()}}>
          <div style={{ position: 'relative', display: 'flex'}} >
            <diV>
              <MultiSelect data-testid="multi-select" id="multi-select" optionLabel="name" optionValue="value" filter //={!doServersideFilter}
                value={value}
                options={options}
                onChange={e => {
                  setValue(e.target.value);
                  setFilter(e.target.value || undefined);
                  if(storeFilter) {
                    if (e.target.value.length > 0) {
                      TableUtil.saveFilter(currentTableName, Header, e.target.value);
                    } else {
                      TableUtil.clearColumnFilter(currentTableName, Header);
                    }
                  }
                  setFiltered(true);
                  //callServerFilter(e);
                }}
                maxSelectedLabels="1"
                selectedItemsLabel="{0} Selected"
                className="multi-select"
                tooltip={(tableToolTipsState[Header])?tableToolTipsState[Header]:"Select one or more value from list and click search icon to search"}
                style={{width: '8em'}}
              />
            </diV>
            {doServersideFilter &&
              <div>
                  <button  className="p-link" onClick={callSearchFunc} >
                    <i className="pi pi-search search-btn" />
                  </button>
              </div>
            }
          </div>
        </div>
      )
    }
    
    // This is a custom filter UI that uses a
    // slider to set the filter value between a column's
    // min and max values
    function SliderColumnFilter({
      column: { filterValue, setFilter, preFilteredRows, id, Header },
    }) {
      // Calculate the min and max
      // using the preFilteredRows
      const [value, setValue] = useState(0);
      /*const [min, max] = React.useMemo(() => {
        let min = preFilteredRows.length ? preFilteredRows[0].values[id] : 0
        let max = preFilteredRows.length ? preFilteredRows[0].values[id] : 0
        preFilteredRows.forEach(row => {
          min = Math.min(row.values[id], min)
          max = Math.max(row.values[id], max)
        })
        return [min, max]
      }, [id, preFilteredRows])*/
    
      React.useEffect(() => {
        if (storeFilter) {
          const filterValue = TableUtil.getFilter(currentTableName, Header);
          if (filterValue && !value) {
            setValue(filterValue);
            setFilter(filterValue);
          }
        }
      });
    
      return (
        <div onClick={e => { e.stopPropagation() }} className="table-slider">
          <Slider value={value} 
            onChange={(e) => { 
              setFilter(e.value); setValue(e.value);
              if (storeFilter) {
                TableUtil.saveFilter(currentTableName, Header, e.value);
              }
            }}
            tooltip={(tableToolTipsState[Header])?tableToolTipsState[Header]:"Select range value to search"}
          />
        </div>
      )
    }
    
    // This is a custom filter UI that uses a
    // switch to set the value
    function BooleanColumnFilter({
      column: { setFilter, filterValue, Header },
    }) {
      // Calculate the min and max
      // using the preFilteredRows
      const [value, setValue] = useState(null);
      const [filtered, setFiltered] = useState(false);
      React.useEffect(() => {
        if (!filterValue && value) {
          setValue(null);
        }
        if (storeFilter) {
          const filterValue = TableUtil.getFilter(currentTableName, Header);
          if(filterValue && !value){
            setValue(filterValue);
            setFilter(filterValue);
          }
        }
      }, [filterValue, value]);
      // Function to call the server side filtering
      const callServerFilter = (isCleared) => {
        hasFilters = true;
        _.remove(tableOptionsState.filters, function(filter) { return filter.id === Header });
        if (isCleared == null) {
            setFiltered(false);
        } else if (isCleared) {
            hasFilters = false;
            tableOptionsState.filters.push({id: Header, value: true});
            setFiltered(true);
            setValue(true);
        } else {
            setFiltered(true);
            setValue(false);
            tableOptionsState.filters.push({id: Header, value: false});
        }
        filterCallback(tableOptionsState, setLoaderFunction);
      };
    
      return (
        <div onClick={e => { e.stopPropagation() }}>
          <TriStateCheckbox value={value} style={{ 'width': '15px', 'height': '24.2014px' }} on
            onChange={(e) => { 
              setValue(e.target.value);
              setFilter(e.target.value || undefined); 
              setFiltered(true);
              if (storeFilter) {
                TableUtil.saveFilter(currentTableName, Header, e.target.value);
              }
              if (doServersideFilter) {
                callServerFilter(e.value);
              }
            }}
            tooltip={(tableToolTipsState[Header])?tableToolTipsState[Header]:"Select checkbox (True/False/None) to search"}
           />
        </div>
      )
    }
    
    // This is a custom filter UI that uses a
    // calendar to set the valueCalendar
    function ColumnFilter({
      column: { setFilter, filterValue, Header },
    }) {
      // Calculate the min and max
      // using the preFilteredRows
      const [value, setValue] = useState('');
      const [filtered, setFiltered] = useState(false);
      React.useEffect(() => {
        if (!filterValue && value) {
          setValue(null);
        }
      }, [filterValue, value]);
    
      React.useEffect(() => {
        // let localstorage_key = window.location.pathname.split('/')[1];
        // let storage =  UtilService.localStore({ type: 'get', key: localstorage_key }); 
        // let storageStatus =_.filter(storage, function (filter) {
        // if ( filter.name === Header && storeFilter) {
        //   setValue(filter.value);
        //   setFilter(filter.value);
        //   setFiltered(true);
        //     return true;
        //   }
        // })
      }, []);
    
      // Function to call the server side filtering
      const callServerFilter = (event, isCleared) => {
        hasFilters = true;
        if (isCleared) {
            hasFilters = false;
            if (filtered) {
                _.remove(tableOptionsState.filters, function(filter) { return filter.id === Header });
                filterCallback(tableOptionsState, setLoaderFunction);
            }
        }   else {
            filterCallback(tableOptionsState, setLoaderFunction);
        }
    };
      return (
    
        <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);
            setFilter(e.value);
            if (value !== 'Invalid date'  && doServersideFilter) {
              setFiltered(true);
              callServerFilter(e);
            }
            // if(storeFilter) {
            //   let localstorage_key = window.location.pathname.split('/')[1];
            //   let storage =  UtilService.localStore({ type: 'get', key: localstorage_key }); 
            //   if(storage && storage.length > 0) {
            //     storage.forEach(function(value, index) {
            //       if(value.name === Header) {
            //         value.name =  Header
            //         value.value = moment(e.value).format('YYYY-MM-DD')
            //       }
            //     });
            //     const selected = _.filter(storage, function (filter) {
            //       if ( filter.name === Header) {
            //         return true;
            //       }
            //     })
            //     if(selected.length <= 0) {
            //       storage.push({name: Header, value: moment(e.value).format('YYYY-MM-DD')})
            //     }
            //   } else {
            //     storage = [{name: Header, value: value}]
            //   }
            //   UtilService.localStore({ type: 'set', key: localstorage_key, value: storage });
            //   }
          }} 
          showIcon></Calendar>
          {value && <i onClick={(e) => { setFilter(undefined); setValue(''); setFiltered(false);
            if (doServersideFilter) {
              setFilter(undefined); 
              setValue('');
              callServerFilter(e, true);
            } }} className="tb-cal-reset fa fa-times" />}
        </div>
      )
    }
    
    // This is a custom filter UI that uses a
    // calendar range to set the value
    function DateRangeColumnFilter({
      column: { setFilter, filterValue, Header },
    }) {
      // Calculate the min and max
      // using the preFilteredRows
      const [value, setValue] = useState('');
      const [filtered, setFiltered] = useState(false);
      React.useEffect(() => {
        if (!filterValue && value) {
          setValue(null);
        }
        
        if (storeFilter) {
          const filter = TableUtil.getFilter(currentTableName, Header);
          const filterValue = _.map(filter, date => {return new Date(date)} )
          if (filterValue[1] &&  !value ){
            setValue(filterValue);
            setFilter(filterValue);
          }
        }
      }, [filterValue, value]);
      // Function to call the server side filtering
      const callServerFilter = (value, isCleared) => {
        hasFilters = true;
        if (isCleared) {
            hasFilters = false;
            if (filtered) {
                _.remove(tableOptionsState.filters, function(filter) { return filter.id === Header });
                filterCallback(tableOptionsState, setLoaderFunction);
            }
        }   else {
          let filterColumn = _.find(tableOptionsState.filters, {id: Header });
          if(filterColumn) {
            filterColumn.value = value;
            filterCallback(tableOptionsState, setLoaderFunction);
          } else {
            filterCallback(tableOptionsState, setLoaderFunction);
          }
        }
    };
      return (
        <div className="table-filter" onClick={e => { e.stopPropagation() }}>
          <Calendar selectionMode="range" value={filterValue} appendTo={document.body}
            placeholder="Range"
            onChange={(e) => {  
              setValue(e.value);
              setFilter(e.value);
              if(storeFilter) {
                TableUtil.saveFilter(currentTableName, Header, e.target.value);
              }
              if ((value !== '' && value !== 'Invalid date' ) && doServersideFilter) {
                setFiltered(true);
                callServerFilter(e.target.value);
              }
            }} 
            showIcon></Calendar>
          {value && <i onClick={(e) => { 
            setFilter(undefined); setValue([]); setFiltered(false);
            if(storeFilter){
              TableUtil.saveFilter(currentTableName, Header, []  );
            }
            if (doServersideFilter) {
              setFilter(undefined); 
              setValue('');
              callServerFilter(e.target.value, true);
            } }} className="tb-cal-reset fa fa-times" />}
        </div>
      )
    }
    
    // This is a custom filter UI that uses a
    // flatpickr range calendar to set the value
    function FlatpickrRangeColumnFilter({
      column: { setFilter, filterValue, Header },
    }) {
        const [value, setValue] = useState('');
        const [filtered, setFiltered] = useState(false);  
        React.useEffect(() => {
          if (!filterValue && value) {
            setValue(null);
          }
          if (storeFilter) {
            const filter = TableUtil.getFilter(currentTableName, Header);
            const filterValue = _.map(filter, date => {return new Date(date)} )
            if (filter === '') {
              TableUtil.saveFilter(currentTableName, Header, []  );
              setFilter(undefined); 
            }
            if (filterValue &&  !value ){
              setValue(filterValue);
              setFilter(filterValue);
            }
          }
      }, [filterValue, value]);
      // Function to call the server side filtering
      const callServerFilter = (value, isCleared) => {
          hasFilters = true;
          if (isCleared) {
              hasFilters = false;
              _.remove(tableOptionsState.filters, function(filter) { return filter.id === Header });
              filterCallback(tableOptionsState, setLoaderFunction);
          }   else {
              let filterColumn = _.find(tableOptionsState.filters, {id: Header });
              if(filterColumn) {
                  filterColumn.value = value;
                  filterCallback(tableOptionsState, setLoaderFunction);
              } else if (!filterColumn && value && value.length === 2) {
                  // Here the above condition placed because the Start/End time filters is not consistency in tableOptionsState.filters
                  filterColumn = {id: Header, value: value}
                  tableOptionsState.filters.push(filterColumn);
                  filterCallback(tableOptionsState, setLoaderFunction);
              } else {
                  filterCallback(tableOptionsState, setLoaderFunction);
              }
        }
      };
      return (
          <div className="table-filter" onClick={e => { e.stopPropagation() }}>
              <Flatpickr data-enable-time data-input 
                options={{  "inlineHideInput": true,
                            "wrap": true,
                            "enableSeconds": true,
                            "time_24hr": true,
                            "minuteIncrement": 1,
                            "allowInput": true,
                            "mode": "range",
                            "defaultHour": 0,
                            "plugins": [new confirmDatePlugin()]
                        }}
                title={(tableToolTipsState[Header])?tableToolTipsState[Header]:"Enter the date & time range to search and press ‘Ok’ button"}
                value={filterValue}
                onClose={newValue => {
                  if(newValue) {
                    // To apply serverside filter only when the value is changed
                    let isValueChanged = false;
                    if (value.length !== newValue.length) {
                      isValueChanged = true;
                    } else if (value.length === newValue.length) {
                      if (value.length === 1 && !(moment(value[0]).isSame(moment(newValue[0])))) {
                        isValueChanged = true
                      } else if (value.length === 2 &&
                        (!(moment(value[0]).isSame(moment(newValue[0]))) ||
                        !(moment(value[1]).isSame(moment(newValue[1]))))) {
                        isValueChanged = true;
                      }
                    }
                    setValue(newValue);
                    setFilter(newValue);
                    if(storeFilter) {
                      TableUtil.saveFilter(currentTableName, Header, newValue);
                    }
                    if ((newValue !== '' && newValue !== 'Invalid date' ) && isValueChanged  && doServersideFilter) {
                      setFiltered(true);
                      callServerFilter(newValue);
                    }
                  }
                }}
              >
                  <input type="text" data-input className={`p-inputtext p-component calendar-input`}  />
                  <button class="p-button p-component p-button-icon-only calendar-button" data-toggle
                          title="Click to select the date range" >
                          <i class="fas fa-calendar"></i>
                  </button>
                  <button class="p-button p-component p-button-icon-only calendar-reset" 
                    onClick={(value) => { 
                      setFilter(undefined); setValue([]); setFiltered(false);filterValue = [];
                      if(storeFilter){
                          TableUtil.saveFilter(currentTableName, Header, []  );
                      }
                      if (doServersideFilter) {
                          setFilter(undefined); 
                          setValue('');
                          callServerFilter(value, true);
                      }
                  }} title="Clear date range" >
                      <i class="fa fa-times" style={{color:'white', marginTop:'-2.85px'}} ></i>
                  </button>
              </Flatpickr>
          </div>
      )
    }
    
    // This is a custom filter UI that uses a
    // calendar to set the value
    function CalendarColumnFilter({
      column: { setFilter, filterValue, Header },
    }) {
      // Calculate the min and max
      // using the preFilteredRows
      const [value, setValue] = useState('');
      const [filtered, setFiltered] = useState(false);
      React.useEffect(() => {
        if (!filterValue && value) {
          setValue(null);
        }
        if (storeFilter) {
          const filterValue = TableUtil.getFilter(currentTableName, Header);
          if(filterValue && !value){
            const valueAsDate = new Date(filterValue)
            setValue(valueAsDate);
            setFilter(valueAsDate);
          }
        }
        
      }, [filterValue, value]);
    
      // Function to call the server side filtering
      const callServerFilter = (event, isCleared) => {
        hasFilters = true;
        if (isCleared) {
            hasFilters = false;
            if (filtered) {
                _.remove(tableOptionsState.filters, function(filter) { return filter.id === Header });
                filterCallback(tableOptionsState, setLoaderFunction);
            }
        }   else {
            filterCallback(tableOptionsState, setLoaderFunction);
        }
    };
      return (
    
        <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);
            setFilter(e.value);
            if (value !== 'Invalid date'  && doServersideFilter) {
              setFiltered(true);
              callServerFilter(e);
            }
    
              if(storeFilter) {
                TableUtil.saveFilter(currentTableName, Header, value);
              }
          }} 
          onClearButtonClick={(e) => {
            if(storeFilter) {
              TableUtil.clearColumnFilter(currentTableName, Header);
            }
          }}
          showIcon></Calendar>
          {value && <i onClick={(e) => { setFilter(undefined); setValue(''); setFiltered(false);
            if (storeFilter) {
              TableUtil.clearColumnFilter(currentTableName, Header);
            }
            if (doServersideFilter) {
              setFilter(undefined); 
              setValue('');
              callServerFilter(e, true);
            } }} className="tb-cal-reset fa fa-times" />}
        </div>
      )
    }
    
    // This is a custom filter UI that uses a
    // calendar to set the value
    function DateTimeColumnFilter({
      column: { setFilter, filterValue, Header },
    }) {
      const [value, setValue] = useState('');
      React.useEffect(() => {
        if (!filterValue && value) {
          setValue(null);
        }
        if (storeFilter) {
          const getValue = TableUtil.getFilter(currentTableName, Header);
          if (getValue && !value) {
            const valueAsDate = new Date(getValue)
            setValue(valueAsDate);
            setFilter(valueAsDate);
          }
        }
      }, [filterValue, value]);
      
      // Function to call the server side filtering
      const callServerFilter = (event, isCleared) => {
          hasFilters = true;
          _.remove(tableOptionsState.filters, function(filter) { return filter.id === Header });
          if (isCleared) {
              hasFilters = false;
              filterCallback(tableOptionsState, setLoaderFunction);
          } else {
              tableOptionsState.filters.push({id: Header, value: moment(event.value, moment.ISO_8601).format('YYYY-MM-DD HH:mm:ss')});
              filterCallback(tableOptionsState, setLoaderFunction);
          }
      };
      return (
        <div className="table-filter" onClick={e => { e.stopPropagation() }}>
          <Calendar value={value} appendTo={document.body} dateFormat="yy/mm/dd"
           onKeyUp={(e) => {
            if (e.key === "Enter" && doServersideFilter) {
              callServerFilter(e);
            }
          }}
          onChange={(e) => {
            const value = moment(e.value, moment.ISO_8601).format('YYYY-MM-DD HH:mm:ss');
            setValue(value); setFilter(value);
            if (value !== 'Invalid date'  && doServersideFilter) {
              callServerFilter(e);
            }
            
            if(storeFilter) {
              TableUtil.saveFilter(currentTableName, Header, value);
            }
          }} 
          showIcon
          // showTime= {true}
          //showSeconds= {true}
          // hourFormat= "24"
          ></Calendar>
          {value && <i onClick={(e) => { 
            setFilter(undefined); setValue('');
            if (doServersideFilter) {
              setFilter(undefined); 
              setValue('');
              callServerFilter(e, true);
            }
            if (storeFilter) {
              TableUtil.clearColumnFilter(currentTableName, Header);
            }
         }} className="tb-cal-reset fa fa-times" />}
        </div>
      )
    }
    
    /**
     * Custom function to filter data from date field.
     * @param {Array} rows 
     * @param {String} id 
     * @param {String} filterValue 
     */
    function fromDatetimeFilterFn(rows, id, filterValue) {
      const filteredRows = _.filter(rows, function (row) {
        // If cell value is null or empty
        if (!row.values[id]) {
          return false;
        }
        //Remove microsecond if value passed is UTC string in format "YYYY-MM-DDTHH:mm:ss.sssss"
        let rowValue = moment.utc(row.values[id].split('.')[0]);
        if (!rowValue.isValid()) {
          // For cell data in format 'YYYY-MMM-DD'
          rowValue = moment.utc(moment(row.values[id], 'YYYY-MM-DDTHH:mm:SS').format("YYYY-MM-DDTHH:mm:SS"));
        }
        const start = moment.utc(moment(filterValue, 'YYYY-MM-DDTHH:mm:SS').format("YYYY-MM-DDTHH:mm:SS"));
    
        return (start.isSameOrBefore(rowValue));
      });
      return filteredRows;
    }
    
    /**
     * Custom function to filter Multi selection based on filter type (Any/All) .
     * @param {Array} rows 
     * @param {String} id 
     * @param {String} filterValue 
     */
    function multiSelectFilterFn(rows, id, filterValue) {
      if (filterValue) {
        const filteredRows = _.filter(rows, function (row) {
          if (filterValue.length === 0) {
            return true;
          }
          // If cell value is null or empty
          if (!row.values[id]) {
            return false;
          }
          let rowValue = row.values[id];
          let hasData = false;
          let columnValues = rowValue.split(',');
          let unfilteredColValues = _.difference(filterValue, columnValues);
          if (multiSelectOption[id] === 'Any') {
              hasData = unfilteredColValues.length < filterValue.length;
          }
          else {
              hasData = unfilteredColValues.length === 0;
          }
          return hasData;
        });
        return filteredRows;
      }
    }
    
    /**
     * Custom function to filter data from date field.
     * @param {Array} rows 
     * @param {String} id 
     * @param {String} filterValue 
     */
    function toDatetimeFilterFn(rows, id, filterValue) {
      let end = moment.utc(moment(filterValue, 'YYYY-MM-DDTHH:mm:SS').format("YYYY-MM-DDTHH:mm:SS"));
      end = moment(end, "DD-MM-YYYY").add(1, 'days');
      const filteredRows = _.filter(rows, function (row) {
        // If cell value is null or empty
        if (!row.values[id]) {
          return false;
        }
        //Remove microsecond if value passed is UTC string in format "YYYY-MM-DDTHH:mm:ss.sssss"
        let rowValue = moment.utc(row.values[id].split('.')[0]);
        if (!rowValue.isValid()) {
          // For cell data in format 'YYYY-MMM-DD'
          rowValue = moment.utc(moment(row.values[id], 'YYYY-MM-DDTHH:mm:SS').format("YYYY-MM-DDTHH:mm:SS"));
        }
        return (end.isSameOrAfter(rowValue));
      });
      return filteredRows;
    }
    
    /**
     * Custom function to filter data from date field.
     * @param {Array} rows 
     * @param {String} id 
     * @param {String} filterValue 
     */
    function dateFilterFn(rows, id, filterValue) {
      const filteredRows = _.filter(rows, function (row) {
        // If cell value is null or empty
        if (!row.values[id]) {
          return false;
        }
        //Remove microsecond if value passed is UTC string in format "YYYY-MM-DDTHH:mm:ss.sssss"
        let rowValue = moment.utc(row.values[id].split('.')[0]);
        if (!rowValue.isValid()) {
          // For cell data in format 'YYYY-MMM-DD'
          rowValue = moment.utc(moment(row.values[id], 'YYYY-MM-DD').format("YYYY-MM-DDT00:00:00"));
        }
        const start = moment.utc(moment(filterValue, 'YYYY-MM-DD').format("YYYY-MM-DDT00:00:00"));
        const end = moment.utc(moment(filterValue, 'YYYY-MM-DD').format("YYYY-MM-DDT23:59:59"));
        return (start.isSameOrBefore(rowValue) && end.isSameOrAfter(rowValue));
      });
      return filteredRows;
    }
    
    /**
     * Custom function to filter data Range from date field.
     * @param {Array} rows 
     * @param {String} id 
     * @param {String} filterValue 
     */
     function dateRangeFilterFn(rows, id, filterValue) {
      const filteredRows = _.filter(rows, function (row) {
        // If cell value is null or empty
        if (!row.values[id]) {
          return false;
        }
        //Remove microsecond if value passed is UTC string in format "YYYY-MM-DDTHH:mm:ss.sssss"
        let rowValue = moment.utc(row.values[id].split('.')[0]);
        if (!rowValue.isValid()) {
          // For cell data in format 'YYYY-MMM-DD'
          rowValue = moment.utc(moment(row.values[id], 'YYYY-MM-DDTHH:mm:SS').format("YYYY-MM-DDTHH:mm:SS"));
        }
        const start = moment.utc(moment(filterValue[0], 'YYYY-MM-DDTHH:mm:SS').format("YYYY-MM-DDTHH:mm:SS"));
        const end = moment.utc(moment(filterValue[1], 'YYYY-MM-DDTHH:mm:SS').format("YYYY-MM-DDTHH:mm:SS"));
        if(moment(end,'YYYY-MM-DDTHH:mm:SS', true).isValid() && moment(start,'YYYY-MM-DDTHH:mm:SS', true).isValid()) {
            return (start.isSameOrBefore(rowValue) && end.isSameOrAfter(rowValue));
        }
        else if(moment(start,'YYYY-MM-DDTHH:mm:SS', true).isValid()) {
          return (start.isSameOrBefore(rowValue));
        }
        else {
          return true;
        }
      });
      return filteredRows;
    }
    
    function durationTimeFilterFn(rows, id, filterValue) {
      const filteredRows = _.filter(rows, function (row) {
        // If cell value is null or empty
        if (!row.values[id]) {
          return false;
        }
        //Remove microsecond if value passed is UTC string in format "HH:mm:ss.sssss"
        let rowValue = moment(row.values[id], 'HH:mm:SS');
        if (!rowValue.isValid()) {
          // For cell data in format 'HH:mm:SS'
          rowValue = moment(row.values[id], 'HH:mm:SS');
        }
        const start = moment(filterValue[0], 'HH:mm:SS');
        const end = moment(filterValue[1], 'HH:mm:SS');
        if(moment(end,'HH:mm:SS', true).isValid() && moment(start,'HH:mm:SS', true).isValid()) {
          return (start.isSameOrBefore(rowValue) && end.isSameOrAfter(rowValue));
        }
        else if (!(moment(end,'HH:mm:SS', true).isValid()) && !(moment(start,'HH:mm:SS', true).isValid()) ){
          return true
        }
        else if(!(moment(start,'HH:mm:SS', true).isValid())) {
          return end.isSameOrAfter(rowValue);
        }
        else if(!(moment(end,'HH:mm:SS', true).isValid())) {
          return start.isSameOrBefore(rowValue);
        }
      });
      return filteredRows;
    }
    
    // This is a custom UI for our 'between' or number range
    // filter. It uses slider to filter between min and max values.
    function RangeColumnFilter({
      column: { filterValue = [], preFilteredRows, setFilter, id, Header },
    }) {
      let [value, setValue] = useState('');
      let [firstLoad, setFirstLoad] = useState(true);
      const [min, max] = React.useMemo(() => {
        let min = 0;
        let max = 0;
        if (preFilteredRows.length > 0 && preFilteredRows[0].values[id]) {
          min = preFilteredRows[0].values[id];
        }
        preFilteredRows.forEach(row => {
          min = Math.min(row.values[id] ? row.values[id] : 0, min);
          max = Math.max(row.values[id] ? row.values[id] : 0, max);
        });
        if (storeFilter && firstLoad) {
          let storedFilter = TableUtil.getFilter(currentTableName, Header);
          if (storedFilter) {
            setValue(storedFilter);
            setFilter(storedFilter);
            setFirstLoad(false);
          }
        }
        return [min, max];
      }, [id, preFilteredRows]);
      if (filterValue.length === 0) {
        filterValue = [min, max];
      }
      return (
        <>
          <div className="filter-slider-label">
            <span style={{ float: "left" }}>{filterValue[0]}</span>
            <span style={{ float: "right" }}>{min !== max ? filterValue[1] : ""}</span>
          </div>
          <Slider value={filterValue} min={min} max={max} className="filter-slider"
            style={{}}
            onChange={(e) => { 
              setValue(e.value);
              setFilter(e.value); 
                if(storeFilter) {
                  TableUtil.saveFilter(currentTableName, Header, e.value);
                }
              }} range />
        </>
      );
    }
    
    /**
     * Number range rilter
     * @param {number} param0 : Range value for min and max filters
     * @returns 
     */
    function NumberRangeFilter({
      column: { filterValue = [], preFilteredRows, setFilter, id, Header },
    }) {
      let [rangeValue, setRangeValue] = useState([0,0]);
      const [value, setValue] = useState('');
      const [filtered, setFiltered] = useState(false);
      React.useEffect(() => {
        if (!filterValue && value) {
          setValue('');     
        }
        if (storeFilter) {
          const filterValue = TableUtil.getFilter(currentTableName, Header);
          if (filterValue) {
              setFiltered(true);
          }
          if(!value){
              setValue(filterValue);
              //setFilter(filterValue);
          }
        }
      }, [filterValue, value]);
      
       // Function to call the server side filtering
       const callServerFilter = (event, isCleared) => {
        hasFilters = true;
        _.remove(tableOptionsState.filters, function(filter) { return filter.id === Header });
        if (isCleared) {
            hasFilters = false;
            if (filtered) {
                filterCallback(tableOptionsState, setLoaderFunction);
            }
        }   else {
            tableOptionsState.filters.push({id: Header, value: rangeValue});
            filterCallback(tableOptionsState, setLoaderFunction);
        }
      };
    
      return (
        <div
          style={{
            alignItems: 'center'
          }}
        >
          <InputText
            value={value[0]}
            type="number"
            tooltip="Enter the minimum value to search"
            onKeyUp={(e) => {
              if (e.key === "Enter" && doServersideFilter) {
                TableUtil.saveFilter(currentTableName, Header, rangeValue);
                setFiltered(true);
                callServerFilter(e, false);
              }
            }}
            onChange={e => {
              setFilter(undefined);  setFiltered(false);
              const val = e.target.value;
              let max = rangeValue[1];
              setValue([val,max]);
              setFilter([val,max] || undefined);
              setRangeValue([val,max]);
              filterValue[0] = val;
              if(storeFilter) {
                TableUtil.saveFilter(currentTableName, Header, [val,max]);
                setFilter([val,max]);
              }
            }}
            style={{
              width: '65px',
              height: '25px'
              // marginRight: '0.5rem',
            }}
            tooltip={(tableToolTipsState[Header])?tableToolTipsState[Header]:"Enter Minimum Range value and press ‘Enter’ key to search"}
          />
          
          <InputText
            value={value[1]}
            type="number"
            tooltip="Enter the maximum value to search"
            onKeyUp={(e) => {
              if (e.key === "Enter" && doServersideFilter) {
                setFiltered(true);
                callServerFilter(e, false);
              }
            }}
            onChange={e => {
              const val = e.target.value;
              let min = rangeValue[0];
              setRangeValue([min,val]);
              filterValue[1] = val;
              setValue([min,val]);
              setFilter([min,val] || undefined);
              if(storeFilter) {
                TableUtil.saveFilter(currentTableName, Header, [min,val]);
                setFilter([min,val]);
              }
            }}
             
            style={{
              width: '65px',
              height: '25px'
            }}
            tooltip={(tableToolTipsState[Header])?tableToolTipsState[Header]:"Enter Maximum Range value and press ‘Enter’ key to search"}
          />
        </div>
      )
    }
    
    // Priority Rank Range Filter
    function RankRangeFilter({
      column: { filterValue = [], preFilteredRows, setFilter, id, Header },
    }) {
      let [rangeValue, setRangeValue] = useState([]);
      const [value, setValue] = useState('');
      const [filtered, setFiltered] = useState(false);
      React.useEffect(() => {
        if (!filterValue && value) {
          setValue('');     
          //setRangeValue([])
        }
        if (storeFilter) {
          const filterValue = TableUtil.getFilter(currentTableName, Header);
          if (filterValue) {
              setFiltered(true);
          }
          if(!value){
              setValue(filterValue);
              //setFilter(filterValue);
          }
        }
      }, [filterValue, value]);
      
       // Function to call the server side filtering
       const callServerFilter = (event, isCleared) => {
        hasFilters = true;
        _.remove(tableOptionsState.filters, function(filter) { return filter.id === Header });
        if (isCleared) {
            hasFilters = false;
            if (filtered) {
                filterCallback(tableOptionsState, setLoaderFunction);
            }
        }   else {
            tableOptionsState.filters.push({id: Header, value: rangeValue});
            filterCallback(tableOptionsState, setLoaderFunction);
        }
      };
    
      return (
        <div
          style={{
            alignItems: 'center'
          }}
        >
          <input type="decimal"
              title={(tableToolTipsState[Header])?tableToolTipsState[Header]:"Enter Minimum Range value and press ‘Enter’ key to search"}
              max="1"
              min="0"
              className="p-inputtext p-component"
              value={value[0]}
              step="0.0001"
              onKeyUp={(e) => {
                  if (e.key === "Enter" && doServersideFilter) {
                      TableUtil.saveFilter(currentTableName, Header, rangeValue);
                      setFiltered(true);
                      callServerFilter(e, false);
                  }
              }}
              onChange={e => {
                  setFilter(undefined);  setFiltered(false);
                  let val = e.target.value;
                  val = val.replace(/([^0-9.]+)/, "");
                  const match = /(\d{0,1})[^.]*((?:\.\d{0,4})?)/g.exec(val);
                  val = match[1] + match[2];
                  if (val == '' || (val >= 0 && val <= 1)) {
                      let max = rangeValue[1];
                      setValue([val,max]);
                      setFilter([val,max] || undefined);
                      setRangeValue([val,max]);
                      filterValue[0] = val;
                      if(storeFilter) {
                          //TableUtil.saveFilter(currentTableName, Header, [val,max]);
                          setFilter([val,max]);
                      }
                }   else {
                    e.target.value = rangeValue[0];
                }
              }}
              style={{
                width: '75px',
                height: '25px'
              }}
          />
           
          <input type="decimal"
              title={(tableToolTipsState[Header])?tableToolTipsState[Header]:"Enter Maximum Range value and press ‘Enter’ key to search"}
              max="1"
              min="0"
              className="p-inputtext p-component"
              value={value[1]}
              step="0.0001"
              onKeyUp={(e) => {
                  if (e.key === "Enter" && doServersideFilter) {
                      TableUtil.saveFilter(currentTableName, Header, rangeValue);
                      setFiltered(true);
                      callServerFilter(e, false);
                  }
              }}
              onChange={e => {
                  setFilter(undefined);  setFiltered(false);
                  let val = e.target.value;
                  val = val.replace(/([^0-9.]+)/, "");
                  const match = /(\d{0,1})[^.]*((?:\.\d{0,4})?)/g.exec(val);
                  val = match[1] + match[2];
                  if (val == '' || (val >= 0 && val <= 1)) {
                      let min = rangeValue[0];
                      setRangeValue([min,val]);
                      filterValue[1] = val;
                      setValue([min,val]);
                      setFilter([min,val] || undefined);
                      if(storeFilter) {
                        //TableUtil.saveFilter(currentTableName, Header, [min,val]);
                        setFilter([min,val]);
                      }  
                  }   else {
                      e.target.value = rangeValue[0];
                  }
              }}
              style={{
                width: '75px',
                height: '25px'
              }}
          />
        </div>
      )
    }
    
    // Duration Range Filter
    function DurationRangeFilter({
      column: { filterValue = [], preFilteredRows, setFilter, id, Header },
    }) {
      let [rangeValue, setRangeValue] = useState(['','']);
      const [value, setValue] = useState('');
      const [filtered, setFiltered] = useState(false);
      React.useEffect(() => {
        if (!filterValue && value) {
          setValue('');     
        }
        if (storeFilter) {
          const filterValue = TableUtil.getFilter(currentTableName, Header);
          if (filterValue) {
              setFiltered(true);
          }
          if(filterValue && !value){
              setValue(filterValue);
              setFilter(filterValue);
          }
          if(!filterValue && value.length>0){
            setValue([]);
          }
        }
      }, [filterValue, value]);
      
       // Function to call the server side filtering
       const callServerFilter = (event, isCleared) => {
        hasFilters = true;
        _.remove(tableOptionsState.filters, function(filter) { return filter.id === Header });
        if (isCleared) {
            hasFilters = false;
            if (filtered) {
                filterCallback(tableOptionsState, setLoaderFunction);
            }
        }   else {
            tableOptionsState.filters.push({id: Header, value: rangeValue});
            filterCallback(tableOptionsState, setLoaderFunction);
        }
      };
    
      return (
        <div
          onKeyPress={(e) => {
            if (e.key === "Enter" && doServersideFilter) {
              TableUtil.saveFilter(currentTableName, Header, rangeValue);
              setFiltered(true);
              callServerFilter(e, false);
            }
            else if(e.key === "Enter" ) {
              setFilter(rangeValue);
            }
          }}
          style={{
            alignItems: 'center'
          }}
        >
          <InputMask mask="99:99:99"
              value={value[0]}
              placeholder="HH:mm:ss"
              tooltip={(tableToolTipsState[Header])?tableToolTipsState[Header]:"Enter Minimum Range value in HH:mm:ss format and press ‘Enter’ key to search"}
              onChange={e => {
                let val = e.target.value;
                if (val.includes(":") && !Validator.isValidHHmmss(val, true)) {
                  val = rangeValue[0];
                }
                let max = rangeValue[1];
                setValue([val,max]);
                if(doServersideFilter) {
                  setFilter([val,max] || undefined);
                }
                setRangeValue([val,max]);
                filterValue[0] = val;
                if(storeFilter) {
                    TableUtil.saveFilter(currentTableName, Header, [val,max]);
                }
              }}
              style={{
                width: '85px',
                height: '25px'
              }}
          />
        
        <InputMask mask="99:99:99"
              value={value[1]}
              tooltip={(tableToolTipsState[Header])?tableToolTipsState[Header]:"Enter Maximum Range value in HH:mm:ss format and press ‘Enter’ key to search"}
              placeholder="HH:mm:ss"
              onChange={e => {
                let val = e.target.value;
                if (val.includes(":") && !Validator.isValidHHmmss(val, true)) {
                  val = rangeValue[1];
                }
                let min = rangeValue[0];
                setValue([min,val]);
                if(doServersideFilter) {
                  setFilter([min,val] || undefined);
                }
                setRangeValue([min,val]);
                filterValue[1] = val;
                if(storeFilter) {
                    TableUtil.saveFilter(currentTableName, Header, [min,val]);
                }
              }}
              style={{
                width: '85px',
                height: '25px'
              }}
        />
        </div>
         
      )
    }
    
    // This is a custom UI for our 'between' or number range
    // filter. It uses two number boxes and filters rows to
    // ones that have values between the two
    function NumberRangeColumnFilter({
      column: { filterValue = [], preFilteredRows, setFilter, id, Header },
    }) {
      const [errorProps, setErrorProps] = useState({});
      const [maxErr, setMaxErr] = useState(false);
      const [min, max] = React.useMemo(() => {
        let min = preFilteredRows.length ? preFilteredRows[0].values[id] : 0
        let max = preFilteredRows.length ? preFilteredRows[0].values[id] : 0
        preFilteredRows.forEach(row => {
          min = Math.min(row.values[id], min)
          max = Math.max(row.values[id], max)
        })
        return [min, max]
      }, [id, preFilteredRows])
    
      return (
        <div
          style={{
            //  display: 'flex',
            //  flexdirection:'column',
            alignItems: 'center'
          }}
        >
          <InputText
            value={filterValue[0]}
            type="number"
            onChange={e => {
              const val = e.target.value;
              setFilter((old = []) => [val ? parseFloat(val, 10) : undefined, old[1]]);
            }}
            placeholder={`Min (${min})`}
            style={{
              width: '55px',
              height: '25px'
              // marginRight: '0.5rem',
            }}
            tooltip={(tableToolTipsState[Header])?tableToolTipsState[Header]:"Enter Minimum Range value and press ‘Enter’ key to search"}
          />
          <InputText
            value={filterValue[1] || ''}
            type="number"
            {...errorProps}
            className={maxErr && 'field-error'}
            onChange={e => {
              const val = e.target.value;
              const minVal = filterValue.length && filterValue[0];
              if (minVal && e.target.value < minVal) {
                setMaxErr(true);
                setErrorProps({
                  tooltip: "Max value should be greater than Min",
                  tooltipOptions: { event: 'hover' }
                });
              } else {
                setMaxErr(false);
                setErrorProps({});
              }
              setFilter((old = []) => [old[0], val ? parseFloat(val, 10) : undefined])
            }}
            placeholder={`Max (${max})`}
            style={{
              width: '55px',
              height: '25px'
              //  marginLeft: '0.5rem',
            }}
            tooltip={(tableToolTipsState[Header])?tableToolTipsState[Header]:"Enter Maximum Range value and press ‘Enter’ key to search"}
          />
        </div>
      )
    }
    
    
    function fuzzyTextFilterFn(rows, id, filterValue) {
      return matchSorter(rows, filterValue, { keys: [row => row.values[id]] });
    }
    
    const filterTypes = {
      'select': {
        fn: SelectColumnFilter,
      },
      // This component has Any and All Radio buttons
      'multiselect': {
        fn: MultiSelectColumnFilter,
        type: multiSelectFilterFn
      },
      // This component does not have Any and All Radio buttons
      'multiselect-filter': {
        fn: MultiSelectFilter,
        type: multiSelectFilterFn
      },
      'switch': {
        fn: BooleanColumnFilter
      },
      'slider': {
        fn: SliderColumnFilter
      },  
      
      'date': {
        fn: CalendarColumnFilter,
        type: dateFilterFn
      },
      'dateRange': {
        fn: DateRangeColumnFilter,
        type: dateRangeFilterFn
      },
      'flatpickrDateRange': {
        fn: FlatpickrRangeColumnFilter,
        type: dateRangeFilterFn
      },
      
      'fromdatetime': {
        fn: DateTimeColumnFilter,
        type: fromDatetimeFilterFn
      },
      'todatetime': {
        fn: DateTimeColumnFilter,
        type: toDatetimeFilterFn
      },
      'range': {
        fn: RangeColumnFilter,
        type: 'between'
      },
      'minMax': {
        fn: NumberRangeColumnFilter,
        type: 'between'
      },
      'numberRangeMinMax': {
        fn: NumberRangeFilter,
        type: 'between'
      },
      'rankMinMax': {
        fn: RankRangeFilter,
        type: 'between'
      },
      'durationMinMax': {
        fn: DurationRangeFilter,
        type: durationTimeFilterFn
      }
    };
    // Let the table remove the filter if the string is empty
    fuzzyTextFilterFn.autoRemove = val => !val
    
    const IndeterminateCheckbox = React.forwardRef(
      ({ indeterminate, ...rest }, ref) => {
        const defaultRef = React.useRef()
        const resolvedRef = ref || defaultRef
        React.useEffect(() => {
          resolvedRef.current.indeterminate = indeterminate
        }, [resolvedRef, indeterminate])
        return <input type="checkbox" ref={resolvedRef} {...rest}/>
      }
    );
     
    // ViewTable table component
    function Table(props) {
      let {fetchData,  pageCount: controlledPageCount, currentPage, dataFetchStatus, columns, data, defaultheader, optionalheader, 
        tablename, defaultSortColumn, defaultpagesize, columnOrders, showAction, toggleBySorting, onColumnToggle, lsKeySortColumn
        , descendingColumn, ignoreSorting } = props;
      ignoreSorting = ignoreSorting ||[];
      ignoreSorting = [...ignoreSorting,'action'];
      descendingColumn = descendingColumn || [];
      const checkDefaultSortColumnEmpty = () => {
        return !defaultSortColumn || !defaultSortColumn[0] || Object.keys(defaultSortColumn[0]).length === 0;
      }
      const checkDescendingColumnExists = (value) => {
        return descendingColumn.includes(value);
      }
      const checkToIgnoreSorting = (value) => {
        return ignoreSorting.includes(value);
      }
      const getFirstVisibleColumn = (selectedColumn, tempAllColumns) => {
        let selected = {};
        let tempColumn = {};
        let totalColumns = undefined;
    
        if (tempAllColumns && tempAllColumns.length > 0) {
          totalColumns = tempAllColumns;
        }
    
        if (totalColumns) {
          for (let i = 0; i < totalColumns.length; i++) {
            tempColumn = { ...totalColumns[i] };
            if (tempColumn.Header && typeof tempColumn.Header === "string") {
              if (tempColumn.Header.toLowerCase() === selectedColumn.Header.toLowerCase()) {
                tempColumn.isVisible = selectedColumn.isVisible;
              }
              if (!checkToIgnoreSorting(tempColumn.Header.toLowerCase()) && tempColumn.isVisible) {
                selected = tempColumn;
                break;
              }
            }
          }
        }
        return selected;
      }
    
      if (checkDefaultSortColumnEmpty()) {
        let tempVisibleColumn = getFirstVisibleColumn({ Header: '' }, columns);
        defaultSortColumn = [{ id: tempVisibleColumn.Header, desc: checkDescendingColumnExists(tempVisibleColumn.Header.toLowerCase()) }];
      }
    
      const filterTypes = React.useMemo(
        () => ({
          // Add a new fuzzyTextFilterFn filter type.
          fuzzyText: fuzzyTextFilterFn,
          // Or, override the default text filter to use
          // "startWith"
          text: (rows, id, filterValue) => {
            return rows.filter(row => {
              const rowValue = row.values[id]
              return rowValue !== undefined
                ? String(rowValue)
                  .toLowerCase()
                  .startsWith(String(filterValue).toLowerCase())
                : true
            })
          },
        }),
        []
      )
    
      const defaultColumn = React.useMemo(
        () => ({
          // Let's set up our default Filter UI
          Filter: DefaultColumnFilter,
          minWidth: 75,
          maxWidth: 250
        }),
        []
      )
      let tblinstance;
      let tableParams = {
        columns,
        data,
        defaultColumn,
        filterTypes,
        initialState: {
          pageIndex: doServersideFilter?currentPage:0,
          pageSize: (defaultpagesize && defaultpagesize > 0) ? defaultpagesize : 10,
          sortBy: defaultSortColumn
        },
        manualPagination: doServersideFilter,
        manualSortBy: doServersideFilter,
        manualFilters: doServersideFilter,
        //autoResetPage: false,
        //autoResetSortBy: false,
        // pageCount: controlledPageCount,
        getExportFileBlob,
      };
      if (doServersideFilter) {
        tableParams.pageCount = controlledPageCount;
      }
      const {
        getTableProps,
        getTableBodyProps,
        headerGroups,
        rows,
        prepareRow,
        setAllFilters,
        allColumns,
        getToggleHideAllColumnsProps,
        visibleColumns,
        state,
        page,
        preGlobalFilteredRows,
        setGlobalFilter,
        setHiddenColumns,
        //gotoPage,
       // setPageSize,
        selectedFlatRows,
        setColumnOrder,
        exportData,
        // pageCount,
        gotoPage,
        setPageSize,
        state: {sortBy, pageIndex, pageSize },
      } = tblinstance = useTable(
        {...tableParams},
        useFilters,
        useGlobalFilter,
        useSortBy,
        usePagination,
        useRowSelect,
        useColumnOrder,
        useExportData,
        useFlexLayout,
        useResizeColumns
      );
      const currentColOrder = React.useRef();
      let pageCount = doServersideFilter?controlledPageCount:data.length;
      tmpTableData = data;  
      // while siwtch the task type or Su type, this will set the relavent default sort column
      if (currentTableName && currentTableName !== tablename) {
          state.sortBy = defaultSortColumn
      }
      currentTableName = props.tablename;
      tableOptionsState = _.cloneDeep(state);
      // Pass the table's state to the parent function if the parent function has set the callback function for it.
      if (props.setTableState) {
        props.setTableState(state);
      }
      const [loading, setLoading] = React.useState(false);
      setLoaderFunction = setLoading;
      React.useEffect(() => {
        fetchData({ state, setLoading });
        }, [sortBy, fetchData, pageIndex, pageSize,  filterTypes,]);
    
      React.useEffect(() => {
        setHiddenColumns(
          //  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));
        const storedColOrder = UtilService.localStore({ type: 'get', key: tablename+'colOrder'});
        if (storedColOrder) {
          setColumnOrder(storedColOrder)
        }
        else if (columnOrders && columnOrders.length) {
          if (showAction === 'true') {
            setColumnOrder(['Select', 'Action', ...columnOrders]);
            UtilService.localStore({ type: 'set', key: tablename+'colOrder', value: ['Select', 'Action', ...columnOrders]});
          } else {
            setColumnOrder(['Select', ...columnOrders]);
            UtilService.localStore({ type: 'set', key: tablename+'colOrder', value: ['Select', ...columnOrders]});
          }
        }
        setLoading(dataFetchStatus);
      }, [setHiddenColumns, columns]);
    
      let op = useRef(null);
    
      const [currentpage, setcurrentPage] = React.useState(0);
      const [selectedClickedRow, setSelectedClickedRow] = React.useState([]);
      const [currentrows, setcurrentRows] = React.useState(defaultpagesize);
      const [custompagevalue, setcustompagevalue] = React.useState();
      
      const onPagination = (e) => {
        loadingStatus = true;
        setLoading(true);
        gotoPage(e.page);
        setcurrentPage(e.first);
        setcurrentRows(e.rows);
        setPageSize(e.rows)
        if ([10, 25, 50, 100].includes(e.rows)) {
          setcustompagevalue();
        }
      };
      const onCustomPage = (e) => {
        loadingStatus = true;
        setLoading(true);
        if (typeof custompagevalue === 'undefined' || custompagevalue == null) return;
        gotoPage(0);
        setcurrentPage(0);
        setcurrentRows(custompagevalue);
        setPageSize(custompagevalue);
      };
    
      const onChangeCustompagevalue = (e) => {
        setcustompagevalue(e.target.value);
      }
    
      const onShowAllPage = (e) => {
        loadingStatus = true;
        setLoading(true);
        gotoPage(0);
        setcurrentPage(0);
        setcurrentRows(0);
        setPageSize(pageCount)
        setcustompagevalue();
      };
    
      const onColumnToggleViewTable = (selectedColumn, sortedColumn) => {
        let visibleColumn = {};
        let viewColumn = {};
        if (selectedColumn && selectedColumn.Header === sortedColumn.Header && !selectedColumn.isVisible) {
          visibleColumn = getFirstVisibleColumn(selectedColumn, allColumns);     
          viewColumn = { Header: visibleColumn.Header, desc: checkDescendingColumnExists(visibleColumn.Header.toLowerCase())};
          let tempdefaultSortColumn = [{ id: viewColumn.Header, desc: viewColumn.desc }];
          if (lsKeySortColumn && lsKeySortColumn.trim().length > 0) {
            localStorage.setItem(lsKeySortColumn, JSON.stringify(tempdefaultSortColumn));
          }
        }
        visibleColumn.Header = visibleColumn.Header || "";
        return viewColumn;
      }
    
      const onToggleChange = (e) => {
        let lsToggleColumns = [];
        let selectedColumn = null;
        let sortedColumn = {};
        let defaultVisible = false;
        if (e.target.id === '') {
          defaultVisible = e.target.checked;
        } 
        // allColumns.forEach(acolumn => {
        for (const acolumn of allColumns) {
          let jsonobj = {};
          let visible = (acolumn.Header === e.target.id) ? ((acolumn.isVisible) ? false : true) : e.target.id === '' ? defaultVisible : acolumn.isVisible;
          jsonobj['Header'] = acolumn.Header;
          jsonobj['isVisible'] = visible;
          lsToggleColumns.push(jsonobj)
          selectedColumn = (acolumn.Header === e.target.id) ? jsonobj : selectedColumn;
          if (acolumn.isSorted) {
            sortedColumn['Header'] = acolumn.Header;
            sortedColumn['isVisible'] = visible;
          }
          // Remove the column filters stored and clear the column filter, if the column is toogled to 
          if (!visible) {
              if (storeFilter) {
                  TableUtil.clearColumnFilter(currentTableName, acolumn.Header);
              }
              _.remove(tableOptionsState.filters, ['id', acolumn.Header]);
              setAllFilters(tableOptionsState.filters);
          }
        }
      // });
        localStorage.setItem(tablename, JSON.stringify(lsToggleColumns));
    
        if (onColumnToggleViewTable) {
          let columnTobeSorted = onColumnToggleViewTable(selectedColumn, sortedColumn); //onColumnToggle(selectedColumn, sortedColumn);
          columnTobeSorted.Header = columnTobeSorted.Header || "";
          if (columnTobeSorted.Header.trim().length > 0) {
            tblinstance.toggleSortBy(columnTobeSorted.Header, columnTobeSorted.desc);
          }
        }   
      }
      
      filteredData = _.map(rows, 'values');
      if (parentCallbackFunction) {
        parentCallbackFunction(filteredData);
      }
    
      /* Select only rows than can be selected. This is required when ALL is selected */
      selectedRows = _.filter(selectedFlatRows, selectedRow => { return (selectedRow.original.canSelect === undefined || selectedRow.original.canSelect) });
      /* Take only the original values passed to the component */
      selectedRows = _.map(selectedRows, 'original');
      /* Callback the parent function if available to pass the selected records on selection */
      if (parentCBonSelection && selectedRows != selectedClickedRow && selectedRows.length != 0) {
        parentCBonSelection(selectedRows)
      }
    
      const onSortBy = () => {
        sessionStorage.setItem("sortedData", tbldata);
      }
    
      /**
       * Clear all filters in table and reload the data
       */
      const clearAllFilter = () => {
        hasFilters = false;
        setAllFilters([]);
        tableOptionsState.filters = [];
        if (doServersideFilter) {
          filterCallback(tableOptionsState, setLoaderFunction);
        }
        if (storeFilter) {
            TableUtil.clearTableFilter(currentTableName);
        }
      }
      
      return (
        <>
          <div style={{display:'flex',justifyContent:'space-between',height:'35px'}}>
            <div id="block_container" >
              {allowColumnSelection &&
                <div style={{ textAlign: 'left', marginRight: '30px' }} title='Toggle Columns'>
                  <i className="fa fa-columns col-filter-btn" label="Toggle Columns" onClick={(e) => op.current.toggle(e)} />
                  {showColumnFilter &&
                    <div style={{ position: "relative", top: "-25px", marginLeft: "50px", color: "#005b9f" }} onClick={() => clearAllFilter()} >
                      <i class="fas fa-sync-alt" title="Clear All Filters"></i></div>}
                  <OverlayPanel ref={op} id="overlay_panel" showCloseIcon={false} >
                    <div>
                      <div style={{ textAlign: 'center' }}>
                        <label>Select column(s) to view</label>
                      </div>
                      <div style={{ float: 'left', backgroundColor: '#d1cdd936', width: '250px', height: '400px', overflow: 'auto', marginBottom: '10px', padding: '5px' }}>
                        <div id="tagleid"  >
                          <div >
                            <div style={{ marginBottom: '5px' }}>
                              <IndeterminateCheckbox {...getToggleHideAllColumnsProps()} onClick={(e) => onToggleChange(e)} /> Select All
                                </div>
                            {allColumns.map(column => (
                              <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={(e) => onToggleChange(e)}
                                /> {
                                  (defaultheader[column.id]) ? defaultheader[column.id] : (optionalheader[column.id] ? optionalheader[column.id] : column.id)}
                              </div>
                            ))}
                            <br />
                          </div>
                        </div>
                      </div>
                    </div>
                  </OverlayPanel>
                </div>
              }
              <div style={{ textAlign: 'right' }}>
                {tbldata && tbldata.length > 0 && !isunittest && showGlobalFilter &&
                  <GlobalFilter
                    preGlobalFilteredRows={preGlobalFilteredRows}
                    globalFilter={state.globalFilter}
                    setGlobalFilter={setGlobalFilter}
                  />
                }
              </div>
    
              {showTopTotal && !hasFilters &&
                <div className="total_records_top_label"> <label >Total records ({pageCount})</label></div>
              }
    
              {showTopTotal && hasFilters &&
                <div className="total_records_top_label" ><label >Filtered {filteredData.length} from {pageCount}</label></div>}
             
            </div>
            {showCSV &&
              <div className="total_records_top_label" style={{ marginTop: '3px', marginRight: '5px' }} >
                <a href="#" onClick={() => { exportData("csv", false); }} title="Download CSV" style={{ verticalAlign: 'middle' }}>
                  <i class="fas fa-file-csv" style={{ color: 'green', fontSize: '20px' }} ></i>
                </a>
              </div>
              /* 
                <div className="total_records_top_label" >
                  <a href="#"  onClick={() => {exportData("pdf", false);}} title="Download PDF" style={{verticalAlign: 'middle'}}>
                      <i class="fas fa-file-pdf" style={{color: 'red', fontSize: '20px'}}></i>
                  </a>
                </div> */
            }
          </div>
    
          <div className="tmss-table table_container">
            <table {...getTableProps()} data-testid="viewtable" className="viewtable" >
              <thead>
                {headerGroups.map(headerGroup => (
                  <DragDropContext
                    onDragStart={() => {
                      currentColOrder.current = allColumns.map(column => column.id);
                    }}
                    onDragUpdate={(dragUpdateObj, b) => {
                      const colOrder = [...currentColOrder.current];
                      const sIndex = dragUpdateObj.source.index;
                      const dIndex = dragUpdateObj.destination && dragUpdateObj.destination.index;
                      if(typeof sIndex === 'number' && typeof dIndex === "number") {
                        colOrder.splice(sIndex, 1);
                        colOrder.splice(dIndex, 0, dragUpdateObj.draggableId);
                        setColumnOrder(colOrder);
                        UtilService.localStore({ type: 'set', key: tablename+'colOrder', value: colOrder}); 
                      }
                    }}
                  >
                    <Droppable droppableId="droppable" direction="horizontal">
                      {(droppableProvided, snapshot) => (
                        <tr {...headerGroup.getHeaderGroupProps()}
                        ref={droppableProvided.innerRef}>
                          {headerGroup.headers.map((column,index) => (
                            <Draggable
                            key={column.id}
                            draggableId={column.id}
                            index={index}
                            isDragDisabled={_.includes(['Select', 'Action', 'Status Logs'], column.id)? true: false}>
                              {(provided, snapshot) => {
                                return (
                                  <th className={column.id} className={_.includes(['Select', 'Action', 'Status Logs'], column.id)?'fixed-column-td':''} style={{display: 'flex'}}
                                    onClick={() => {
                                      if(!doServersideFilter) {
                                        toggleBySorting({ 'id': column.id, desc: (column.isSortedDesc != undefined ? !column.isSortedDesc : false) });
                                      }
                                  }}>
                                    <div style={{display:'flex'}}>
                                    <div style={{display: 'grid',verticalAlign:'bottom'}}>
                                      <div {...column.getHeaderProps(column.getSortByToggleProps())} className={_.includes(['Select', 'Action', 'Status Logs'], column.id)?'fixed-column':''}>
                                      <div
                                        {...provided.draggableProps}
                                        {...provided.dragHandleProps}
                                        // {...extraProps}
                                        ref={provided.innerRef}
                                        style={{
                                          ...getItemStyle(
                                            snapshot,
                                            provided.draggableProps.style
                                          )
                                          // ...style
                                        }}>
                                        {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>) : ""
                                          : ""
                                        }
                                      </div>
                                    </div>
                                    {/* Render the columns filter UI */}
                                    {column.Header !== 'actionpath' &&
                                      // <div className={columnclassname[0][column.Header]}>
                                      <div {...column.getHeaderProps(column.getSortByToggleProps())} >
                                        {column.canFilter && column.Header !== 'Action' ? column.render('Filter') : null}
                                      </div>
                                    }
                                    </div>
                                    </div>
                                    {_.includes(['Select', 'Action', 'Status Logs'], column.id)?<></>:
                                    <div {...column.getResizerProps()}
                                          className={`resizer ${
                                            column.isResizing ? 'isResizing' : ''
                                          }`}
                                        >
                                    </div> 
                                    }
                                  </th>
                                );
                              }}
                            </Draggable>
                          ))}
                        </tr>
                      )}
                    </Droppable>
                  </DragDropContext>
                ))}
                {(doServersideFilter && loading) && 
                <tr style={{height: "5px"}}><td colSpan={columns.length} style={{padding: "0px"}}>
                <div><ProgressBar mode="indeterminate" style={{ height: '5px' }}/></div>
                </td></tr>}
              </thead>
              {/* If want to to clear the existing data while loading, remove the commented line below */}
              {/* {((doServersideFilter && !loading) || !doServersideFilter) &&  */}
              <tbody {...getTableBodyProps()}>
                {page.map((row, i) => {
                  prepareRow(row)
                  return (
                    <tr {...row.getRowProps()}>
                      {row.cells.map(cell => {
                        if (cell.column.id !== 'actionpath') {
                          // return <td {...cell.getCellProps()} className={cell.column.id+'_body'}>
                          return <td className={cell.column.id+'_body'} className={_.includes(['Select', 'Action', 'Status Logs'], cell.column.id)?'fixed-column-td':''}>
                            {(cell.row.original.links || []).includes(cell.column.id) ? <a href={cell.row.original.linksURL[cell.column.id]}>{cell.render('Cell', cell.getCellProps())}</a> : cell.render('Cell', cell.getCellProps())}
                          </td>
                        }
                        else {
                          return "";
                        }
                      }
                      )}
                    </tr>
                  );
                })}
                
              </tbody>
              {/* } */}
            </table>
          </div>
          <div>{(doServersideFilter && loading) && <ProgressBar mode="indeterminate" style={{ height: '5px' }}/>}</div>
          <div className="pagination p-grid" >
            {tableOptionsState.filters.length === 0 &&
              <div className="total_records_bottom_label" ><label >Total records ({pageCount})</label></div>
            }
            {tableOptionsState.filters.length > 0 &&
              <div className="total_records_bottom_label" ><label >Filtered {filteredData.length} from {pageCount}</label></div>
            }
            <div>
              <Paginator rowsPerPageOptions={[10, 25, 50, 100]} first={currentpage} rows={currentrows} totalRecords={doServersideFilter?pageCount:rows.length} onPageChange={onPagination}></Paginator>
            </div>
            <div>
              <InputNumber id="custompage" value={custompagevalue} onChange={onChangeCustompagevalue}
                min={0} style={{ width: '100px' }} />
              <label >Records/Page</label>
              <Button onClick={onCustomPage}> Show </Button>
              <Button onClick={onShowAllPage} style={{ marginLeft: "1em" }}> Show All </Button>
            </div>
          </div>
        </>
      )
    }
    
    
    // Define a custom filter filter function!
    function filterGreaterThan(rows, id, filterValue) {
      return rows.filter(row => {
        const rowValue = row.values[id]
        return rowValue >= filterValue
      })
    }
    
    // This is an autoRemove method on the filter function that
    // when given the new filter value and returns true, the filter
    // will be automatically removed. Normally this is just an undefined
    // check, but here, we want to remove the filter if it's not a number
    filterGreaterThan.autoRemove = val => typeof val !== 'number'
    
    function ViewTable(props) {
      const history = useHistory();
      tbldata = JSON.parse(sessionStorage.getItem("sortedData")) || props.data;
      data = tbldata;
      let pageCount = props.totalPage || data.length;
      showCSV = (props.showCSV) ? props.showCSV : false;
      doServersideFilter = (props.callBackFunction)?true:false;
      parentCallbackFunction = props.filterCallback;
      parentCBonSelection = props.onRowSelection;
      isunittest = props.unittest;
      columnclassname = props.columnclassname;
      loadingStatus = props.loadingStatus === undefined ? loadingStatus :  props.loadingStatus;
      showTopTotal = props.showTopTotal === undefined ? true : props.showTopTotal;
      showGlobalFilter = props.showGlobalFilter === undefined ? true : props.showGlobalFilter;
      showColumnFilter = props.showColumnFilter === undefined ? true : props.showColumnFilter;
      allowColumnSelection = props.allowColumnSelection === undefined ? true : props.allowColumnSelection;
      allowRowSelection = props.allowRowSelection === undefined ? false : props.allowRowSelection;
      let pageUpdated = props.pageUpdated === undefined ? true : props.pageUpdated;
    
      // Default Header to show in table and other columns header will not show until user action on UI
      let defaultheader = props.defaultcolumns;
      let optionalheader = props.optionalcolumns;
      let defaultSortColumn = props.defaultSortColumn;
      storeFilter = props.storeFilter? props.storeFilter : false
      let tablename = (props.tablename) ? props.tablename : window.location.pathname;
    
      if (!defaultSortColumn) {
        defaultSortColumn = [{}];
      }
      let defaultpagesize = (typeof props.defaultpagesize === 'undefined' || props.defaultpagesize == null) ? 10 : props.defaultpagesize;
      let columns = [];
      let defaultdataheader = Object.keys(defaultheader[0]);
      let optionaldataheader = Object.keys(optionalheader[0]);
    
      // Get Tooltips for each column if provided and used in filter components
      tableToolTipsState = {};
      for(const headerId of defaultdataheader) {
          if (defaultheader[0][headerId].tooltip) {
              tableToolTipsState[defaultheader[0][headerId].name] = defaultheader[0][headerId].tooltip;
          }
       }
      for(const headerId of optionaldataheader) {
        if (optionalheader[0][headerId].tooltip) {
            tableToolTipsState[optionalheader[0][headerId].name] = optionalheader[0][headerId].tooltip;
        }
      }
    
      /* If allowRowSelection property is true for the component, add checkbox column as 1st column.
         If the record has property to select, enable the checkbox */
      if (allowRowSelection) {
        columns.push({
          Header: ({ getToggleAllRowsSelectedProps }) => {
            return (
              <div>
                <IndeterminateCheckbox {...getToggleAllRowsSelectedProps()} style={{ width: '15px', height: '15px' }} />
              </div>
            )
          },
          id: 'Select',
          accessor: props.keyaccessor,
          Cell: ({ row }) => {     
            return (
              <div>
                {(row.original.canSelect === undefined || row.original.canSelect) &&
                  <IndeterminateCheckbox {...row.getToggleRowSelectedProps()} 
                  attr-id={row.original.id}
                  style={{ width: '15px', height: '15px' }} />
                }
                {row.original.canSelect === false &&
                  <input type="checkbox" checked={false} disabled style={{ width: '15px', height: '15px' }}></input>
                }
              </div>
            )
          },
          disableFilters: true,
          disableSortBy: true,
          isVisible: true,
        });
      }
    
      if (props.showaction) {
        columns.push({
          Header: 'Action',
          id: 'Action',
          accessor: props.keyaccessor,
          Cell: props => <Link to={{pathname: props.cell.row.values['actionpath']}}className='p-link' onClick={(e) => navigateTo(e, props)} ><i className="fa fa-eye" style={{ cursor: 'pointer' }}></i></Link>,
          disableFilters: true,
          disableSortBy: true,
          //isVisible: defaultdataheader.includes(props.keyaccessor),
          isVisible: true
        })
      }
    
      const navigateTo = (cellProps) => () => {
        if (cellProps.cell.row.values['actionpath']) {
          if (!props.viewInNewWindow) {
            return history.push({
              pathname: cellProps.cell.row.values['actionpath'],
              state: {
                "id": cellProps.value,
              }
            })
          } else {
            window.open(cellProps.cell.row.values['actionpath'], '_blank');
          }
        }
        // Object.entries(props.paths[0]).map(([key,value]) =>{})
      }
    
      //Default Columns
      defaultdataheader.forEach(header => {
        const isString = typeof defaultheader[0][header] === 'string';
        const disableSortBy = defaultheader[0][header].disableSortBy;
        const disableFilter = defaultheader[0][header].disableFilters;
        const filterFn = (showColumnFilter ? (isString ? DefaultColumnFilter : (filterTypes[defaultheader[0][header].filter] && filterTypes[defaultheader[0][header].filter].fn ? filterTypes[defaultheader[0][header].filter].fn : DefaultColumnFilter)) : "");
        const filtertype = (showColumnFilter ? (!isString && filterTypes[defaultheader[0][header].filter] && filterTypes[defaultheader[0][header].filter].type) ? filterTypes[defaultheader[0][header].filter].type : 'fuzzyText' : "");
        columns.push({
          Header: isString ? defaultheader[0][header] : defaultheader[0][header].name,
          id: isString ? defaultheader[0][header] : defaultheader[0][header].name,
          accessor: header,
          filter: filtertype,
          Filter: filterFn,
          disableSortBy: doServersideFilter?typeof disableSortBy !== 'undefined' ? disableSortBy : true:false,
          disableFilters: doServersideFilter?typeof disableFilter !== 'undefined' ? disableFilter : true:false,
          //minResizeWidth: 50,
          //*** TO REMOVE - INCOMING CHANGE */
          // filter: (showColumnFilter?((!isString && defaultheader[0][header].filter=== 'date') ? 'includes' : 'fuzzyText'):""),
          // Filter: (showColumnFilter?(isString ? DefaultColumnFilter : (filterTypes[defaultheader[0][header].filter] ? filterTypes[defaultheader[0][header].filter] : DefaultColumnFilter)):""),
          isVisible: true,
          Cell: props => { return <div style={{...props.style}}> {updatedCellvalue(header, props.value, defaultheader[0][header])} </div>},
        })
      })
    
      //Optional Columns
      optionaldataheader.forEach(header => {
        const isString = typeof optionalheader[0][header] === 'string';
        const disableSortBy = optionalheader[0][header].disableSortBy;
        const disableFilter = optionalheader[0][header].disableFilters;
        const filterFn = (showColumnFilter ? (isString ? DefaultColumnFilter : (filterTypes[optionalheader[0][header].filter] && filterTypes[optionalheader[0][header].filter].fn ? filterTypes[optionalheader[0][header].filter].fn : DefaultColumnFilter)) : "");
        const filtertype = (showColumnFilter ? (!isString && filterTypes[optionalheader[0][header].filter]) ? (filterTypes[optionalheader[0][header].filter].type || filterTypes[optionalheader[0][header].filter]) : 'fuzzyText' : "");
        columns.push({
          Header: isString ? optionalheader[0][header] : optionalheader[0][header].name,
          id: isString ? header : optionalheader[0][header].name,
          accessor: header,
          filter: filtertype,
          Filter: filterFn,
          disableSortBy: doServersideFilter?typeof disableSortBy !== 'undefined' ? disableSortBy : true:false,
          disableFilters: doServersideFilter?typeof disableFilter !== 'undefined' ? disableFilter : true:false,
          isVisible: false,
          Cell: props => <div style={{...props.style}}> {updatedCellvalue(header, props.value, optionalheader[0][header])} </div>,
        })
      });
    
      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;
        });
      }
    
      function updatedCellvalue(key, value, properties) {
        try {
          if (typeof value == "boolean") {
            return value.toString();
          } 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)
        }
        return value;
      };
    
      /**
       * To fetch data from server side - Start
       */
      // const [loading, setLoading] = React.useState(false);
      const [currentPage, setCurrentPage] = React.useState(0);
      const fetchData = React.useCallback( ({ state, setLoading }) => {
          loadServerData(state, setLoading, true);
      }, []);
      
      const loadServerData = (state, setLoading, onload) => {
          //setLoading(true);
          loadingStatus = true;
          setCurrentPage(state.pageIndex);
          if(props.callBackFunction) {
            if(storeFilter) {
              if (onload) {
                let filters = UtilService.localStore({ type: 'get', key: tablename });
                UtilService.localStore({ type: 'set', key: tablename, value: filters});    
              } else {
                UtilService.localStore({ type: 'set', key: tablename, value: state.filters});    
              }
            }
              const promises = [props.callBackFunction(state)];
              Promise.all(promises).then(async responses => {
                  tbldata = responses[0][0];
                  if (tbldata) {
                      //setData(tbldata);
                      //setPageCount(Math.ceil(responses[0][1]));
                      pageCount = await Math.ceil(responses[0][1]);
                      if (setLoading) {
                        setLoading(false);
                      }
                      loadingStatus = false;
                  }
              });
          } else {
              if(tbldata) {
                  const startRow = state.pageSize * state.pageIndex;
                  const endRow = startRow + state.pageSize;
                  //setData(tbldata.slice(startRow, endRow));
                  //setPageCount(Math.ceil(tbldata.length));
                  data = tbldata.slice(startRow, endRow);
                  pageCount = Math.ceil(tbldata.length);
                  setLoading(false);
                  loadingStatus = false;
              }
          }
      }
      // Set the filterCallback function to load on filter changes
      filterCallback = loadServerData;
      // Set the reloadCallback function in the parent if it has passed the callback function.
      if (props.setTableReloadFunction) {
        props.setTableReloadFunction(loadServerData);
      }
      // Callback function to load on option list values
      showFilterOption = props.showFilterOption;
      
      //If page not load with fresh data then set existing data, otherwise it will reset the checkbox selection in table
      if (!pageUpdated) {
          data = tmpTableData;
      }
      return (
        <div>
          <Table fetchData={fetchData} pageCount={pageCount} currentPage={currentPage} dataFetchStatus={loadingStatus} columns={columns}
            data={data} defaultheader={defaultheader[0]} optionalheader={optionalheader[0]} showAction={props.showaction}
            defaultSortColumn={defaultSortColumn} tablename={tablename} defaultpagesize={defaultpagesize} columnOrders={props.columnOrders} 
            toggleBySorting={(sortData) => {if(props.toggleBySorting){props.toggleBySorting(sortData)}}} onColumnToggle={props.onColumnToggle} lsKeySortColumn={props.lsKeySortColumn}
            descendingColumn={props.descendingColumn} ignoreSorting={props.ignoreSorting} setTableState={props.setTableState} />
        </div>
      )
    }
    
    export default ViewTable