Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [M3-7109] - Add AGLB Delete Route Dialog #9735

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
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Upcoming Features
---

Add AGLB Route Delete Dialog ([#9735](https://github.com/linode/manager/pull/9735))
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,19 @@ import { useOrder } from 'src/hooks/useOrder';
import { usePagination } from 'src/hooks/usePagination';
import { useLoadBalancerRoutesQuery } from 'src/queries/aglb/routes';

import { DeleteRouteDialog } from './Routes/DeleteRouteDialog';
import { RulesTable } from './RulesTable';

import type { Filter } from '@linode/api-v4';
import type { Filter, Route } from '@linode/api-v4';

const PREFERENCE_KEY = 'loadbalancer-routes';

export const LoadBalancerRoutes = () => {
const { loadbalancerId } = useParams<{ loadbalancerId: string }>();

const [query, setQuery] = useState<string>();
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
const [selectedRouteId, setSelectedRouteId] = useState<number>();

const pagination = usePagination(1, PREFERENCE_KEY);

Expand Down Expand Up @@ -64,6 +67,15 @@ export const LoadBalancerRoutes = () => {
filter
);

const selectedRoute = routes?.data.find(
(route) => route.id === selectedRouteId
);

const onDeleteRoute = (route: Route) => {
setIsDeleteDialogOpen(true);
setSelectedRouteId(route.id);
};

if (isLoading) {
return <CircleProgress />;
}
Expand All @@ -72,14 +84,14 @@ export const LoadBalancerRoutes = () => {
if (!routes) {
return [];
}
return routes.data?.map(({ id, label, protocol, rules }) => {
return routes.data?.map((route) => {
const OuterTableCells = (
<>
<Hidden smDown>
<TableCell>{rules?.length}</TableCell>
<TableCell>{route.rules.length}</TableCell>
</Hidden>
<Hidden smDown>
<TableCell>{protocol?.toLocaleUpperCase()}</TableCell>{' '}
<TableCell>{route.protocol.toLocaleUpperCase()}</TableCell>{' '}
</Hidden>
<TableCell actionCell>
{/**
Expand All @@ -93,21 +105,21 @@ export const LoadBalancerRoutes = () => {
actionsList={[
{ onClick: () => null, title: 'Edit' },
{ onClick: () => null, title: 'Clone Route' },
{ onClick: () => null, title: 'Delete' },
{ onClick: () => onDeleteRoute(route), title: 'Delete' },
]}
ariaLabel={`Action Menu for Route ${label}`}
ariaLabel={`Action Menu for Route ${route.label}`}
/>
</TableCell>
</>
);

const InnerTable = <RulesTable rules={rules} />;
const InnerTable = <RulesTable rules={route.rules} />;

return {
InnerTable,
OuterTableCells,
id,
label,
id: route.id,
label: route.label,
};
});
};
Expand Down Expand Up @@ -192,6 +204,12 @@ export const LoadBalancerRoutes = () => {
page={pagination.page}
pageSize={pagination.pageSize}
/>
<DeleteRouteDialog
loadbalancerId={Number(loadbalancerId)}
onClose={() => setIsDeleteDialogOpen(false)}
open={isDeleteDialogOpen}
route={selectedRoute}
/>
Comment on lines +207 to +212
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried conditionally rendering like how we discussed in cafe, but the animation close breaks so I'm using our normal pattern

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually do wonder if there is actual benefit in conditionally rendering the dialog, since the element isn't even mounted unless open is true. It sounds to me like performance issues would be more relevant when mounting a Dialog with a big tree (maybe like the Linode Resize dialog for instance). The docs mention a keepMounted prop to that effect, but it sounds like the opposite of what we usually want to do. From what I could read, it's a case that should be supported by performance benchmarks to justify its usage (when it outside the scope of a micro optimisation).

</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React from 'react';

import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel';
import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog';
import { useLoadBalancerRouteDeleteMutation } from 'src/queries/aglb/routes';

import type { Route } from '@linode/api-v4';

interface Props {
loadbalancerId: number;
onClose: () => void;
open: boolean;
route: Route | undefined;
}

export const DeleteRouteDialog = (props: Props) => {
const { loadbalancerId, onClose, open, route } = props;

const { error, isLoading, mutateAsync } = useLoadBalancerRouteDeleteMutation(
loadbalancerId,
route?.id ?? -1
);

const onDelete = async () => {
await mutateAsync();
onClose();
};

return (
<ConfirmationDialog
actions={
<ActionsPanel
primaryButtonProps={{
label: 'Delete',
loading: isLoading,
onClick: onDelete,
}}
secondaryButtonProps={{
label: 'Cancel',
onClick: onClose,
}}
/>
}
error={error?.[0]?.reason}
onClose={onClose}
open={open}
title={`Delete Route ${route?.label}?`}
>
Are you sure you want to delete this route?
</ConfirmationDialog>
);
};
24 changes: 22 additions & 2 deletions packages/manager/src/queries/aglb/routes.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getLoadbalancerRoutes } from '@linode/api-v4';
import { useQuery } from 'react-query';
import { deleteLoadbalancerRoute, getLoadbalancerRoutes } from '@linode/api-v4';
import { useMutation, useQuery, useQueryClient } from 'react-query';

import { QUERY_KEY } from './loadbalancers';

Expand All @@ -22,3 +22,23 @@ export const useLoadBalancerRoutesQuery = (
{ keepPreviousData: true }
);
};

export const useLoadBalancerRouteDeleteMutation = (
loadbalancerId: number,
routeId: number
) => {
const queryClient = useQueryClient();
return useMutation<{}, APIError[]>(
() => deleteLoadbalancerRoute(loadbalancerId, routeId),
{
onSuccess() {
queryClient.invalidateQueries([
QUERY_KEY,
'loadbalancer',
loadbalancerId,
'routes',
]);
},
}
);
};