mirror of
				https://github.com/optim-enterprises-bv/OptimCloud-gw-ui.git
				synced 2025-10-30 17:57:46 +00:00 
			
		
		
		
	[WIFI-12285] Add support for FMS database refreshes
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", | ||||
|   "version": "2.9.0(11)", | ||||
|   "version": "2.9.0(12)", | ||||
|   "lockfileVersion": 2, | ||||
|   "requires": true, | ||||
|   "packages": { | ||||
|     "": { | ||||
|       "name": "ucentral-client", | ||||
|       "version": "2.9.0(11)", | ||||
|       "version": "2.9.0(12)", | ||||
|       "license": "ISC", | ||||
|       "dependencies": { | ||||
|         "@chakra-ui/icons": "^2.0.11", | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "ucentral-client", | ||||
|   "version": "2.9.0(11)", | ||||
|   "version": "2.9.0(12)", | ||||
|   "description": "", | ||||
|   "private": true, | ||||
|   "main": "index.tsx", | ||||
|   | ||||
| @@ -685,6 +685,13 @@ | ||||
| 		"update_success": "Entität aktualisiert!", | ||||
| 		"venues_under_root": "Veranstaltungsorte können nicht direkt unter der Root-Entität erstellt werden" | ||||
| 	}, | ||||
| 	"firmware": { | ||||
| 		"db_update_warning": "Dieser Vorgang wird täglich automatisch durchgeführt, ohne dass dieses manuelle Update verwendet werden muss. Die Aktualisierung dieser Datenbank kann bis zu 25 Minuten dauern", | ||||
| 		"last_db_update_modal": "Firmware-Datenbank", | ||||
| 		"last_db_update_title": "Datenbank", | ||||
| 		"start_db_update": "Datenbankaktualisierung starten", | ||||
| 		"started_db_update": "Datenbankaktualisierung gestartet, dieser Vorgang sollte bis zu 25 Minuten dauern" | ||||
| 	}, | ||||
| 	"footer": { | ||||
| 		"powered_by": "Unterstützt von", | ||||
| 		"version": "Ausführung" | ||||
| @@ -1128,6 +1135,7 @@ | ||||
| 		"upgrade_all_devices": "Aktualisieren Sie alle Geräte auf die neueste Firmware", | ||||
| 		"upgrade_all_devices_error": "Fehler beim Aktualisieren von Geräten: {{e}}", | ||||
| 		"upgrade_all_devices_success": "Upgrade von Geräten erfolgreich gestartet!", | ||||
| 		"upgrade_options_available": "Hier sind alle verfügbaren Revisionen, bitte wählen Sie diejenige aus, auf die ALLE Geräte dieses Veranstaltungsortes aktualisiert werden sollen", | ||||
| 		"use_existing": "Benutze existierendes", | ||||
| 		"use_existing_contacts": "Verwenden Sie vorhandene Kontakte", | ||||
| 		"use_this_contact": "Verwenden Sie diesen Kontakt" | ||||
|   | ||||
| @@ -685,6 +685,13 @@ | ||||
| 		"update_success": "Entity updated!", | ||||
| 		"venues_under_root": "Venues cannot be created directly under the root entity" | ||||
| 	}, | ||||
| 	"firmware": { | ||||
| 		"db_update_warning": "This operation is done daily automatically without need to use this manual update. Updating this database can take up to 25 minutes", | ||||
| 		"last_db_update_modal": "Firmware Database", | ||||
| 		"last_db_update_title": "Database", | ||||
| 		"start_db_update": "Start Database Update", | ||||
| 		"started_db_update": "Started database update, this operation should take up to 25 minutes to complete" | ||||
| 	}, | ||||
| 	"footer": { | ||||
| 		"powered_by": "Powered By", | ||||
| 		"version": "Version" | ||||
| @@ -1128,6 +1135,7 @@ | ||||
| 		"upgrade_all_devices": "Upgrade All Devices to Latest Firmware", | ||||
| 		"upgrade_all_devices_error": "Error upgrading devices: {{e}}", | ||||
| 		"upgrade_all_devices_success": "Successfully started upgrading devices!", | ||||
| 		"upgrade_options_available": "Here are all available revisions, please select the one you want ALL of this venue's devices to be upgrade to", | ||||
| 		"use_existing": "Use Existing", | ||||
| 		"use_existing_contacts": "Use Existing Contacts", | ||||
| 		"use_this_contact": "Use this contact" | ||||
|   | ||||
| @@ -685,6 +685,13 @@ | ||||
| 		"update_success": "¡Entidad actualizada!", | ||||
| 		"venues_under_root": "Los lugares no se pueden crear directamente bajo la entidad raíz" | ||||
| 	}, | ||||
| 	"firmware": { | ||||
| 		"db_update_warning": "Esta operación se realiza automáticamente todos los días de forma automática sin necesidad de utilizar esta actualización manual. La actualización de esta base de datos puede tardar hasta 25 minutos", | ||||
| 		"last_db_update_modal": "Base de datos de firmware", | ||||
| 		"last_db_update_title": "Base de datos", | ||||
| 		"start_db_update": "Iniciar actualización de la base de datos", | ||||
| 		"started_db_update": "Actualización de la base de datos iniciada, esta operación debería tardar hasta 25 minutos en completarse" | ||||
| 	}, | ||||
| 	"footer": { | ||||
| 		"powered_by": "energizado por", | ||||
| 		"version": "Versión" | ||||
| @@ -1128,6 +1135,7 @@ | ||||
| 		"upgrade_all_devices": "Actualice todos los dispositivos al firmware más reciente", | ||||
| 		"upgrade_all_devices_error": "Error al actualizar dispositivos: {{e}}", | ||||
| 		"upgrade_all_devices_success": "¡Comenzó con éxito la actualización de dispositivos!", | ||||
| 		"upgrade_options_available": "Aquí están todas las revisiones disponibles, seleccione la que desea que TODOS los dispositivos de este lugar se actualicen", | ||||
| 		"use_existing": "Utilizar existente", | ||||
| 		"use_existing_contacts": "Usar contactos existentes", | ||||
| 		"use_this_contact": "Usa este contacto" | ||||
|   | ||||
| @@ -685,6 +685,13 @@ | ||||
| 		"update_success": "Entité mise à jour !", | ||||
| 		"venues_under_root": "Les lieux ne peuvent pas être créés directement sous l'entité racine" | ||||
| 	}, | ||||
| 	"firmware": { | ||||
| 		"db_update_warning": "Cette opération se fait automatiquement quotidiennement sans avoir besoin d'utiliser cette mise à jour manuelle. La mise à jour de cette base de données peut prendre jusqu'à 25 minutes", | ||||
| 		"last_db_update_modal": "Base de données du micrologiciel", | ||||
| 		"last_db_update_title": "Base de données", | ||||
| 		"start_db_update": "Démarrer la mise à jour de la base de données", | ||||
| 		"started_db_update": "Mise à jour de la base de données démarrée, cette opération devrait prendre jusqu'à 25 minutes" | ||||
| 	}, | ||||
| 	"footer": { | ||||
| 		"powered_by": "Alimenté par", | ||||
| 		"version": "Version" | ||||
| @@ -1128,6 +1135,7 @@ | ||||
| 		"upgrade_all_devices": "Mettre à niveau tous les appareils vers le dernier micrologiciel", | ||||
| 		"upgrade_all_devices_error": "Erreur lors de la mise à jour des appareils : {{e}}", | ||||
| 		"upgrade_all_devices_success": "La mise à niveau des appareils a démarré avec succès !", | ||||
| 		"upgrade_options_available": "Voici toutes les révisions disponibles, veuillez sélectionner celle vers laquelle vous souhaitez que TOUS les appareils de ce lieu soient mis à niveau", | ||||
| 		"use_existing": "Utiliser l'existant", | ||||
| 		"use_existing_contacts": "Utiliser les contacts existants", | ||||
| 		"use_this_contact": "Utilisez ce contact" | ||||
|   | ||||
| @@ -685,6 +685,13 @@ | ||||
| 		"update_success": "Entidade atualizada!", | ||||
| 		"venues_under_root": "Os locais não podem ser criados diretamente na entidade raiz" | ||||
| 	}, | ||||
| 	"firmware": { | ||||
| 		"db_update_warning": "Esta operação é feita automaticamente diariamente sem necessidade de usar esta atualização manual. A atualização deste banco de dados pode levar até 25 minutos", | ||||
| 		"last_db_update_modal": "banco de dados de firmware", | ||||
| 		"last_db_update_title": "base de dados", | ||||
| 		"start_db_update": "Iniciar atualização do banco de dados", | ||||
| 		"started_db_update": "Atualização do banco de dados iniciada, esta operação deve levar até 25 minutos para ser concluída" | ||||
| 	}, | ||||
| 	"footer": { | ||||
| 		"powered_by": "Distribuído por", | ||||
| 		"version": "Versão" | ||||
| @@ -1128,6 +1135,7 @@ | ||||
| 		"upgrade_all_devices": "Atualize todos os dispositivos para o firmware mais recente", | ||||
| 		"upgrade_all_devices_error": "Erro ao atualizar dispositivos: {{e}}", | ||||
| 		"upgrade_all_devices_success": "Atualização de dispositivos iniciada com sucesso!", | ||||
| 		"upgrade_options_available": "Aqui estão todas as revisões disponíveis, selecione aquela para a qual você deseja que TODOS os dispositivos deste local sejam atualizados", | ||||
| 		"use_existing": "Usar existente", | ||||
| 		"use_existing_contacts": "Usar contatos existentes", | ||||
| 		"use_this_contact": "Use este contato" | ||||
|   | ||||
| @@ -32,7 +32,7 @@ export const useGetAvailableFirmware = ({ deviceType }: { deviceType: string }) | ||||
|   const { t } = useTranslation(); | ||||
|   const toast = useToast(); | ||||
|  | ||||
|   return useQuery(['firmware'], () => getAllAvailableFirmware(deviceType), { | ||||
|   return useQuery(['get-device-profile'], () => getAllAvailableFirmware(deviceType), { | ||||
|     enabled: deviceType !== '', | ||||
|     onError: (e: AxiosError) => { | ||||
|       if (!toast.isActive('firmware-fetching-error')) | ||||
| @@ -242,3 +242,23 @@ export const useGetFirmwareDashboard = () => | ||||
|     keepPreviousData: true, | ||||
|     refetchInterval: 30000, | ||||
|   }); | ||||
|  | ||||
| const getLastDbUpdate = async () => | ||||
|   axiosFms.get(`firmwares?updateTimeOnly=true`).then((response) => response.data as { lastUpdateTime: number }); | ||||
| export const useGetFirmwareDbUpdate = () => | ||||
|   useQuery(['firmware', 'db'], getLastDbUpdate, { | ||||
|     keepPreviousData: true, | ||||
|     staleTime: 30 * 1000, | ||||
|   }); | ||||
|  | ||||
| const updateDb = async () => axiosFms.put(`firmwares?update=true`); | ||||
|  | ||||
| export const useUpdateFirmwareDb = () => { | ||||
|   const queryClient = useQueryClient(); | ||||
|  | ||||
|   return useMutation(updateDb, { | ||||
|     onSuccess: () => { | ||||
|       queryClient.invalidateQueries(['firmware', 'db']); | ||||
|     }, | ||||
|   }); | ||||
| }; | ||||
|   | ||||
| @@ -191,6 +191,7 @@ const FirmwareDetailsModal = ({ modalProps, firmware }: Props) => { | ||||
|               ml={2} | ||||
|             /> | ||||
|             {isEditingDescription && ( | ||||
|               // @ts-ignore | ||||
|               <SaveButton onClick={onSaveDescription} ml={2} isCompact size="sm" isLoading={updateFirmware.isLoading} /> | ||||
|             )} | ||||
|           </FormLabel> | ||||
| @@ -202,48 +203,51 @@ const FirmwareDetailsModal = ({ modalProps, firmware }: Props) => { | ||||
|             isDisabled={!isEditingDescription} | ||||
|           /> | ||||
|         </FormControl> | ||||
|         <FormControl> | ||||
|           <FormLabel> | ||||
|             {t('common.notes')}{' '} | ||||
|             <Popover trigger="click" placement="auto"> | ||||
|               {({ onClose }) => ( | ||||
|                 <> | ||||
|                   <PopoverTrigger> | ||||
|                     <IconButton | ||||
|                       aria-label={`${t('crud.add')} ${t('common.note')}`} | ||||
|                       size="sm" | ||||
|                       icon={<Plus size={20} />} | ||||
|                     /> | ||||
|                   </PopoverTrigger> | ||||
|                   <PopoverContent w={breakpoint === 'base' ? 'calc(80vw)' : '500px'}> | ||||
|                     <PopoverArrow /> | ||||
|                     <PopoverCloseButton alignContent="center" mt={1} /> | ||||
|                     <PopoverHeader display="flex">{t('profile.add_new_note')}</PopoverHeader> | ||||
|                     <PopoverBody> | ||||
|                       <Box> | ||||
|                         <Textarea h="100px" placeholder="Your new note" value={newNote} onChange={onNoteChange} /> | ||||
|                       </Box> | ||||
|                       <Center mt={2}> | ||||
|                         <Button | ||||
|                           colorScheme="blue" | ||||
|                           isDisabled={newNote.length === 0} | ||||
|                           onClick={onNoteSubmit(onClose)} | ||||
|                           isLoading={updateFirmware.isLoading} | ||||
|                         > | ||||
|                           {t('crud.add')} | ||||
|                         </Button> | ||||
|                       </Center> | ||||
|                     </PopoverBody> | ||||
|                   </PopoverContent> | ||||
|                 </> | ||||
|               )} | ||||
|             </Popover> | ||||
|           </FormLabel> | ||||
|           <Box overflowX="auto" overflowY="auto" maxH="400px"> | ||||
|             <DataTable columns={columns as Column<object>[]} data={notes} obj={t('common.notes')} minHeight="200px" /> | ||||
|           </Box> | ||||
|         </FormControl> | ||||
|       </SimpleGrid> | ||||
|       <FormControl mt={2}> | ||||
|         <FormLabel> | ||||
|           {t('common.notes')}{' '} | ||||
|           <Popover trigger="click" placement="auto"> | ||||
|             {({ onClose }) => ( | ||||
|               <> | ||||
|                 <PopoverTrigger> | ||||
|                   <IconButton aria-label={`${t('crud.add')} ${t('common.note')}`} size="sm" icon={<Plus size={20} />} /> | ||||
|                 </PopoverTrigger> | ||||
|                 <PopoverContent w={breakpoint === 'base' ? 'calc(80vw)' : '500px'}> | ||||
|                   <PopoverArrow /> | ||||
|                   <PopoverCloseButton alignContent="center" mt={1} /> | ||||
|                   <PopoverHeader display="flex">{t('profile.add_new_note')}</PopoverHeader> | ||||
|                   <PopoverBody> | ||||
|                     <Box> | ||||
|                       <Textarea h="100px" placeholder="Your new note" value={newNote} onChange={onNoteChange} /> | ||||
|                     </Box> | ||||
|                     <Center mt={2}> | ||||
|                       <Button | ||||
|                         colorScheme="blue" | ||||
|                         isDisabled={newNote.length === 0} | ||||
|                         onClick={onNoteSubmit(onClose)} | ||||
|                         isLoading={updateFirmware.isLoading} | ||||
|                       > | ||||
|                         {t('crud.add')} | ||||
|                       </Button> | ||||
|                     </Center> | ||||
|                   </PopoverBody> | ||||
|                 </PopoverContent> | ||||
|               </> | ||||
|             )} | ||||
|           </Popover> | ||||
|         </FormLabel> | ||||
|       </FormControl> | ||||
|       <Box overflowX="auto" overflowY="auto" maxH="400px" mb={4}> | ||||
|         <DataTable | ||||
|           columns={columns as Column<object>[]} | ||||
|           data={notes} | ||||
|           obj={t('common.notes')} | ||||
|           minHeight="200px" | ||||
|           showAllRows | ||||
|           hideControls | ||||
|         /> | ||||
|       </Box> | ||||
|     </Modal> | ||||
|   ); | ||||
| }; | ||||
|   | ||||
							
								
								
									
										101
									
								
								src/pages/Firmware/List/UpdateDbButton.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								src/pages/Firmware/List/UpdateDbButton.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| import * as React from 'react'; | ||||
| import { | ||||
|   Alert, | ||||
|   AlertDescription, | ||||
|   AlertIcon, | ||||
|   AlertTitle, | ||||
|   Box, | ||||
|   Button, | ||||
|   Center, | ||||
|   Tag, | ||||
|   TagLabel, | ||||
|   Text, | ||||
|   useDisclosure, | ||||
|   useToast, | ||||
| } from '@chakra-ui/react'; | ||||
| import axios from 'axios'; | ||||
| import { Database } from 'phosphor-react'; | ||||
| import { useTranslation } from 'react-i18next'; | ||||
| import FormattedDate from 'components/InformationDisplays/FormattedDate'; | ||||
| import { Modal } from 'components/Modals/Modal'; | ||||
| import { useGetFirmwareDbUpdate, useUpdateFirmwareDb } from 'hooks/Network/Firmware'; | ||||
|  | ||||
| const UpdateDbButton = () => { | ||||
|   const { t } = useTranslation(); | ||||
|   const toast = useToast(); | ||||
|   const { isOpen, onOpen, onClose } = useDisclosure(); | ||||
|   const updateDb = useUpdateFirmwareDb(); | ||||
|   const getLastUpdate = useGetFirmwareDbUpdate(); | ||||
|  | ||||
|   const onUpdateClick = async () => { | ||||
|     updateDb.mutate(undefined, { | ||||
|       onSuccess: () => { | ||||
|         toast({ | ||||
|           id: `firmware-db-update-success`, | ||||
|           title: t('common.success'), | ||||
|           description: t('firmware.started_db_update'), | ||||
|           status: 'success', | ||||
|           duration: 5000, | ||||
|           isClosable: true, | ||||
|           position: 'top-right', | ||||
|         }); | ||||
|       }, | ||||
|       onError: (e) => { | ||||
|         if (axios.isAxiosError(e)) { | ||||
|           toast({ | ||||
|             id: `firmware-db-update-error`, | ||||
|             title: t('common.error'), | ||||
|             description: e?.response?.data?.ErrorDescription, | ||||
|             status: 'error', | ||||
|             duration: 5000, | ||||
|             isClosable: true, | ||||
|             position: 'top-right', | ||||
|           }); | ||||
|         } | ||||
|       }, | ||||
|     }); | ||||
|   }; | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       <Button colorScheme="teal" leftIcon={<Database size={20} />} onClick={onOpen}> | ||||
|         {t('firmware.last_db_update_title')} | ||||
|       </Button> | ||||
|       <Modal | ||||
|         isOpen={isOpen} | ||||
|         onClose={onClose} | ||||
|         title={t('firmware.last_db_update_modal')} | ||||
|         tags={ | ||||
|           <Tag colorScheme="blue" size="lg"> | ||||
|             <TagLabel display="flex"> | ||||
|               <Text mr={1}>Last Update:</Text> | ||||
|               <FormattedDate date={getLastUpdate.data?.lastUpdateTime} /> | ||||
|             </TagLabel> | ||||
|           </Tag> | ||||
|         } | ||||
|       > | ||||
|         <Box> | ||||
|           <Alert status="warning"> | ||||
|             <AlertIcon /> | ||||
|             <Box> | ||||
|               <AlertTitle>{t('common.warning')}</AlertTitle> | ||||
|               <AlertDescription>{t('firmware.db_update_warning')}</AlertDescription> | ||||
|             </Box> | ||||
|           </Alert> | ||||
|           <Center my={4}> | ||||
|             <Button | ||||
|               colorScheme="red" | ||||
|               leftIcon={<Database size={20} />} | ||||
|               onClick={onUpdateClick} | ||||
|               isLoading={updateDb.isLoading} | ||||
|             > | ||||
|               {t('firmware.start_db_update')} | ||||
|             </Button> | ||||
|           </Center> | ||||
|         </Box> | ||||
|       </Modal> | ||||
|     </> | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| export default UpdateDbButton; | ||||
| @@ -16,6 +16,7 @@ import { MagnifyingGlass } from 'phosphor-react'; | ||||
| import { useTranslation } from 'react-i18next'; | ||||
| import { v4 as uuid } from 'uuid'; | ||||
| import FirmwareDetailsModal from './Modal'; | ||||
| import UpdateDbButton from './UpdateDbButton'; | ||||
| import UriCell from './UriCell'; | ||||
| import { RefreshButton } from 'components/Buttons/RefreshButton'; | ||||
| import { CardBody } from 'components/Containers/Card/CardBody'; | ||||
| @@ -143,6 +144,7 @@ const FirmwareListTable = () => { | ||||
|           </Box> | ||||
|           <Text>{t('controller.firmware.show_dev_releases')}</Text> | ||||
|           <Switch isChecked={showDevFirmware} onChange={toggle} size="lg" /> | ||||
|           <UpdateDbButton /> | ||||
|           <RefreshButton | ||||
|             onClick={() => { | ||||
|               getDeviceTypes.refetch(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Charles
					Charles