From dae9ebe3627c38a739c8870deaa816929c0d9a00 Mon Sep 17 00:00:00 2001 From: Aurora Lahtela <24460436+AuroraLS3@users.noreply.github.com> Date: Sun, 15 Oct 2023 18:16:23 +0300 Subject: [PATCH] Various fixes to tables - Fixed errors related to how sortBy changes when column visibility is toggled. - Fixed player page links in extension tables - All Extension tables are now colored DataTables instead of being different based on row count. --- .../datatransfer/extension/TableDto.java | 3 +- .../json/PlayersTableJSONCreator.java | 4 +- .../components/extensions/ExtensionTable.js | 105 +++--------------- .../src/components/table/DataTablesTable.js | 19 ++-- 4 files changed, 31 insertions(+), 100 deletions(-) diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/domain/datatransfer/extension/TableDto.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/domain/datatransfer/extension/TableDto.java index c7d9b7dfe..2f333fc61 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/domain/datatransfer/extension/TableDto.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/domain/datatransfer/extension/TableDto.java @@ -20,6 +20,7 @@ import com.djrapitops.plan.delivery.formatting.Formatters; import com.djrapitops.plan.delivery.rendering.html.Html; import com.djrapitops.plan.extension.table.Table; import com.djrapitops.plan.extension.table.TableColumnFormat; +import org.apache.commons.text.StringEscapeUtils; import java.util.ArrayList; import java.util.Arrays; @@ -76,7 +77,7 @@ public class TableDto { case DATE_SECOND: return Formatters.getInstance().secondLong().apply(Long.parseLong(value.toString())); case PLAYER_NAME: - return Html.LINK.create("../player/" + Html.encodeToURL(value.toString())); + return Html.LINK.create("../player/" + Html.encodeToURL(value.toString()), StringEscapeUtils.escapeHtml4(value.toString())); default: return value.toString(); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/json/PlayersTableJSONCreator.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/json/PlayersTableJSONCreator.java index 0e52758d7..eecef90fb 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/json/PlayersTableJSONCreator.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/json/PlayersTableJSONCreator.java @@ -201,7 +201,9 @@ public class PlayersTableJSONCreator { Html link = openPlayerPageInNewTab ? Html.LINK_EXTERNAL : Html.LINK; - putDataEntry(dataJson, link.create(url, StringUtils.replace(StringEscapeUtils.escapeHtml4(name), "\\", "\\\\") /* Backslashes escaped to prevent json errors */), "name"); + /* Backslashes escaped to prevent json errors */ + String escapedName = StringUtils.replace(StringEscapeUtils.escapeHtml4(name), "\\", "\\\\"); + putDataEntry(dataJson, link.create(url, escapedName, escapedName), "name"); putDataEntry(dataJson, activityIndex.getValue(), activityString, "index"); putDataEntry(dataJson, activePlaytime, numberFormatters.get(FormatType.TIME_MILLISECONDS).apply(activePlaytime), "activePlaytime"); putDataEntry(dataJson, loginTimes, "sessions"); diff --git a/Plan/react/dashboard/src/components/extensions/ExtensionTable.js b/Plan/react/dashboard/src/components/extensions/ExtensionTable.js index 312a41427..ced5e8cd4 100644 --- a/Plan/react/dashboard/src/components/extensions/ExtensionTable.js +++ b/Plan/react/dashboard/src/components/extensions/ExtensionTable.js @@ -1,15 +1,21 @@ -import React, {useCallback, useState} from 'react'; -import {useTheme} from "../../hooks/themeHook"; -import {useTranslation} from "react-i18next"; +import React, {useState} from 'react'; import ExtensionIcon from "./ExtensionIcon"; import DataTablesTable from "../table/DataTablesTable"; -import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; -import {faSort, faSortDown, faSortUp} from "@fortawesome/free-solid-svg-icons"; import ColoredText from "../text/ColoredText"; +import {baseAddress} from "../../service/backendConfiguration"; const ExtensionDataTable = ({table}) => { const [id] = useState("extension-table-" + new Date().getTime() + "-" + (Math.floor(Math.random() * 100000))); + const mapToCell = (value, j) => { + if (String(value).startsWith("; + } + return + }; + const data = { columns: table.table.columns.map((column, i) => { return { @@ -24,7 +30,7 @@ const ExtensionDataTable = ({table}) => { const dataRow = {}; row.forEach((cell, j) => { dataRow[`col${j}Value`] = cell['valueUnformatted'] || cell.value || cell; - dataRow[`col${j}Display`] = cell.value || cell; + dataRow[`col${j}Display`] = mapToCell(cell.value || cell, j); }); return dataRow; }) @@ -37,96 +43,17 @@ const ExtensionDataTable = ({table}) => { pagingType: "numbers", order: [[1, "desc"]] } - return ( - - ) -} - -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 rowKeyFunction = (row, column) => { + return JSON.stringify(Object.entries(row).filter(e => e[0].includes('Value'))) + "-" + JSON.stringify(column?.data?._); } -} - -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 [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 mapToCell = (value, j) => { - if (String(value?.value).startsWith("; - } - return - - ; - }; - - const rows = table.table.rows.length ? sortRows(table.table.rows, sortBy, sortReverse) - .map((row, i) => {row.map(mapToCell)}) : - {table.table.columns.map((column, i) => - {i === 0 ? t('generic.noData') : '-'})} - return ( - - - - {table.table.columns.map((column, i) => changeSort(i)}> - - - {column} - - - )} - - - - {rows} - - + ) } const ExtensionTable = ({table}) => { - const tableLength = table.table.rows.length; - - if (tableLength > 10) { - return - } else { - return - } + return ; } export default ExtensionTable \ No newline at end of file diff --git a/Plan/react/dashboard/src/components/table/DataTablesTable.js b/Plan/react/dashboard/src/components/table/DataTablesTable.js index b56b95fec..092d38826 100644 --- a/Plan/react/dashboard/src/components/table/DataTablesTable.js +++ b/Plan/react/dashboard/src/components/table/DataTablesTable.js @@ -79,7 +79,7 @@ const VisibleColumnsSelector = ({columns, visibleColumnIndexes, toggleColumn}) = ) } -const DataTablesTable = ({id, rowKeyFunction, options}) => { +const DataTablesTable = ({id, rowKeyFunction, options, colorClass}) => { const {t} = useTranslation(); const {nightModeEnabled} = useTheme(); @@ -88,22 +88,23 @@ const DataTablesTable = ({id, rowKeyFunction, options}) => { const [sortReversed, setSortReversed] = useState(options.order[0][1] === 'asc'); const [visibleColumnIndexes, setVisibleColumnIndexes] = useState(columns.map((_, i) => i)); const toggleColumn = useCallback(index => { + const currentSortIndex = visibleColumnIndexes[sortBy]; if (visibleColumnIndexes.includes(index)) { if (visibleColumnIndexes.length === 1) return; const newVisible = visibleColumnIndexes.filter(i => i !== index); newVisible.sort((a, b) => a - b); setVisibleColumnIndexes(newVisible); - if (sortBy === index) { + if (currentSortIndex === index) { setSortBy(0); setSortReversed(false); - } else if (index < sortBy) { + } else if (index <= currentSortIndex) { setSortBy(sortBy - 1); // Keep the current sort } } else { const newVisible = [index, ...visibleColumnIndexes]; newVisible.sort((a, b) => a - b); setVisibleColumnIndexes(newVisible); - if (sortBy >= index) { + if (currentSortIndex >= index) { setSortBy(sortBy + 1); // Keep the current sort } } @@ -198,14 +199,14 @@ const DataTablesTable = ({id, rowKeyFunction, options}) => { - + {columns.length > 2 && - + } - + {visibleColumns.map((column, i) => changeSort(i)}> @@ -268,7 +269,7 @@ const DataTablesTable = ({id, rowKeyFunction, options}) => { )} - + { m: matchingData.length }}/> - +
+
{ m: matchingData.length }}/>