Last active
July 14, 2020 15:17
-
-
Save FilipIlievski/3afda30c5d9585b868047c1305faef06 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import { | |
createTableMultiSort, | |
Column, | |
Table, | |
SortDirection, | |
} from "react-virtualized"; | |
import "./styles.css"; | |
import { orderBy, sortBy } from "lodash"; | |
// NOTE: Based on https://github.com/bvaughn/react-virtualized/blob/master/docs/multiColumnSortTable.md | |
const rows = [ | |
{ | |
id: "200880", | |
names: { de: "B Weg ", en: "B Weg " }, | |
}, | |
{ | |
id: "200878", | |
names: { de: "A", en: "A" }, | |
}, | |
{ | |
id: "200881", | |
names: { de: "C", en: "C" }, | |
}, | |
{ | |
id: "200882", | |
names: { de: "D", en: "D" }, | |
}, | |
{ | |
id: "200883", | |
names: { de: "E", en: "E" }, | |
}, | |
]; | |
const columns = [ | |
{ | |
dataKey: "stopName", | |
label: "stopName", | |
width: 200, | |
cellRenderer: ({ | |
rowData: { | |
id, | |
names: { de: stopName }, | |
}, | |
dataKey, | |
}) => ( | |
<div style={{ border: "1px solid black" }} id={id}> | |
<p>{stopName}</p> | |
</div> | |
), | |
}, | |
{ | |
dataKey: "stopId", | |
label: "stopId", | |
width: 200, | |
cellRenderer: ({ rowData: { id }, dataKey }) => ( | |
<div style={{ border: "1px solid black" }} id={id}> | |
<p>{id}</p> | |
</div> | |
), | |
}, | |
{ | |
dataKey: "avgWalkingDist", | |
label: "avgWalkingDist", | |
width: 200, | |
cellRenderer: ({ rowData: { id, combinedWalkingDistance }, dataKey }) => ( | |
<div style={{ border: "1px solid black" }} id={id}> | |
<p>{combinedWalkingDistance}</p> | |
</div> | |
), | |
}, | |
]; | |
const DataTableSortIcon = ({ active, order, ...props }) => { | |
const activeColor = "#00f"; | |
const defaultColor = "#000"; | |
const upperArrow = active && order === "desc" ? activeColor : defaultColor; | |
const lowerArrow = active && order === "asc" ? activeColor : defaultColor; | |
return ( | |
<svg width={12} height={13} fill="none" {...props}> | |
<path d="M1 8L6 13L11 8H1Z" fill={upperArrow} /> | |
<path d="M11 5L6 0L1 5L11 5Z" fill={lowerArrow} /> | |
</svg> | |
); | |
}; | |
export const SortIndicator = ({ active, sortDirection }) => { | |
return ( | |
<DataTableSortIcon | |
active={active} | |
order={ | |
sortDirection === SortDirection.ASC | |
? "asc" | |
: sortDirection === SortDirection.DESC | |
? "desc" | |
: null | |
} | |
/> | |
); | |
}; | |
const defaultSortState = { | |
defaultSortBy: ["stopId", "avgWalkingDist"], | |
defaultSortDirection: { | |
stopId: "DESC", | |
avgWalkingDist: "ASC", | |
}, | |
}; | |
const VirtualizedMultiSortingTable = (tableProps) => { | |
// sort function | |
const sortFunc = ({ row, sortBy }) => { | |
return sortBy.map((sortField) => { | |
switch (sortField) { | |
case "stopId": | |
return +row.id; | |
case "stopName": | |
return row?.names?.de; | |
case "avgWalkingDist": | |
return row.combinedWalkingDistance || 0; | |
default: | |
return +row.id; | |
} | |
}); | |
}; | |
// sorting the provided list | |
const sortList = ({ sortBy, sortDirection }) => { | |
return orderBy( | |
rows, | |
(row) => sortFunc({ row, sortBy }), | |
Object.values(sortDirection).map((val) => val.toLowerCase()) | |
); | |
}; | |
// **start** local state | |
const [sortByState, setSortByState] = React.useState( | |
defaultSortState.defaultSortBy | |
); | |
const [sortDirectionState, setSortDirectionState] = React.useState( | |
defaultSortState.defaultSortDirection | |
); | |
const [sortListState, setsortListState] = React.useState(null); | |
// ** end ** local state | |
// callback for the createTableMultiSort() | |
const sort = ({ sortBy, sortDirection }) => { | |
const sortedList = sortList({ | |
sortBy: sortByState, | |
sortDirection: sortDirectionState, | |
}); | |
setsortListState(sortedList); | |
setSortByState(Array.from(new Set([sortByState, sortBy].flat(Infinity)))); | |
setSortDirectionState({ ...sortDirectionState, ...sortDirection }); | |
return sortedList; | |
}; | |
const sortState = createTableMultiSort(sort); | |
// | |
// 🤔 | |
sortState.sortBy = sortByState; | |
sortState.sortDirection = sortDirectionState; | |
console.log(sortState); | |
const headerRenderer = ({ dataKey, label }) => { | |
const showSortIndicator = sortByState?.includes(dataKey); | |
return ( | |
<div | |
style={{ display: "flex", background: "skyblue", marginRight: "5px" }} | |
> | |
<span title={label}>{label}</span> | |
{showSortIndicator && ( | |
<SortIndicator | |
active={showSortIndicator} | |
sortDirection={sortDirectionState[dataKey]} | |
/> | |
)} | |
</div> | |
); | |
}; | |
return ( | |
<div | |
style={{ display: "flex", flexDirection: "column", marginTop: "30px" }} | |
> | |
<Table | |
{...tableProps} | |
sort={sortState.sort} | |
// sortBy={undefined} | |
// sortDirection={undefined} | |
sortBy={sortByState} | |
sortDirection={sortDirectionState} | |
// sortBy={sortState.sortBy} | |
// sortDirection={sortState.sortDirection} | |
width={600} | |
height={600} | |
headerHeight={30} | |
rowHeight={50} | |
rowCount={rows.length} | |
rowGetter={({ index }) => rows[index]} | |
> | |
{columns.map((column) => { | |
return ( | |
<Column | |
// style={{ ...headerColumn }} | |
{...column} | |
key={column.dataKey} | |
width={300} | |
headerRenderer={headerRenderer} | |
/> | |
); | |
})} | |
</Table> | |
<pre>{JSON.stringify(sortState)}</pre> | |
</div> | |
); | |
}; | |
export default VirtualizedMultiSortingTable; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment