mirror of
				https://github.com/optim-enterprises-bv/OptimCloud-gw-ui.git
				synced 2025-10-31 18:27:45 +00:00 
			
		
		
		
	[WIFI-13515] Supporting deviceTypes in lowercase
Signed-off-by: Charles <charles.bourque96@gmail.com>
This commit is contained in:
		
							
								
								
									
										4
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,12 +1,12 @@ | |||||||
| { | { | ||||||
|   "name": "ucentral-client", |   "name": "ucentral-client", | ||||||
|   "version": "3.0.2(6)", |   "version": "3.0.2(8)", | ||||||
|   "lockfileVersion": 3, |   "lockfileVersion": 3, | ||||||
|   "requires": true, |   "requires": true, | ||||||
|   "packages": { |   "packages": { | ||||||
|     "": { |     "": { | ||||||
|       "name": "ucentral-client", |       "name": "ucentral-client", | ||||||
|       "version": "3.0.2(6)", |       "version": "3.0.2(8)", | ||||||
|       "license": "ISC", |       "license": "ISC", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "@chakra-ui/anatomy": "^2.1.1", |         "@chakra-ui/anatomy": "^2.1.1", | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "ucentral-client", |   "name": "ucentral-client", | ||||||
|   "version": "3.0.2(6)", |   "version": "3.0.2(8)", | ||||||
|   "description": "", |   "description": "", | ||||||
|   "private": true, |   "private": true, | ||||||
|   "main": "index.tsx", |   "main": "index.tsx", | ||||||
|   | |||||||
| @@ -54,7 +54,7 @@ const DeviceActionDropdown = ({ | |||||||
| }: Props) => { | }: Props) => { | ||||||
|   const { t } = useTranslation(); |   const { t } = useTranslation(); | ||||||
|   const toast = useToast(); |   const toast = useToast(); | ||||||
|   const deviceType = device?.deviceType ?? 'AP'; |   const deviceType = device?.deviceType ?? 'ap'; | ||||||
|   const connectColor = useColorModeValue('blackAlpha', 'gray'); |   const connectColor = useColorModeValue('blackAlpha', 'gray'); | ||||||
|   const addEventListeners = useControllerStore((state) => state.addEventListeners); |   const addEventListeners = useControllerStore((state) => state.addEventListeners); | ||||||
|   const { refetch: getRtty, isFetching: isRtty } = useGetDeviceRtty({ |   const { refetch: getRtty, isFetching: isRtty } = useGetDeviceRtty({ | ||||||
| @@ -173,7 +173,7 @@ const DeviceActionDropdown = ({ | |||||||
|           isLoading={isRtty} |           isLoading={isRtty} | ||||||
|           onClick={handleConnectClick} |           onClick={handleConnectClick} | ||||||
|           colorScheme={connectColor} |           colorScheme={connectColor} | ||||||
|           hidden={isCompact || deviceType !== 'AP'} |           hidden={isCompact || deviceType !== 'ap'} | ||||||
|         /> |         /> | ||||||
|       </Tooltip> |       </Tooltip> | ||||||
|       <Tooltip label={t('controller.configure.title')}> |       <Tooltip label={t('controller.configure.title')}> | ||||||
| @@ -206,7 +206,7 @@ const DeviceActionDropdown = ({ | |||||||
|           isDisabled={isDisabled} |           isDisabled={isDisabled} | ||||||
|           onClick={handleOpenScan} |           onClick={handleOpenScan} | ||||||
|           colorScheme="teal" |           colorScheme="teal" | ||||||
|           hidden={isCompact || deviceType !== 'AP'} |           hidden={isCompact || deviceType !== 'ap'} | ||||||
|         /> |         /> | ||||||
|       </Tooltip> |       </Tooltip> | ||||||
|       <Menu> |       <Menu> | ||||||
| @@ -222,7 +222,7 @@ const DeviceActionDropdown = ({ | |||||||
|         <Portal> |         <Portal> | ||||||
|           <MenuList maxH="315px" overflowY="auto"> |           <MenuList maxH="315px" overflowY="auto"> | ||||||
|             <MenuItem onClick={handleBlinkClick}>{t('commands.blink')}</MenuItem> |             <MenuItem onClick={handleBlinkClick}>{t('commands.blink')}</MenuItem> | ||||||
|             <MenuItem onClick={handleOpenConfigure} hidden={!isCompact || deviceType !== 'AP'}> |             <MenuItem onClick={handleOpenConfigure} hidden={!isCompact || deviceType !== 'ap'}> | ||||||
|               {t('controller.configure.title')} |               {t('controller.configure.title')} | ||||||
|             </MenuItem> |             </MenuItem> | ||||||
|             <MenuItem onClick={handleConnectClick} hidden={!isCompact}> |             <MenuItem onClick={handleConnectClick} hidden={!isCompact}> | ||||||
| @@ -240,7 +240,7 @@ const DeviceActionDropdown = ({ | |||||||
|             <MenuItem onClick={handleUpdateToLatest} hidden> |             <MenuItem onClick={handleUpdateToLatest} hidden> | ||||||
|               {t('premium.toolbox.upgrade_to_latest')} |               {t('premium.toolbox.upgrade_to_latest')} | ||||||
|             </MenuItem> |             </MenuItem> | ||||||
|             <MenuItem onClick={handleOpenScan} hidden={!isCompact || deviceType !== 'AP'}> |             <MenuItem onClick={handleOpenScan} hidden={!isCompact || deviceType !== 'ap'}> | ||||||
|               {t('commands.wifiscan')} |               {t('commands.wifiscan')} | ||||||
|             </MenuItem> |             </MenuItem> | ||||||
|           </MenuList> |           </MenuList> | ||||||
|   | |||||||
| @@ -3,10 +3,12 @@ import { axiosGw } from 'constants/axiosInstances'; | |||||||
| import { useEndpointStatus } from 'hooks/useEndpointStatus'; | import { useEndpointStatus } from 'hooks/useEndpointStatus'; | ||||||
| import { AxiosError } from 'models/Axios'; | import { AxiosError } from 'models/Axios'; | ||||||
| import { DeviceConfiguration } from 'models/Device'; | import { DeviceConfiguration } from 'models/Device'; | ||||||
|  | import { DevicePlatform } from './Devices'; | ||||||
|  |  | ||||||
| export type DefaultConfigurationResponse = { | export type DefaultConfigurationResponse = { | ||||||
|   configuration: DeviceConfiguration; |   configuration: DeviceConfiguration; | ||||||
|   created: number; |   created: number; | ||||||
|  |   platform: DevicePlatform; | ||||||
|   description: string; |   description: string; | ||||||
|   lastModified: number; |   lastModified: number; | ||||||
|   modelIds: string[]; |   modelIds: string[]; | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ import { Note } from 'models/Note'; | |||||||
| import { PageInfo } from 'models/Table'; | import { PageInfo } from 'models/Table'; | ||||||
| import { DeviceCommandHistory } from './Commands'; | import { DeviceCommandHistory } from './Commands'; | ||||||
|  |  | ||||||
| export const DEVICE_PLATFORMS = ['ALL', 'AP', 'SWITCH'] as const; | export const DEVICE_PLATFORMS = ['all', 'ap', 'switch'] as const; | ||||||
| export type DevicePlatform = (typeof DEVICE_PLATFORMS)[number]; | export type DevicePlatform = (typeof DEVICE_PLATFORMS)[number]; | ||||||
|  |  | ||||||
| const getDeviceCount = (platform: DevicePlatform) => | const getDeviceCount = (platform: DevicePlatform) => | ||||||
| @@ -19,7 +19,7 @@ const getDeviceCount = (platform: DevicePlatform) => | |||||||
|     count: number; |     count: number; | ||||||
|   }>; |   }>; | ||||||
|  |  | ||||||
| export const useGetDeviceCount = ({ enabled, platform = 'ALL' }: { enabled: boolean; platform?: DevicePlatform }) => { | export const useGetDeviceCount = ({ enabled, platform = 'all' }: { enabled: boolean; platform?: DevicePlatform }) => { | ||||||
|   const { t } = useTranslation(); |   const { t } = useTranslation(); | ||||||
|   const toast = useToast(); |   const toast = useToast(); | ||||||
|  |  | ||||||
| @@ -55,7 +55,7 @@ export type DeviceWithStatus = { | |||||||
|   certificateExpiryDate?: number; |   certificateExpiryDate?: number; | ||||||
|   createdTimestamp: number; |   createdTimestamp: number; | ||||||
|   devicePassword: string; |   devicePassword: string; | ||||||
|   deviceType: 'AP' | 'SWITCH' | 'IOT' | 'MESH'; |   deviceType: 'ap' | 'switch'; | ||||||
|   entity: string; |   entity: string; | ||||||
|   firmware: string; |   firmware: string; | ||||||
|   fwUpdatePolicy: string; |   fwUpdatePolicy: string; | ||||||
| @@ -111,7 +111,7 @@ export const useGetDevices = ({ | |||||||
|   pageInfo, |   pageInfo, | ||||||
|   enabled, |   enabled, | ||||||
|   onError, |   onError, | ||||||
|   platform = 'ALL', |   platform = 'all', | ||||||
| }: { | }: { | ||||||
|   pageInfo?: PageInfo; |   pageInfo?: PageInfo; | ||||||
|   enabled: boolean; |   enabled: boolean; | ||||||
| @@ -147,7 +147,7 @@ const getAllDevices = async (platform: DevicePlatform) => { | |||||||
|  |  | ||||||
| export const useGetAllDevicesWithStatus = ({ | export const useGetAllDevicesWithStatus = ({ | ||||||
|   onError, |   onError, | ||||||
|   platform = 'ALL', |   platform = 'all', | ||||||
| }: { | }: { | ||||||
|   onError?: (e: AxiosError) => void; |   onError?: (e: AxiosError) => void; | ||||||
|   platform?: DevicePlatform; |   platform?: DevicePlatform; | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import * as React from 'react'; | import * as React from 'react'; | ||||||
| import { Box, SimpleGrid, useBoolean, useDisclosure, useToast } from '@chakra-ui/react'; | import { Box, Flex, useBoolean, useDisclosure, useToast } from '@chakra-ui/react'; | ||||||
| import { Formik, FormikProps } from 'formik'; | import { Formik, FormikProps } from 'formik'; | ||||||
| import { useTranslation } from 'react-i18next'; | import { useTranslation } from 'react-i18next'; | ||||||
| import { v4 as uuid } from 'uuid'; | import { v4 as uuid } from 'uuid'; | ||||||
| @@ -16,6 +16,7 @@ import { useGetDeviceTypes } from 'hooks/Network/Firmware'; | |||||||
| import { useFormModal } from 'hooks/useFormModal'; | import { useFormModal } from 'hooks/useFormModal'; | ||||||
| import { useFormRef } from 'hooks/useFormRef'; | import { useFormRef } from 'hooks/useFormRef'; | ||||||
| import { AxiosError } from 'models/Axios'; | import { AxiosError } from 'models/Axios'; | ||||||
|  | import { SelectField } from 'components/Form/Fields/SelectField'; | ||||||
|  |  | ||||||
| const CreateDefaultConfigurationModal = () => { | const CreateDefaultConfigurationModal = () => { | ||||||
|   const { t } = useTranslation(); |   const { t } = useTranslation(); | ||||||
| @@ -100,10 +101,28 @@ const CreateDefaultConfigurationModal = () => { | |||||||
|             }} |             }} | ||||||
|           > |           > | ||||||
|             <Box> |             <Box> | ||||||
|               <SimpleGrid spacing={4} minChildWidth="200px"> |               <Flex mb={4}> | ||||||
|                 <StringField name="name" label={t('common.name')} isRequired isDisabled={isDisabled} /> |                 <StringField | ||||||
|                 <StringField name="description" label={t('common.description')} isDisabled={isDisabled} /> |                   name="name" | ||||||
|               </SimpleGrid> |                   label={t('common.name')} | ||||||
|  |                   isRequired | ||||||
|  |                   isDisabled={isDisabled} | ||||||
|  |                   maxW="340px" | ||||||
|  |                   mr={4} | ||||||
|  |                 /> | ||||||
|  |                 <SelectField | ||||||
|  |                   name="platform" | ||||||
|  |                   label="Platform" | ||||||
|  |                   options={[ | ||||||
|  |                     { label: 'AP', value: 'ap' }, | ||||||
|  |                     { label: 'Switch', value: 'switch' }, | ||||||
|  |                   ]} | ||||||
|  |                   isRequired | ||||||
|  |                   isDisabled={isDisabled} | ||||||
|  |                   w="max-content" | ||||||
|  |                 /> | ||||||
|  |               </Flex> | ||||||
|  |               <StringField name="description" label={t('common.description')} isDisabled={isDisabled} mb={4} /> | ||||||
|               <MultiSelectField |               <MultiSelectField | ||||||
|                 name="modelIds" |                 name="modelIds" | ||||||
|                 label={t('controller.dashboard.device_types')} |                 label={t('controller.dashboard.device_types')} | ||||||
| @@ -116,7 +135,7 @@ const CreateDefaultConfigurationModal = () => { | |||||||
|                 } |                 } | ||||||
|                 isRequired |                 isRequired | ||||||
|               /> |               /> | ||||||
|               <StringField name="configuration" label={t('configurations.one')} isArea isDisabled={isDisabled} /> |               <StringField name="configuration" label={t('configurations.one')} isArea isDisabled={isDisabled} mt={4} /> | ||||||
|             </Box> |             </Box> | ||||||
|           </Formik> |           </Formik> | ||||||
|         </Box> |         </Box> | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import * as React from 'react'; | import * as React from 'react'; | ||||||
| import { Box, SimpleGrid, useBoolean, UseDisclosureReturn, useToast } from '@chakra-ui/react'; | import { Box, Flex, useBoolean, UseDisclosureReturn, useToast } from '@chakra-ui/react'; | ||||||
| import { Formik, FormikProps } from 'formik'; | import { Formik, FormikProps } from 'formik'; | ||||||
| import { useTranslation } from 'react-i18next'; | import { useTranslation } from 'react-i18next'; | ||||||
| import { v4 as uuid } from 'uuid'; | import { v4 as uuid } from 'uuid'; | ||||||
| @@ -15,6 +15,7 @@ import { useGetDeviceTypes } from 'hooks/Network/Firmware'; | |||||||
| import { useFormModal } from 'hooks/useFormModal'; | import { useFormModal } from 'hooks/useFormModal'; | ||||||
| import { useFormRef } from 'hooks/useFormRef'; | import { useFormRef } from 'hooks/useFormRef'; | ||||||
| import { AxiosError } from 'models/Axios'; | import { AxiosError } from 'models/Axios'; | ||||||
|  | import { SelectField } from 'components/Form/Fields/SelectField'; | ||||||
|  |  | ||||||
| type Props = { | type Props = { | ||||||
|   modalProps: UseDisclosureReturn; |   modalProps: UseDisclosureReturn; | ||||||
| @@ -106,10 +107,28 @@ const EditDefaultConfiguration = ({ modalProps, config }: Props) => { | |||||||
|               }} |               }} | ||||||
|             > |             > | ||||||
|               <Box> |               <Box> | ||||||
|                 <SimpleGrid spacing={4} minChildWidth="200px"> |                 <Flex mb={4}> | ||||||
|                   <StringField name="name" label={t('common.name')} isRequired isDisabled={isDisabled} /> |                   <StringField | ||||||
|                   <StringField name="description" label={t('common.description')} isDisabled={isDisabled} /> |                     name="name" | ||||||
|                 </SimpleGrid> |                     label={t('common.name')} | ||||||
|  |                     isRequired | ||||||
|  |                     isDisabled={isDisabled} | ||||||
|  |                     maxW="340px" | ||||||
|  |                     mr={4} | ||||||
|  |                   /> | ||||||
|  |                   <SelectField | ||||||
|  |                     name="platform" | ||||||
|  |                     label="Platform" | ||||||
|  |                     options={[ | ||||||
|  |                       { label: 'AP', value: 'ap' }, | ||||||
|  |                       { label: 'Switch', value: 'switch' }, | ||||||
|  |                     ]} | ||||||
|  |                     isRequired | ||||||
|  |                     isDisabled | ||||||
|  |                     w="max-content" | ||||||
|  |                   /> | ||||||
|  |                 </Flex> | ||||||
|  |                 <StringField name="description" label={t('common.description')} isDisabled={isDisabled} mb={4} /> | ||||||
|                 <MultiSelectField |                 <MultiSelectField | ||||||
|                   name="modelIds" |                   name="modelIds" | ||||||
|                   label={t('controller.dashboard.device_types')} |                   label={t('controller.dashboard.device_types')} | ||||||
| @@ -122,7 +141,13 @@ const EditDefaultConfiguration = ({ modalProps, config }: Props) => { | |||||||
|                   } |                   } | ||||||
|                   isRequired |                   isRequired | ||||||
|                 /> |                 /> | ||||||
|                 <StringField name="configuration" label={t('configurations.one')} isArea isDisabled={isDisabled} /> |                 <StringField | ||||||
|  |                   name="configuration" | ||||||
|  |                   label={t('configurations.one')} | ||||||
|  |                   isArea | ||||||
|  |                   isDisabled={isDisabled} | ||||||
|  |                   mt={4} | ||||||
|  |                 /> | ||||||
|               </Box> |               </Box> | ||||||
|             </Formik> |             </Formik> | ||||||
|           )} |           )} | ||||||
|   | |||||||
| @@ -58,6 +58,14 @@ const DefaultConfigurationsList = () => { | |||||||
|         Cell: ({ cell }) => dateCell(cell.row.original.lastModified), |         Cell: ({ cell }) => dateCell(cell.row.original.lastModified), | ||||||
|         customWidth: '50px', |         customWidth: '50px', | ||||||
|       }, |       }, | ||||||
|  |       { | ||||||
|  |         id: 'platform', | ||||||
|  |         Header: 'Platform', | ||||||
|  |         Footer: '', | ||||||
|  |         accessor: 'platform', | ||||||
|  |         Cell: ({ cell }) => cell.row.original.platform.toUpperCase(), | ||||||
|  |         customWidth: '50px', | ||||||
|  |       }, | ||||||
|       { |       { | ||||||
|         id: 'modelIds', |         id: 'modelIds', | ||||||
|         Header: t('controller.dashboard.device_types'), |         Header: t('controller.dashboard.device_types'), | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ export const DefaultConfigurationSchema = (t: (str: string) => string) => | |||||||
|       name: Yup.string().required(t('form.required')), |       name: Yup.string().required(t('form.required')), | ||||||
|       description: Yup.string(), |       description: Yup.string(), | ||||||
|       modelIds: Yup.array().of(Yup.string()).required(t('form.required')).min(1, t('form.required')), |       modelIds: Yup.array().of(Yup.string()).required(t('form.required')).min(1, t('form.required')), | ||||||
|  |       platform: Yup.string().oneOf(['ap', 'switch']).required(t('form.required')), | ||||||
|       configuration: Yup.string() |       configuration: Yup.string() | ||||||
|         .required(t('form.required')) |         .required(t('form.required')) | ||||||
|         .test('configuration', t('form.invalid_json'), (v) => testJson(v ?? '')), |         .test('configuration', t('form.invalid_json'), (v) => testJson(v ?? '')), | ||||||
| @@ -15,5 +16,6 @@ export const DefaultConfigurationSchema = (t: (str: string) => string) => | |||||||
|       name: '', |       name: '', | ||||||
|       description: '', |       description: '', | ||||||
|       modelIds: [], |       modelIds: [], | ||||||
|  |       platform: 'ap', | ||||||
|       configuration: '', |       configuration: '', | ||||||
|     }); |     }); | ||||||
|   | |||||||
| @@ -80,19 +80,8 @@ const DevicePageWrapper = ({ serialNumber }: Props) => { | |||||||
|   const isCompact = breakpoint === 'base' || breakpoint === 'sm' || breakpoint === 'md'; |   const isCompact = breakpoint === 'base' || breakpoint === 'sm' || breakpoint === 'md'; | ||||||
|   const boxShadow = useColorModeValue('0px 7px 23px rgba(0, 0, 0, 0.05)', 'none'); |   const boxShadow = useColorModeValue('0px 7px 23px rgba(0, 0, 0, 0.05)', 'none'); | ||||||
|  |  | ||||||
|   const handleDeleteClick = () => |   const handleDeleteClick = () => { | ||||||
|     deleteDevice(serialNumber, { |     deleteDevice(serialNumber, { | ||||||
|       onSuccess: () => { |  | ||||||
|         toast({ |  | ||||||
|           id: `delete-device-success-${serialNumber}`, |  | ||||||
|           title: t('common.success'), |  | ||||||
|           status: 'success', |  | ||||||
|           duration: 5000, |  | ||||||
|           isClosable: true, |  | ||||||
|           position: 'top-right', |  | ||||||
|         }); |  | ||||||
|         navigate('/devices'); |  | ||||||
|       }, |  | ||||||
|       onError: (e) => { |       onError: (e) => { | ||||||
|         if (axios.isAxiosError(e)) { |         if (axios.isAxiosError(e)) { | ||||||
|           toast({ |           toast({ | ||||||
| @@ -107,6 +96,16 @@ const DevicePageWrapper = ({ serialNumber }: Props) => { | |||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|     }); |     }); | ||||||
|  |     toast({ | ||||||
|  |       id: `delete-device-success-${serialNumber}`, | ||||||
|  |       title: t('common.success'), | ||||||
|  |       status: 'success', | ||||||
|  |       duration: 5000, | ||||||
|  |       isClosable: true, | ||||||
|  |       position: 'top-right', | ||||||
|  |     }); | ||||||
|  |     navigate('/'); | ||||||
|  |   }; | ||||||
|  |  | ||||||
|   const connectedTag = React.useMemo(() => { |   const connectedTag = React.useMemo(() => { | ||||||
|     if (!getStatus.data) return null; |     if (!getStatus.data) return null; | ||||||
| @@ -123,7 +122,7 @@ const DevicePageWrapper = ({ serialNumber }: Props) => { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     let icon = getStatus.data.connected ? WifiHigh : WifiSlash; |     let icon = getStatus.data.connected ? WifiHigh : WifiSlash; | ||||||
|     if (getDevice.data?.deviceType === 'SWITCH') |     if (getDevice.data?.deviceType === 'switch') | ||||||
|       icon = getStatus.data.connected ? ethernetConnected : ethernetDisconnected; |       icon = getStatus.data.connected ? ethernetConnected : ethernetDisconnected; | ||||||
|  |  | ||||||
|     return ( |     return ( | ||||||
| @@ -325,8 +324,8 @@ const DevicePageWrapper = ({ serialNumber }: Props) => { | |||||||
|           <DeviceSummary serialNumber={serialNumber} /> |           <DeviceSummary serialNumber={serialNumber} /> | ||||||
|           <DeviceDetails serialNumber={serialNumber} /> |           <DeviceDetails serialNumber={serialNumber} /> | ||||||
|           <DeviceStatisticsCard serialNumber={serialNumber} /> |           <DeviceStatisticsCard serialNumber={serialNumber} /> | ||||||
|           {getDevice.data?.deviceType === 'AP' ? <WifiAnalysisCard serialNumber={serialNumber} /> : null} |           {getDevice.data?.deviceType === 'ap' ? <WifiAnalysisCard serialNumber={serialNumber} /> : null} | ||||||
|           {getDevice.data?.deviceType === 'SWITCH' ? <SwitchPortExamination serialNumber={serialNumber} /> : null} |           {getDevice.data?.deviceType === 'switch' ? <SwitchPortExamination serialNumber={serialNumber} /> : null} | ||||||
|           <DeviceLogsCard serialNumber={serialNumber} /> |           <DeviceLogsCard serialNumber={serialNumber} /> | ||||||
|           {getDevice.data && getDevice.data?.hasRADIUSSessions > 0 ? ( |           {getDevice.data && getDevice.data?.hasRADIUSSessions > 0 ? ( | ||||||
|             <RadiusClientsCard serialNumber={serialNumber} /> |             <RadiusClientsCard serialNumber={serialNumber} /> | ||||||
|   | |||||||
| @@ -737,8 +737,8 @@ const DeviceListCard = () => { | |||||||
|                 ml={2} |                 ml={2} | ||||||
|               > |               > | ||||||
|                 <option value="ALL">All</option> |                 <option value="ALL">All</option> | ||||||
|                 <option value="AP">APs</option> |                 <option value="ap">APs</option> | ||||||
|                 <option value="SWITCH">Switches</option> |                 <option value="switch">Switches</option> | ||||||
|               </Select> |               </Select> | ||||||
|             </> |             </> | ||||||
|           ), |           ), | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Charles
					Charles