Skip to content

Commit

Permalink
[WIP] serial number lookup + filter to only "All" group
Browse files Browse the repository at this point in the history
Signed-off-by: Edouard Vanbelle <[email protected]>
  • Loading branch information
EdouardVanbelle committed Nov 27, 2024
1 parent 2aa7b0c commit 4e56441
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 21 deletions.
48 changes: 48 additions & 0 deletions src/components/table/DataTableToolTipButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import Button from "@components/Button";
import { Tooltip, TooltipContent, TooltipTrigger } from "@components/Tooltip";
import { motion } from "framer-motion";
import { RefreshCcw } from "lucide-react";
import * as React from "react";
import { useState } from "react";

type Props = {
onClick: () => void;
disabled?: boolean;
variant?: "default" | "primary" | "secondary" | "input" | "dotted" | "tertiary" | "white" | "outline" | "danger-outline" | "default-outline" | "danger" | null | undefined;
title?:any;
children: any;
};
export default function DataTableToolTipButton({ onClick, disabled, variant, title, children }: Props) {
const [rotate, setRotate] = useState(false);
//const [disabled, setDisabled] = useState(false);
const [hovered, setHovered] = useState(false);

return (
<Tooltip>
<TooltipTrigger
asChild={true}
>
<Button
className={"h-[42px]"}
variant={variant}
disabled={disabled == true ? true : disabled}
onClick={onClick}
>
{children}
</Button>
</TooltipTrigger>

<TooltipContent
sideOffset={10}
className={"px-3 py-2"}
onPointerDownOutside={(event) => {
if (hovered) event.preventDefault();
}}
>
<span className={"text-xs text-neutral-300"}>
{title}
</span>
</TooltipContent>
</Tooltip>
);
}
2 changes: 1 addition & 1 deletion src/modules/groups/AssignPeerToGroupModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,6 @@ const PeersTableColumns: ColumnDef<Peer>[] = [
header: ({ column }) => {
return <DataTableHeader column={column}>OS</DataTableHeader>;
},
cell: ({ row }) => <PeerOSCell os={row.original.os} />,
cell: ({ row }) => <PeerOSCell os={row.original.os} serial={row.original.serial_number} />,
},
];
2 changes: 1 addition & 1 deletion src/modules/peer/AccessiblePeersTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const AccessiblePeersColumns: ColumnDef<Peer>[] = [
header: ({ column }) => {
return <DataTableHeader column={column}>OS</DataTableHeader>;
},
cell: ({ row }) => <PeerOSCell os={row.original.os} />,
cell: ({ row }) => <PeerOSCell os={row.original.os} serial={row.original.serial_number}/>,
},
];

Expand Down
39 changes: 37 additions & 2 deletions src/modules/peers/PeerOSCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import AppleLogo from "@/assets/os-icons/apple.svg";
import FreeBSDLogo from "@/assets/os-icons/FreeBSD.png";
import { getOperatingSystem } from "@/hooks/useOperatingSystem";
import { OperatingSystem } from "@/interfaces/OperatingSystem";
import { Barcode, Laptop } from "lucide-react";

export function PeerOSCell({ os }: { os: string }) {
export function PeerOSCell({ os, serial }: { os: string, serial: string }) {
return (
<TooltipProvider>
<Tooltip delayDuration={1}>
Expand All @@ -34,13 +35,47 @@ export function PeerOSCell({ os }: { os: string }) {
</div>
</TooltipTrigger>
<TooltipContent>
<div className={"text-neutral-300 flex flex-col gap-1"}>{os}</div>
<ListItem
icon={<Laptop size={14} />}
label={"OS"}
value={os}
/>
<ListItem
icon={<Barcode size={14} />}
label={"Serial"}
value={serial}
/>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}

const ListItem = ({
icon,
label,
value,
}: {
icon: React.ReactNode;
label: string;
value: string | React.ReactNode;
}) => {
return (
<div
className={
"flex justify-between gap-5 border-b border-nb-gray-920 py-2 px-4 last:border-b-0 text-xs"
}
>
<div className={"flex items-center gap-2 text-nb-gray-100 font-medium"}>
{icon}
{label}
</div>
<div className={"text-nb-gray-400"}>{value}</div>
</div>
);
};


export function OSLogo({ os }: { os: string }) {
const icon = useMemo(() => {
return getOperatingSystem(os);
Expand Down
96 changes: 79 additions & 17 deletions src/modules/peers/PeersTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ import {
ColumnDef,
RowSelectionState,
SortingState,
VisibilityState,
} from "@tanstack/react-table";
import { uniqBy } from "lodash";
import { ExternalLinkIcon } from "lucide-react";
import { usePathname } from "next/navigation";
import React, { useState } from "react";
import { useSWRConfig } from "swr";
import PeerIcon from "@/assets/icons/PeerIcon";
import DataTableToolTipButton from "@/components/table/DataTableToolTipButton";
import PeerProvider from "@/contexts/PeerProvider";
import { useLoggedInUser } from "@/contexts/UsersProvider";
import { useLocalStorage } from "@/hooks/useLocalStorage";
Expand All @@ -40,6 +42,7 @@ import PeerVersionCell from "@/modules/peers/PeerVersionCell";
const PeersTableColumns: ColumnDef<Peer>[] = [
{
id: "select",
enableHiding: false,
header: ({ table }) => (
<div className={"min-w-[20px] max-w-[20px]"}>
<Checkbox
Expand All @@ -60,10 +63,10 @@ const PeersTableColumns: ColumnDef<Peer>[] = [
</div>
),
enableSorting: false,
enableHiding: false,
},
{
accessorKey: "name",
enableHiding: false,
header: ({ column }) => {
return <DataTableHeader column={column}>Name</DataTableHeader>;
},
Expand All @@ -82,6 +85,7 @@ const PeersTableColumns: ColumnDef<Peer>[] = [
accessorFn: (peer) => peer.connected,
},
{
id: "ip",
accessorKey: "ip",
sortingFn: "text",
},
Expand All @@ -94,18 +98,30 @@ const PeersTableColumns: ColumnDef<Peer>[] = [
accessorFn: (peer) => (peer.user ? peer.user?.email : "Unknown"),
},
{
id: "dns_label",
enableHiding: false,
accessorKey: "dns_label",
header: ({ column }) => {
return <DataTableHeader column={column}>Address</DataTableHeader>;
},
cell: ({ row }) => <PeerAddressCell peer={row.original} />,
},
{
id: "group_name_strings",
accessorKey: "group_name_strings",
accessorFn: (peer) => peer.groups?.map((g) => g?.name || "").join(", "),
sortingFn: "text",
},
{
// used for exact group matching
id: "exact_group_name_strings",
accessorKey: "exact_group_name_strings",
accessorFn: (peer) => peer.groups?.map((g) => g?.name || "").join("|"),
sortingFn: "text",
filterFn: "equals"
},
{
id: "group_names",
accessorKey: "group_names",
accessorFn: (peer) => peer.groups?.map((g) => g?.name || ""),
sortingFn: "text",
Expand All @@ -124,6 +140,7 @@ const PeersTableColumns: ColumnDef<Peer>[] = [
),
},
{
id: "last_seen",
accessorKey: "last_seen",
header: ({ column }) => {
return <DataTableHeader column={column}>Last seen</DataTableHeader>;
Expand All @@ -132,13 +149,23 @@ const PeersTableColumns: ColumnDef<Peer>[] = [
cell: ({ row }) => <PeerLastSeenCell peer={row.original} />,
},
{
id: "os",
accessorKey: "os",
header: ({ column }) => {
return <DataTableHeader column={column}>OS</DataTableHeader>;
},
cell: ({ row }) => <PeerOSCell os={row.original.os} />,
cell: ({ row }) => <PeerOSCell os={row.original.os} serial={row.original.serial_number} />,
},
{
id: "serial",
header: ({ column }) => {
return <DataTableHeader column={column}>Serial number</DataTableHeader>;
},
accessorFn: (peer) => peer.serial_number,
sortingFn: "text",
},
{
id: "version",
accessorKey: "version",
header: ({ column }) => {
return <DataTableHeader column={column}>Version</DataTableHeader>;
Expand All @@ -165,8 +192,10 @@ const PeersTableColumns: ColumnDef<Peer>[] = [
},
{
id: "actions",
enableHiding: false,
accessorKey: "id",
header: "",

cell: ({ row }) => (
<PeerProvider peer={row.original}>
<PeerActionCell />
Expand Down Expand Up @@ -213,6 +242,25 @@ export default function PeersTable({ peers, isLoading, headingTarget }: Props) {

const [selectedRows, setSelectedRows] = useState<RowSelectionState>({});

const colVisibility: VisibilityState = {
select: !isUser,
actions: !isUser,
groups: !isUser,
connected: false,
approval_required: false,

// hidden, but usefull for lookup
serial: false,
group_name_strings: false,
exact_group_name_strings: false,
group_names: false,
ip: false,
user_name: false,
user_email: false,
}

const [resultingColumnVisibility, setColumnVisibility] = useState(colVisibility);

const resetSelectedRows = () => {
if (Object.keys(selectedRows).length > 0) {
setSelectedRows({});
Expand All @@ -226,28 +274,19 @@ export default function PeersTable({ peers, isLoading, headingTarget }: Props) {
onCanceled={() => setSelectedRows({})}
/>
<DataTable
keepStateInLocalStorage={true}
headingTarget={headingTarget}
rowSelection={selectedRows}
setRowSelection={setSelectedRows}
useRowId={true}
text={"Peers"}
sorting={sorting}
setSorting={setSorting}
setColumnVisibility={setColumnVisibility}
columns={PeersTableColumns}
data={peers}
searchPlaceholder={"Search by name, IP, owner or group..."}
columnVisibility={{
select: !isUser,
connected: false,
approval_required: false,
group_name_strings: false,
group_names: false,
ip: false,
user_name: false,
user_email: false,
actions: !isUser,
groups: !isUser,
}}
searchPlaceholder={"Search by name, IP, Serial, owner or group..."}
columnVisibility={resultingColumnVisibility}
isLoading={isLoading}
getStartedCard={
<GetStartedTest
Expand Down Expand Up @@ -393,7 +432,7 @@ export default function PeersTable({ peers, isLoading, headingTarget }: Props) {
table.setPageIndex(0);
let current =
table.getColumn("approval_required")?.getFilterValue() ===
undefined
undefined
? true
: undefined;

Expand All @@ -412,7 +451,7 @@ export default function PeersTable({ peers, isLoading, headingTarget }: Props) {
}}
variant={
table.getColumn("approval_required")?.getFilterValue() ===
true
true
? "tertiary"
: "secondary"
}
Expand Down Expand Up @@ -446,6 +485,29 @@ export default function PeersTable({ peers, isLoading, headingTarget }: Props) {
/>
)}

<DataTableToolTipButton
disabled={peers?.length == 0}
onClick={() => {
table.setPageIndex(0);
if (table.getColumn("exact_group_name_strings")?.getFilterValue() !== undefined) {
table.resetColumnFilters();
return;
}
table.setColumnFilters([
{
id: "exact_group_name_strings",
value: "All"
}
])
}}
variant={table.getColumn("exact_group_name_strings")?.getFilterValue() !== undefined
? "tertiary"
: "secondary"}
title="filter peers assigned to the uniq group: 'All'"
>
All group only
</DataTableToolTipButton>

<DataTableRefreshButton
isDisabled={peers?.length == 0}
onClick={() => {
Expand Down

0 comments on commit 4e56441

Please sign in to comment.