Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/lint-web.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ jobs:
run: pnpm run lint
- name: Audit
working-directory: ./web
run: pnpm audit --prod
run: pnpm audit --prod --ignore-unfixable
1 change: 1 addition & 0 deletions web/messages/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"controls_close": "Close",
"controls_back": "Back",
"controls_delete": "Delete",
"controls_reset": "Reset",
"controls_edit": "Edit",
"controls_logout": "Logout",
"controls_keep": "Keep",
Expand Down
6 changes: 6 additions & 0 deletions web/messages/en/modal.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
"modal_delete_location_body": "Deleting location {name} will also delete related gateways. This action cannot be undone.",
"modal_delete_network_device_title": "Delete device",
"modal_delete_network_device_body": "Are you sure you want to delete this device? This action cannot be undone.",
"modal_delete_user_title": "Delete user",
"modal_delete_user_body": "Are you sure you want to delete user {name}? This action cannot be undone.",
"modal_delete_edge_title": "Delete edge",
"modal_delete_edge_body": "Are you sure you want to delete edge {name}? This action cannot be undone.",
"modal_delete_group_title": "Delete group",
"modal_delete_group_body": "Are you sure you want to delete group {name}? This action cannot be undone.",
"modal_delete_user_device_title": "Delete device",
"modal_delete_user_device_body": "Are you sure you want to delete the {name} device? This action cannot be undone.",
"modal_delete_openid_client_title": "Delete application",
Expand Down
4 changes: 4 additions & 0 deletions web/messages/en/openid.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
"openid_table_top_title": "All apps",
"openid_delete_success": "OpenID application deleted",
"openid_delete_failed": "Failed to delete OpenID application",
"settings_openid_provider_delete_confirm_title": "Delete Identity Provider",
"settings_openid_provider_delete_confirm_body": "Are you sure you want to delete this external identity provider? This action cannot be undone.",
"settings_openid_provider_delete_success": "Identity provider deleted",
"settings_openid_provider_delete_failed": "Failed to delete identity provider",
"openid_consent_title": "{name} would like to",
"openid_consent_scope_openid": "Use OpenID.",
"openid_consent_scope_profile": "Know basic information from your profile.",
Expand Down
7 changes: 6 additions & 1 deletion web/messages/en/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,14 @@
"settings_activity_log_streaming_no_upstreams_subtitle": "Click the button below to add an activity log provider and start streaming events.",
"settings_activity_log_streaming_add_log_streaming_button": "Add log streaming.",
"settings_activity_log_streaming_delete_log_streaming_title": "Delete destination confirmation",
"settings_activity_log_streaming_delete_log_streaming_failed": "Failed to delete log stream destination.",
"settings_activity_log_streaming_table_title": "All log streams",
"settings_activity_log_streaming_table_header_name": "Name",
"settings_activity_log_streaming_table_stream_type_name": "Destination",
"settings_msg_saved": "Settings saved",
"settings_msg_save_failed": "Failed to save settings"
"settings_msg_save_failed": "Failed to save settings",
"settings_smtp_reset_confirm_title": "Reset SMTP Settings",
"settings_smtp_reset_confirm_body": "Are you sure you want to reset SMTP settings? This action cannot be undone.",
"settings_smtp_reset_success": "SMTP settings reset",
"settings_smtp_reset_failed": "Failed to reset SMTP settings"
}
6 changes: 5 additions & 1 deletion web/messages/en/webhooks.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
"webhooks_table_title": "All Webhooks",
"webhooks_add": "Add new webhook",
"webhooks_empty_title": "You don't have any Webhooks.",
"webhooks_empty_subtitle": "To add one, click the button below."
"webhooks_empty_subtitle": "To add one, click the button below.",
"webhooks_delete_confirm_title": "Delete Webhook",
"webhooks_delete_confirm_body": "Are you sure you want to delete this webhook? This action cannot be undone.",
"webhooks_delete_success": "Webhook deleted",
"webhooks_delete_failed": "Failed to delete webhook"
}
2 changes: 2 additions & 0 deletions web/pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
auditConfig: {}

onlyBuiltDependencies:
- '@parcel/watcher'
- '@swc/core'
Expand Down
19 changes: 10 additions & 9 deletions web/src/pages/EdgesPage/EdgesTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import { TableCell } from '../../shared/defguard-ui/components/table/TableCell/T
import { TableEditCell } from '../../shared/defguard-ui/components/table/TableEditCell/TableEditCell';
import { TableTop } from '../../shared/defguard-ui/components/table/TableTop/TableTop';
import { isPresent } from '../../shared/defguard-ui/utils/isPresent';
import { openModal } from '../../shared/hooks/modalControls/modalsSubjects';
import { ModalName } from '../../shared/hooks/modalControls/modalTypes';
import { getEdgesQueryOptions, getLicenseInfoQueryOptions } from '../../shared/query';
import { displayDate } from '../../shared/utils/displayDate';
import { canUseEnterpriseFeature, licenseActionCheck } from '../../shared/utils/license';
Expand Down Expand Up @@ -72,13 +74,6 @@ export const EdgesTable = () => {

const navigate = useNavigate();

const { mutate: deleteEdge } = useMutation({
mutationFn: api.edge.deleteEdge,
meta: {
invalidate: ['edge'],
},
});

const { mutate: toggleEdge } = useMutation({
mutationFn: api.edge.editEdge,
meta: {
Expand Down Expand Up @@ -239,7 +234,13 @@ export const EdgesTable = () => {
icon: 'delete',
variant: 'danger',
onClick: () => {
deleteEdge(rowData.id);
openModal(ModalName.ConfirmAction, {
title: m.modal_delete_edge_title(),
contentMd: m.modal_delete_edge_body({ name: rowData.name }),
actionPromise: () => api.edge.deleteEdge(rowData.id),
invalidateKeys: [['edge']],
submitProps: { text: m.controls_delete(), variant: 'critical' },
});
},
},
],
Expand All @@ -250,7 +251,7 @@ export const EdgesTable = () => {
},
}),
],
[deleteEdge, navigate, toggleEdge],
[navigate, toggleEdge],
);

const table = useReactTable({
Expand Down
33 changes: 14 additions & 19 deletions web/src/pages/EditEdgePage/EditEdgePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { Snackbar } from '../../shared/defguard-ui/providers/snackbar/snackbar';
import { ThemeSpacing } from '../../shared/defguard-ui/types';
import { useAppForm } from '../../shared/form';
import { formChangeLogic } from '../../shared/formLogic';
import { openModal } from '../../shared/hooks/modalControls/modalsSubjects';
import { ModalName } from '../../shared/hooks/modalControls/modalTypes';
import { getEdgeQueryOptions } from '../../shared/query';

export const EditEdgePage = () => {
Expand Down Expand Up @@ -69,23 +71,6 @@ const EditEdgeForm = ({ edge }: { edge: Edge }) => {
},
});

const { mutate: deleteEdge, isPending: deletePending } = useMutation({
mutationFn: () => api.edge.deleteEdge(edge.id),
meta: {
invalidate: ['edge'],
},
onSuccess: () => {
navigate({
to: '/edges',
replace: true,
});
Snackbar.default(m.edge_delete_success());
},
onError: () => {
Snackbar.error(m.edge_delete_failed());
},
});

const defaultValues = useMemo((): FormFields => ({ ...edge }), [edge]);

const form = useAppForm({
Expand Down Expand Up @@ -142,9 +127,19 @@ const EditEdgeForm = ({ edge }: { edge: Edge }) => {
deleteProps={{
text: m.edge_edit_delete(),
onClick: () => {
deleteEdge();
openModal(ModalName.ConfirmAction, {
title: m.modal_delete_edge_title(),
contentMd: m.modal_delete_edge_body({ name: edge.name }),
actionPromise: () => api.edge.deleteEdge(edge.id),
invalidateKeys: [['edge']],
submitProps: { text: m.edge_edit_delete(), variant: 'critical' },
onSuccess: () => {
navigate({ to: '/edges', replace: true });
Snackbar.default(m.edge_delete_success());
},
onError: () => Snackbar.error(m.edge_delete_failed()),
});
},
loading: deletePending,
disabled: isSubmitting,
}}
submitProps={{
Expand Down
41 changes: 21 additions & 20 deletions web/src/pages/EditGatewayPage/EditGatewayPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import { Snackbar } from '../../shared/defguard-ui/providers/snackbar/snackbar';
import { ThemeSpacing } from '../../shared/defguard-ui/types';
import { useAppForm } from '../../shared/form';
import { formChangeLogic } from '../../shared/formLogic';
import { getGatewayQueryOptions } from '../../shared/query';
import { openModal } from '../../shared/hooks/modalControls/modalsSubjects';
import { ModalName } from '../../shared/hooks/modalControls/modalTypes';
import { getGatewayQueryOptions, getLocationQueryOptions } from '../../shared/query';

export const EditGatewayPage = () => {
const { gatewayId } = useParams({
Expand Down Expand Up @@ -56,6 +58,9 @@ type FormFields = z.infer<typeof formSchema>;

const EditGatewayForm = ({ gateway }: { gateway: Gateway }) => {
const navigate = useNavigate();
const { data: location } = useSuspenseQuery(
getLocationQueryOptions(gateway.location_id),
);

const { mutateAsync: editGateway } = useMutation({
mutationFn: api.gateway.editGateway,
Expand All @@ -70,23 +75,6 @@ const EditGatewayForm = ({ gateway }: { gateway: Gateway }) => {
},
});

const { mutate: deleteGateway, isPending: deletePending } = useMutation({
mutationFn: () => api.gateway.deleteGateway(gateway.id),
meta: {
invalidate: [['gateway'], ['network']],
},
onSuccess: () => {
navigate({
to: '/locations',
replace: true,
});
Snackbar.default(m.gateway_delete_success());
},
onError: () => {
Snackbar.error(m.gateway_delete_failed());
},
});

const defaultValues = useMemo((): FormFields => ({ ...gateway }), [gateway]);

const form = useAppForm({
Expand Down Expand Up @@ -144,9 +132,22 @@ const EditGatewayForm = ({ gateway }: { gateway: Gateway }) => {
deleteProps={{
text: m.gateway_edit_delete(),
onClick: () => {
deleteGateway();
openModal(ModalName.ConfirmAction, {
title: m.modal_delete_gateway_title(),
contentMd: m.modal_delete_gateway_body({
name: gateway.name,
locationName: location.name,
}),
actionPromise: () => api.gateway.deleteGateway(gateway.id),
invalidateKeys: [['gateway'], ['network']],
submitProps: { text: m.gateway_edit_delete(), variant: 'critical' },
onSuccess: () => {
navigate({ to: '/locations', replace: true });
Snackbar.default(m.gateway_delete_success());
},
onError: () => Snackbar.error(m.gateway_delete_failed()),
});
},
loading: deletePending,
disabled: isSubmitting,
}}
submitProps={{
Expand Down
29 changes: 14 additions & 15 deletions web/src/pages/EditLocationPage/EditLocationPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import { ThemeSpacing } from '../../shared/defguard-ui/types';
import { isPresent } from '../../shared/defguard-ui/utils/isPresent';
import { useAppForm } from '../../shared/form';
import { formChangeLogic } from '../../shared/formLogic';
import { openModal } from '../../shared/hooks/modalControls/modalsSubjects';
import { ModalName } from '../../shared/hooks/modalControls/modalTypes';
import { getLicenseInfoQueryOptions, getLocationQueryOptions } from '../../shared/query';
import {
canUseBusinessFeature,
Expand Down Expand Up @@ -192,19 +194,6 @@ const EditLocationForm = ({ location }: { location: NetworkLocation }) => {
},
});

const { mutate: deleteLocation, isPending: deletePending } = useMutation({
mutationFn: () => api.location.deleteLocation(location.id),
meta: {
invalidate: ['network'],
},
onSuccess: () => {
navigate({
to: '/locations',
replace: true,
});
},
});

const defaultValues = useMemo(
(): FormFields => ({
name: location.name,
Expand Down Expand Up @@ -538,9 +527,19 @@ const EditLocationForm = ({ location }: { location: NetworkLocation }) => {
deleteProps={{
text: 'Delete location',
onClick: () => {
deleteLocation();
openModal(ModalName.ConfirmAction, {
title: m.modal_delete_location_title(),
contentMd: m.modal_delete_location_body({ name: location.name }),
actionPromise: () => api.location.deleteLocation(location.id),
invalidateKeys: [['network'], ['enterprise_info']],
submitProps: { text: m.controls_delete(), variant: 'critical' },
onSuccess: () => {
Snackbar.default(m.location_delete_success());
navigate({ to: '/locations', replace: true });
},
onError: () => Snackbar.error(m.location_delete_failed()),
});
},
loading: deletePending,
disabled: isSubmitting,
}}
cancelProps={{
Expand Down
17 changes: 8 additions & 9 deletions web/src/pages/GroupsPage/components/GroupsTable/GroupsTable.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useMutation } from '@tanstack/react-query';
import {
createColumnHelper,
getCoreRowModel,
Expand Down Expand Up @@ -33,12 +32,6 @@ const columnHelper = createColumnHelper<RowData>();
export const GroupsTable = ({ groups, users }: Props) => {
const [search, setSearch] = useState('');
const reservedNames = useMemo(() => groups.map((g) => g.name), [groups]);
const { mutate: deleteGroup } = useMutation({
mutationFn: api.group.deleteGroup,
meta: {
invalidate: [['group'], ['group-info']],
},
});

const transformedData = useMemo(() => {
let data = groups;
Expand Down Expand Up @@ -123,15 +116,21 @@ export const GroupsTable = ({ groups, users }: Props) => {
icon: 'delete',
variant: 'danger',
onClick: () => {
deleteGroup(rowData.name);
openModal(ModalName.ConfirmAction, {
title: m.modal_delete_group_title(),
contentMd: m.modal_delete_group_body({ name: rowData.name }),
actionPromise: () => api.group.deleteGroup(rowData.name),
invalidateKeys: [['group'], ['group-info']],
submitProps: { text: m.controls_delete(), variant: 'critical' },
});
},
},
];
return <TableEditCell menuItems={[{ items: menuItems }]} />;
},
}),
],
[deleteGroup, reservedNames, users],
[reservedNames, users],
);

const table = useReactTable({
Expand Down
16 changes: 12 additions & 4 deletions web/src/pages/LocationsPage/components/GatewaysTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { TableBody } from '../../../shared/defguard-ui/components/table/TableBod
import { TableCell } from '../../../shared/defguard-ui/components/table/TableCell/TableCell';
import { TableEditCell } from '../../../shared/defguard-ui/components/table/TableEditCell/TableEditCell';
import { TableTop } from '../../../shared/defguard-ui/components/table/TableTop/TableTop';
import { Snackbar } from '../../../shared/defguard-ui/providers/snackbar/snackbar';
import { openModal } from '../../../shared/hooks/modalControls/modalsSubjects';
import { ModalName } from '../../../shared/hooks/modalControls/modalTypes';
import { getGatewaysQueryOptions } from '../../../shared/query';
Expand Down Expand Up @@ -211,10 +212,17 @@ export const GatewaysTable = () => {
icon: 'delete',
variant: 'danger',
onClick: () => {
openModal(ModalName.DeleteGateway, {
id: rowData.id,
name: rowData.name,
locationName: rowData.location_name,
openModal(ModalName.ConfirmAction, {
title: m.modal_delete_gateway_title(),
contentMd: m.modal_delete_gateway_body({
name: rowData.name,
locationName: rowData.location_name,
}),
actionPromise: () => api.gateway.deleteGateway(rowData.id),
invalidateKeys: [['gateway'], ['network']],
submitProps: { text: m.controls_delete(), variant: 'critical' },
onSuccess: () => Snackbar.default(m.gateway_delete_success()),
onError: () => Snackbar.error(m.gateway_delete_failed()),
});
},
},
Expand Down
13 changes: 10 additions & 3 deletions web/src/pages/LocationsPage/components/LocationsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from '@tanstack/react-table';
import { useMemo, useState } from 'react';
import { m } from '../../../paraglide/messages';
import api from '../../../shared/api/api';
import type { NetworkLocation } from '../../../shared/api/types';
import { GatewaysStatusBadge } from '../../../shared/components/GatewaysStatusBadge/GatewaysStatusBadge';
import { TableValuesListCell } from '../../../shared/components/TableValuesListCell/TableValuesListCell';
Expand All @@ -23,6 +24,7 @@ import { TableBody } from '../../../shared/defguard-ui/components/table/TableBod
import { TableCell } from '../../../shared/defguard-ui/components/table/TableCell/TableCell';
import { TableEditCell } from '../../../shared/defguard-ui/components/table/TableEditCell/TableEditCell';
import { TableTop } from '../../../shared/defguard-ui/components/table/TableTop/TableTop';
import { Snackbar } from '../../../shared/defguard-ui/providers/snackbar/snackbar';
import { ThemeSpacing, ThemeVariable } from '../../../shared/defguard-ui/types';
import { openModal } from '../../../shared/hooks/modalControls/modalsSubjects';
import { ModalName } from '../../../shared/hooks/modalControls/modalTypes';
Expand Down Expand Up @@ -281,9 +283,14 @@ export const LocationsTable = () => {
text: m.controls_delete(),
variant: 'danger',
onClick: () => {
openModal(ModalName.DeleteLocation, {
id: row.id,
name: row.name,
openModal(ModalName.ConfirmAction, {
title: m.modal_delete_location_title(),
contentMd: m.modal_delete_location_body({ name: row.name }),
actionPromise: () => api.location.deleteLocation(row.id),
invalidateKeys: [['network'], ['enterprise_info']],
submitProps: { text: m.controls_delete(), variant: 'critical' },
onSuccess: () => Snackbar.default(m.location_delete_success()),
onError: () => Snackbar.error(m.location_delete_failed()),
});
},
},
Expand Down
Loading
Loading