diff --git a/Plan/react/dashboard/src/components/extensions/ExtensionTable.js b/Plan/react/dashboard/src/components/extensions/ExtensionTable.js index a0e01ec9c..a96a8a240 100644 --- a/Plan/react/dashboard/src/components/extensions/ExtensionTable.js +++ b/Plan/react/dashboard/src/components/extensions/ExtensionTable.js @@ -1,8 +1,10 @@ -import React, {useState} from 'react'; +import React, {useCallback, useState} from 'react'; import {useTheme} from "../../hooks/themeHook"; import {useTranslation} from "react-i18next"; import ExtensionIcon, {toExtensionIconHtmlString} from "./ExtensionIcon"; import DataTablesTable from "../table/DataTablesTable"; +import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; +import {faSort, faSortDown, faSortUp} from "@fortawesome/free-solid-svg-icons"; const ExtensionDataTable = ({table}) => { const [id] = useState("extension-table-" + new Date().getTime() + "-" + (Math.floor(Math.random() * 100000))); @@ -39,22 +41,65 @@ const ExtensionDataTable = ({table}) => { ) } +const sortComparator = (columnIndex) => (rowA, rowB) => { + const a = rowA[columnIndex].valueUnformatted; + const b = rowB[columnIndex].valueUnformatted; + if (a === b) return 0; + if (isNaN(Number(a)) || isNaN(Number(b))) { + return String(a).toLowerCase().localeCompare(String(b).toLowerCase()); + } else { + const numA = Number(a); + const numB = Number(b); + if (numA < numB) return -1; + if (numA > numB) return 1; + return 0; + } +} + +const sortRows = (rows, sortIndex, sortReversed) => { + if (sortIndex === undefined) return rows; + + const comparator = sortComparator(sortIndex); + const sorted = rows.sort(comparator); + if (sortReversed) return rows.reverse(); + return sorted; +} + const ExtensionColoredTable = ({table}) => { const {nightModeEnabled} = useTheme(); const {t} = useTranslation(); - const rows = table.table.rows.length ? table.table.rows.map((row, i) => {row.map((value, j) => {value.value || String(value)})}) : + const [sortBy, setSortBy] = useState(undefined); + const [sortReverse, setSortReverse] = useState(false); + const changeSort = useCallback(index => { + if (index === sortBy) { + setSortReverse(!sortReverse); + } else { + setSortBy(index); + setSortReverse(false); + } + + }, [sortBy, setSortBy, sortReverse, setSortReverse]); + + const rows = table.table.rows.length ? sortRows(table.table.rows, sortBy, sortReverse) + .map((row, i) => {row.map((value, j) => {value.value || String(value)})}) : {table.table.columns.map((column, i) => - {i === 0 ? t('generic.noData') : '-'})} + {i === 0 ? t('generic.noData') : '-'})} return ( - {table.table.columns.map((column, i) => )} diff --git a/Plan/react/dashboard/src/style/style.css b/Plan/react/dashboard/src/style/style.css index e7b8988b8..012d4bb82 100644 --- a/Plan/react/dashboard/src/style/style.css +++ b/Plan/react/dashboard/src/style/style.css @@ -1429,4 +1429,8 @@ ul.filters { .contributor { width: 33%; +} + +.extension-table-header { + cursor: pointer; } \ No newline at end of file
{column} + {table.table.columns.map((column, i) => changeSort(i)}> + +   + {column} +   +