mirror of
https://github.com/meshtastic/web.git
synced 2026-03-12 10:56:13 -04:00
Fix sorting on peers table
Enables sorting by clicking column heading. Defaults to most recent contacts at the top
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { ChevronUpIcon } from "lucide-react";
|
||||
import { ChevronDownIcon, ChevronUpIcon } from "lucide-react";
|
||||
import React, { useState } from "react";
|
||||
|
||||
export interface TableProps {
|
||||
headings: Heading[];
|
||||
@@ -12,6 +13,49 @@ export interface Heading {
|
||||
}
|
||||
|
||||
export const Table = ({ headings, rows }: TableProps): JSX.Element => {
|
||||
const [sortColumn, setSortColumn] = useState<string | null>("Last Heard");
|
||||
const [sortOrder, setSortOrder] = useState<"asc" | "desc">("desc");
|
||||
|
||||
const headingSort = (title: string) => {
|
||||
if (sortColumn === title) {
|
||||
setSortOrder(sortOrder === "asc" ? "desc" : "asc");
|
||||
} else {
|
||||
setSortColumn(title);
|
||||
setSortOrder("asc");
|
||||
}
|
||||
};
|
||||
|
||||
const sortedRows = rows.slice().sort((a, b) => {
|
||||
if (!sortColumn) return 0;
|
||||
|
||||
const columnIndex = headings.findIndex((h) => h.title === sortColumn);
|
||||
const aValue = a[columnIndex].props.children;
|
||||
const bValue = b[columnIndex].props.children;
|
||||
|
||||
// Custom comparison for 'Last Heard' column
|
||||
if (sortColumn === "Last Heard") {
|
||||
const aTimestamp = a[columnIndex].props.timestamp;
|
||||
const bTimestamp = b[columnIndex].props.timestamp;
|
||||
|
||||
if (aTimestamp < bTimestamp) {
|
||||
return sortOrder === "asc" ? -1 : 1;
|
||||
}
|
||||
if (aTimestamp > bTimestamp) {
|
||||
return sortOrder === "asc" ? 1 : -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Default comparison for other columns
|
||||
if (aValue < bValue) {
|
||||
return sortOrder === "asc" ? -1 : 1;
|
||||
}
|
||||
if (aValue > bValue) {
|
||||
return sortOrder === "asc" ? 1 : -1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
return (
|
||||
<table className="min-w-full">
|
||||
<thead className="bg-backgroundPrimary text-sm font-semibold text-textPrimary">
|
||||
@@ -25,11 +69,12 @@ export const Table = ({ headings, rows }: TableProps): JSX.Element => {
|
||||
? "cursor-pointer hover:brightness-hover active:brightness-press"
|
||||
: ""
|
||||
}`}
|
||||
onClick={() => heading.sortable && headingSort(heading.title)}
|
||||
>
|
||||
<div className="flex gap-2">
|
||||
{heading.title}
|
||||
{heading.sortable && (
|
||||
<ChevronUpIcon size={16} className="my-auto" />
|
||||
{sortColumn === heading.title && (
|
||||
<>{sortOrder === "asc" ? <ChevronUpIcon size={16} /> : <ChevronDownIcon size={16} />}</>
|
||||
)}
|
||||
</div>
|
||||
</th>
|
||||
@@ -37,7 +82,7 @@ export const Table = ({ headings, rows }: TableProps): JSX.Element => {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows.map((row, index) => (
|
||||
{sortedRows.map((row, index) => (
|
||||
<tr key={index}>
|
||||
{row.map((item, index) => (
|
||||
<td
|
||||
|
||||
Reference in New Issue
Block a user