diff --git a/core/frontend/src/components/ethernet/AddressDeletionDialog.vue b/core/frontend/src/components/ethernet/AddressDeletionDialog.vue
new file mode 100644
index 0000000000..5d6de7aa08
--- /dev/null
+++ b/core/frontend/src/components/ethernet/AddressDeletionDialog.vue
@@ -0,0 +1,92 @@
+
+
+
+ {{ title }}
+
+
+ {{ message }}
+
+
+
+
+ Abort
+
+
+ Confirm
+
+
+
+
+
+
+
diff --git a/core/frontend/src/components/ethernet/InterfaceCard.vue b/core/frontend/src/components/ethernet/InterfaceCard.vue
index 769652b31b..3777512993 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({