Skip to content

Commit bb79711

Browse files
committed
warn before deleting disconnected/disabled gw
1 parent 782425b commit bb79711

4 files changed

Lines changed: 67 additions & 17 deletions

File tree

web/messages/en/modal.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
"modal_selection_title": "Select items",
99
"modal_delete_gateway_title": "Delete Gateway",
1010
"modal_delete_gateway_body": "Deleting gateway {name} may cause location {locationName} to stop working if it is the only Gateway connected to this location or if other connected Gateways are currently unavailable. This action cannot be undone.",
11+
"modal_delete_gateway_disabled_body": "Gateway **{name}** is currently **disabled**. Deleting it now will make it permanently unusable. Are you sure you want to proceed?",
12+
"modal_delete_gateway_disconnected_body": "Gateway **{name}** is currently **disconnected**. Deleting it now will make it permanently unusable. Are you sure you want to proceed?",
1113
"modal_delete_location_title": "Delete location",
1214
"modal_delete_location_body": "Deleting location {name} will also delete related gateways. This action cannot be undone.",
1315
"modal_add_location_title": "Select location type",

web/src/pages/EditGatewayPage/EditGatewayPage.tsx

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,29 @@ const EditGatewayForm = ({ gateway }: { gateway: Gateway }) => {
5252
getLocationQueryOptions(gateway.location_id),
5353
);
5454

55+
const isConnected = useMemo(() => {
56+
if (gateway.connected_at == null) {
57+
return false;
58+
}
59+
if (gateway.disconnected_at == null) {
60+
return true;
61+
}
62+
return gateway.connected_at >= gateway.disconnected_at;
63+
}, [gateway.connected_at, gateway.disconnected_at]);
64+
65+
const getDeleteModalContent = () => {
66+
if (!gateway.enabled) {
67+
return m.modal_delete_gateway_disabled_body({ name: gateway.name });
68+
}
69+
if (!isConnected) {
70+
return m.modal_delete_gateway_disconnected_body({ name: gateway.name });
71+
}
72+
return m.modal_delete_gateway_body({
73+
name: gateway.name,
74+
locationName: location.name,
75+
});
76+
};
77+
5578
const { mutateAsync: editGateway } = useMutation({
5679
mutationFn: api.gateway.editGateway,
5780
meta: {
@@ -167,10 +190,7 @@ const EditGatewayForm = ({ gateway }: { gateway: Gateway }) => {
167190
onClick: () => {
168191
openModal(ModalName.ConfirmAction, {
169192
title: m.modal_delete_gateway_title(),
170-
contentMd: m.modal_delete_gateway_body({
171-
name: gateway.name,
172-
locationName: location.name,
173-
}),
193+
contentMd: getDeleteModalContent(),
174194
actionPromise: () => api.gateway.deleteGateway(gateway.id),
175195
invalidateKeys: [['gateway'], ['network']],
176196
submitProps: { text: m.gateway_edit_delete(), variant: 'critical' },

web/src/pages/LocationsPage/components/GatewaysTable.tsx

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,20 @@ export const GatewaysTable = () => {
198198
enableResizing: false,
199199
cell: (info) => {
200200
const rowData = info.row.original;
201+
202+
const getDeleteModalContent = () => {
203+
if (!rowData.enabled) {
204+
return m.modal_delete_gateway_disabled_body({ name: rowData.name });
205+
}
206+
if (!rowData.connected) {
207+
return m.modal_delete_gateway_disconnected_body({ name: rowData.name });
208+
}
209+
return m.modal_delete_gateway_body({
210+
name: rowData.name,
211+
locationName: rowData.location_name,
212+
});
213+
};
214+
201215
const menuItems: MenuItemsGroup[] = [
202216
{
203217
items: [
@@ -235,10 +249,7 @@ export const GatewaysTable = () => {
235249
onClick: () => {
236250
openModal(ModalName.ConfirmAction, {
237251
title: m.modal_delete_gateway_title(),
238-
contentMd: m.modal_delete_gateway_body({
239-
name: rowData.name,
240-
locationName: rowData.location_name,
241-
}),
252+
contentMd: getDeleteModalContent(),
242253
actionPromise: () => api.gateway.deleteGateway(rowData.id),
243254
invalidateKeys: [['gateway'], ['network']],
244255
submitProps: { text: m.controls_delete(), variant: 'critical' },

web/src/shared/components/GatewaysStatusBadge/GatewaysStatusBadge.tsx

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import {
1010
useFloating,
1111
useInteractions,
1212
} from '@floating-ui/react';
13-
import { useMutation } from '@tanstack/react-query';
1413
import { useNavigate } from '@tanstack/react-router';
1514
import clsx from 'clsx';
1615
import { type HTMLProps, useMemo, useState } from 'react';
@@ -26,7 +25,10 @@ import { Icon } from '../../defguard-ui/components/Icon';
2625
import type { IconKindValue } from '../../defguard-ui/components/Icon/icon-types';
2726
import { InteractionBox } from '../../defguard-ui/components/InteractionBox/InteractionBox';
2827
import { SizedBox } from '../../defguard-ui/components/SizedBox/SizedBox';
28+
import { Snackbar } from '../../defguard-ui/providers/snackbar/snackbar';
2929
import { ThemeSpacing } from '../../defguard-ui/types';
30+
import { openModal } from '../../hooks/modalControls/modalsSubjects';
31+
import { ModalName } from '../../hooks/modalControls/modalTypes';
3032
import './style.scss';
3133

3234
type Status = 'all' | 'none' | 'some';
@@ -151,13 +153,6 @@ const FloatingMenu = ({
151153
const disconnected = useMemo(() => status.filter((gw) => !gw.connected), [status]);
152154
const navigate = useNavigate();
153155

154-
const { mutate: removeGw } = useMutation({
155-
mutationFn: api.gateway.deleteGateway,
156-
meta: {
157-
invalidate: [['gateway'], ['network']],
158-
},
159-
});
160-
161156
return (
162157
<div className={clsx('gateways-status-floating', className)} {...rest}>
163158
{connected.length > 0 && (
@@ -198,7 +193,29 @@ const FloatingMenu = ({
198193
icon="close"
199194
iconSize={20}
200195
onClick={() => {
201-
removeGw(gw.id);
196+
const getDeleteModalContent = () => {
197+
if (!gw.enabled) {
198+
return m.modal_delete_gateway_disabled_body({ name: gw.name });
199+
}
200+
if (!gw.connected) {
201+
return m.modal_delete_gateway_disconnected_body({
202+
name: gw.name,
203+
});
204+
}
205+
return m.modal_delete_gateway_body({
206+
name: gw.name,
207+
locationName: gw.location_name,
208+
});
209+
};
210+
openModal(ModalName.ConfirmAction, {
211+
title: m.modal_delete_gateway_title(),
212+
contentMd: getDeleteModalContent(),
213+
actionPromise: () => api.gateway.deleteGateway(gw.id),
214+
invalidateKeys: [['gateway'], ['network']],
215+
submitProps: { text: m.controls_delete(), variant: 'critical' },
216+
onSuccess: () => Snackbar.default(m.gateway_delete_success()),
217+
onError: () => Snackbar.error(m.gateway_delete_failed()),
218+
});
202219
}}
203220
/>
204221
</li>

0 commit comments

Comments
 (0)