mirror of
				https://github.com/optim-enterprises-bv/OptimCloud-gw-ui.git
				synced 2025-10-31 02:07:45 +00:00 
			
		
		
		
	[WIFI-13153] Added IP addresses to wifi analysis
Signed-off-by: Charles <charles.bourque96@gmail.com>
This commit is contained in:
		
							
								
								
									
										10
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										10
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,12 +1,12 @@ | ||||
| { | ||||
|   "name": "ucentral-client", | ||||
|   "version": "2.11.0(15)", | ||||
|   "version": "2.11.0(16)", | ||||
|   "lockfileVersion": 3, | ||||
|   "requires": true, | ||||
|   "packages": { | ||||
|     "": { | ||||
|       "name": "ucentral-client", | ||||
|       "version": "2.11.0(15)", | ||||
|       "version": "2.11.0(16)", | ||||
|       "license": "ISC", | ||||
|       "dependencies": { | ||||
|         "@chakra-ui/anatomy": "^2.1.1", | ||||
| @@ -4760,9 +4760,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/axios": { | ||||
|       "version": "1.3.5", | ||||
|       "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.5.tgz", | ||||
|       "integrity": "sha512-glL/PvG/E+xCWwV8S6nCHcrfg1exGx7vxyUIivIA1iL7BIh6bePylCfVHwp6k13ao7SATxB6imau2kqY+I67kw==", | ||||
|       "version": "1.6.1", | ||||
|       "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.1.tgz", | ||||
|       "integrity": "sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g==", | ||||
|       "dependencies": { | ||||
|         "follow-redirects": "^1.15.0", | ||||
|         "form-data": "^4.0.0", | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "ucentral-client", | ||||
|   "version": "2.11.0(15)", | ||||
|   "version": "2.11.0(16)", | ||||
|   "description": "", | ||||
|   "private": true, | ||||
|   "main": "index.tsx", | ||||
|   | ||||
| @@ -6,6 +6,7 @@ import { ColumnPicker } from 'components/DataTables/ColumnPicker'; | ||||
| import { DataTable } from 'components/DataTables/DataTable'; | ||||
| import DataCell from 'components/TableCells/DataCell'; | ||||
| import { Column } from 'models/Table'; | ||||
| import IpCell from './IpCell'; | ||||
|  | ||||
| export type ParsedAssociation = { | ||||
|   radio?: ParsedRadio; | ||||
| @@ -35,7 +36,7 @@ type Props = { | ||||
|   isSingle?: boolean; | ||||
| }; | ||||
|  | ||||
| const WifiAnalysisAssocationsTable = ({ data, ouis, isSingle }: Props) => { | ||||
| const WifiAnalysisAssociationsTable = ({ data, ouis, isSingle }: Props) => { | ||||
|   const { t } = useTranslation(); | ||||
|   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 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( | ||||
|     (): Column<ParsedAssociation>[] => [ | ||||
| @@ -72,6 +77,13 @@ const WifiAnalysisAssocationsTable = ({ data, ouis, isSingle }: Props) => { | ||||
|         isMonospace: true, | ||||
|         alwaysShow: true, | ||||
|       }, | ||||
|       { | ||||
|         id: 'ips', | ||||
|         Header: 'IPs', | ||||
|         Footer: '', | ||||
|         Cell: (v) => ipCell(v.cell.row.original), | ||||
|         disableSortBy: true, | ||||
|       }, | ||||
|       { | ||||
|         id: '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
	 Charles
					Charles