mirror of
https://github.com/optim-enterprises-bv/OptimCloud-gw-ui.git
synced 2025-10-29 17:32:20 +00:00
Merge pull request #201 from stephb9959/main
[WIFI-13153] Added IP addresses to wifi analysis
This commit is contained in:
10
package-lock.json
generated
10
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "ucentral-client",
|
"name": "ucentral-client",
|
||||||
"version": "2.11.0(15)",
|
"version": "2.11.0(16)",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ucentral-client",
|
"name": "ucentral-client",
|
||||||
"version": "2.11.0(15)",
|
"version": "2.11.0(16)",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chakra-ui/anatomy": "^2.1.1",
|
"@chakra-ui/anatomy": "^2.1.1",
|
||||||
@@ -4760,9 +4760,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "1.3.5",
|
"version": "1.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.1.tgz",
|
||||||
"integrity": "sha512-glL/PvG/E+xCWwV8S6nCHcrfg1exGx7vxyUIivIA1iL7BIh6bePylCfVHwp6k13ao7SATxB6imau2kqY+I67kw==",
|
"integrity": "sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.15.0",
|
"follow-redirects": "^1.15.0",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ucentral-client",
|
"name": "ucentral-client",
|
||||||
"version": "2.11.0(15)",
|
"version": "2.11.0(16)",
|
||||||
"description": "",
|
"description": "",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "index.tsx",
|
"main": "index.tsx",
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { ColumnPicker } from 'components/DataTables/ColumnPicker';
|
|||||||
import { DataTable } from 'components/DataTables/DataTable';
|
import { DataTable } from 'components/DataTables/DataTable';
|
||||||
import DataCell from 'components/TableCells/DataCell';
|
import DataCell from 'components/TableCells/DataCell';
|
||||||
import { Column } from 'models/Table';
|
import { Column } from 'models/Table';
|
||||||
|
import IpCell from './IpCell';
|
||||||
|
|
||||||
export type ParsedAssociation = {
|
export type ParsedAssociation = {
|
||||||
radio?: ParsedRadio;
|
radio?: ParsedRadio;
|
||||||
@@ -35,7 +36,7 @@ type Props = {
|
|||||||
isSingle?: boolean;
|
isSingle?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const WifiAnalysisAssocationsTable = ({ data, ouis, isSingle }: Props) => {
|
const WifiAnalysisAssociationsTable = ({ data, ouis, isSingle }: Props) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [hiddenColumns, setHiddenColumns] = React.useState<string[]>([]);
|
const [hiddenColumns, setHiddenColumns] = React.useState<string[]>([]);
|
||||||
|
|
||||||
@@ -50,6 +51,10 @@ const WifiAnalysisAssocationsTable = ({ data, ouis, isSingle }: Props) => {
|
|||||||
);
|
);
|
||||||
const dataCell = React.useCallback((v: number) => <DataCell bytes={v} />, []);
|
const dataCell = React.useCallback((v: number) => <DataCell bytes={v} />, []);
|
||||||
const indexCell = React.useCallback((assoc: ParsedAssociation) => assoc.radio?.band ?? assoc.radio?.deductedBand, []);
|
const indexCell = React.useCallback((assoc: ParsedAssociation) => assoc.radio?.band ?? assoc.radio?.deductedBand, []);
|
||||||
|
const ipCell = React.useCallback(
|
||||||
|
(assoc: ParsedAssociation) => <IpCell ipv4={assoc.ips.ipv4} ipv6={assoc.ips.ipv6} />,
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
const columns: Column<ParsedAssociation>[] = React.useMemo(
|
const columns: Column<ParsedAssociation>[] = React.useMemo(
|
||||||
(): Column<ParsedAssociation>[] => [
|
(): Column<ParsedAssociation>[] => [
|
||||||
@@ -72,6 +77,13 @@ const WifiAnalysisAssocationsTable = ({ data, ouis, isSingle }: Props) => {
|
|||||||
isMonospace: true,
|
isMonospace: true,
|
||||||
alwaysShow: true,
|
alwaysShow: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'ips',
|
||||||
|
Header: 'IPs',
|
||||||
|
Footer: '',
|
||||||
|
Cell: (v) => ipCell(v.cell.row.original),
|
||||||
|
disableSortBy: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'vendor',
|
id: 'vendor',
|
||||||
Header: t('controller.wifi.vendor'),
|
Header: t('controller.wifi.vendor'),
|
||||||
@@ -195,4 +207,4 @@ const WifiAnalysisAssocationsTable = ({ data, ouis, isSingle }: Props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default WifiAnalysisAssocationsTable;
|
export default WifiAnalysisAssociationsTable;
|
||||||
|
|||||||
90
src/pages/Device/WifiAnalysis/IpCell.tsx
Normal file
90
src/pages/Device/WifiAnalysis/IpCell.tsx
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { CopyIcon } from '@chakra-ui/icons';
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Flex,
|
||||||
|
Heading,
|
||||||
|
IconButton,
|
||||||
|
ListItem,
|
||||||
|
Popover,
|
||||||
|
PopoverArrow,
|
||||||
|
PopoverBody,
|
||||||
|
PopoverCloseButton,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverHeader,
|
||||||
|
PopoverTrigger,
|
||||||
|
Text,
|
||||||
|
Tooltip,
|
||||||
|
UnorderedList,
|
||||||
|
useBoolean,
|
||||||
|
useClipboard,
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
|
||||||
|
const CopyString = ({ str }: { str: string }) => {
|
||||||
|
const [isHovered, setHovered] = useBoolean(false);
|
||||||
|
const copy = useClipboard(str);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex alignItems="center" onMouseEnter={setHovered.on} onMouseLeave={setHovered.off}>
|
||||||
|
<Text>{str}</Text>
|
||||||
|
<Tooltip label={copy.hasCopied ? 'Copied!' : 'Copy'} placement="top">
|
||||||
|
<IconButton
|
||||||
|
aria-label={copy.hasCopied ? 'Copied!' : 'Copy'}
|
||||||
|
size="sm"
|
||||||
|
onClick={copy.onCopy}
|
||||||
|
icon={<CopyIcon />}
|
||||||
|
variant="transparent"
|
||||||
|
opacity={!isHovered ? 0 : 1}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
ipv4: string[];
|
||||||
|
ipv6: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const IpCell = ({ ipv4, ipv6 }: Props) => {
|
||||||
|
const length = ipv4.length + ipv6.length;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger>
|
||||||
|
<Button colorScheme="teal" size="sm">
|
||||||
|
{length}
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent>
|
||||||
|
<PopoverArrow />
|
||||||
|
<PopoverCloseButton />
|
||||||
|
<PopoverHeader>
|
||||||
|
<Heading size="sm">
|
||||||
|
{length} {length === 1 ? 'IP' : 'IPs'}
|
||||||
|
</Heading>
|
||||||
|
</PopoverHeader>
|
||||||
|
<PopoverBody>
|
||||||
|
<Heading size="sm">IpV4 ({ipv4.length})</Heading>
|
||||||
|
<UnorderedList>
|
||||||
|
{ipv4.map((ip) => (
|
||||||
|
<ListItem key={ip}>
|
||||||
|
<CopyString str={ip} />
|
||||||
|
</ListItem>
|
||||||
|
))}
|
||||||
|
</UnorderedList>
|
||||||
|
<Heading size="sm">IpV6 ({ipv6.length})</Heading>
|
||||||
|
<UnorderedList>
|
||||||
|
{ipv6.map((ip) => (
|
||||||
|
<ListItem key={ip}>
|
||||||
|
<CopyString str={ip} />
|
||||||
|
</ListItem>
|
||||||
|
))}
|
||||||
|
</UnorderedList>
|
||||||
|
</PopoverBody>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default IpCell;
|
||||||
Reference in New Issue
Block a user