Select Git revision
ViewTable.js
-
Ramesh Kumar authoredRamesh Kumar authored
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