diff --git a/core/frontend/src/components/ethernet/AddressDeletionDialog.vue b/core/frontend/src/components/ethernet/AddressDeletionDialog.vue new file mode 100644 index 000000000..5d6de7aa0 --- /dev/null +++ b/core/frontend/src/components/ethernet/AddressDeletionDialog.vue @@ -0,0 +1,92 @@ + + + diff --git a/core/frontend/src/components/ethernet/InterfaceCard.vue b/core/frontend/src/components/ethernet/InterfaceCard.vue index 769652b31..377751299 100644 --- a/core/frontend/src/components/ethernet/InterfaceCard.vue +++ b/core/frontend/src/components/ethernet/InterfaceCard.vue @@ -47,6 +47,11 @@ v-model="show_creation_dialog" :interface-name="adapter.name" /> + address.mode === AddressMode.unmanaged) }, + is_interface_last_ip_address(): boolean { + return this.adapter.addresses.length === 1 + }, + }, + mounted() { + beacon.registerBeaconListener(this) }, methods: { + async fireConfirmDeletionModal(type: 'last-ip-address' | 'ip-being-used'): Promise { + const dialog = this.$refs.deletionDialog as InstanceType + + this.deletion_dialog_type = type + this.show_deletion_dialog = true + + return new Promise((resolve) => { + dialog.resolveCallback = resolve + }) + }, + /** + * Opens a dialog and requests the user to confirm the deletion of the IP address. + * @returns {Promise} - Resolves to true if no confirmation is needed or + * granted and false otherwise. + */ + async confirm_last_interface_ip(): Promise { + if (this.is_interface_last_ip_address) { + return this.fireConfirmDeletionModal('last-ip-address') + } + + return true + }, + /** + * Opens a dialog and requests the user to confirm the deletion of current used IP address. + * @returns {Promise} - Resolves to true if no confirmation is needed or + * granted and false otherwise. + */ + async confirm_ip_being_used(ip: string): Promise { + const ip_being_used = ip === beacon.nginx_ip_address + + if (ip_being_used) { + return this.fireConfirmDeletionModal('ip-being-used') + } + + return true + }, showable_mode_name(mode: AddressMode): string { switch (mode) { case AddressMode.client: return 'Dynamic IP' @@ -141,6 +193,13 @@ export default Vue.extend({ this.show_creation_dialog = true }, async deleteAddress(ip: string): Promise { + const confirmed_ip_used = await this.confirm_ip_being_used(ip) + const confirmed_last_ip = confirmed_ip_used && await this.confirm_last_interface_ip() + + if (!confirmed_ip_used || !confirmed_last_ip) { + return + } + ethernet.setUpdatingInterfaces(true) await back_axios({ diff --git a/core/frontend/src/components/wifi/DisconnectionDialog.vue b/core/frontend/src/components/wifi/DisconnectionDialog.vue index 5de9e945d..fa9478231 100644 --- a/core/frontend/src/components/wifi/DisconnectionDialog.vue +++ b/core/frontend/src/components/wifi/DisconnectionDialog.vue @@ -18,6 +18,26 @@ + + + mdi-alert-octagon + + + + + This IP address is currently being used to access BlueOS. + Deleting it could prevent you from accessing your vehicle. Are you sure you want to disconnect? + +
@@ -58,6 +78,7 @@ import Vue, { PropType } from 'vue' import Notifier from '@/libs/notifier' +import beacon from '@/store/beacon' import wifi from '@/store/wifi' import { wifi_service } from '@/types/frontend_services' import { Network, WifiStatus } from '@/types/wifi' @@ -100,6 +121,12 @@ export default Vue.extend({ } return { ...this.network, ...this.status } }, + holds_ip_being_used(): boolean { + return this.status?.ip_address === beacon.nginx_ip_address + }, + }, + mounted() { + beacon.registerBeaconListener(this) }, methods: { toggleInfoShow(): void {