Skip to content

Commit 258b1d5

Browse files
jaalah-akamaijaalahcoliu-akamai
authored
revert: [M3-9080] - Tanstack routing for VPCs (#11991)
* revert: [M3-9080] - Tanstack routing for VPCs * fix issues found --------- Co-authored-by: Jaalah Ramos <[email protected]> Co-authored-by: Connie Liu <[email protected]>
1 parent dbca818 commit 258b1d5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+856
-305
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@linode/manager": Fixed
3+
---
4+
5+
Pagination for subnets in VPC Subnet table ([#11906](https://github.com/linode/manager/pull/11906))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@linode/manager": Fixed
3+
---
4+
5+
IP incrementation in Subnet Create drawer ([#11906](https://github.com/linode/manager/pull/11906))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@linode/manager": Tech Stories
3+
---
4+
5+
VPC rerouting (TanStack) ([#11906](https://github.com/linode/manager/pull/11906))

packages/manager/.eslintrc.cjs

+1
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ module.exports = {
151151
'src/features/PlacementGroups/**/*',
152152
'src/features/StackScripts/**/*',
153153
'src/features/Volumes/**/*',
154+
'src/features/VPCs/**/*',
154155
],
155156
rules: {
156157
'no-restricted-imports': [

packages/manager/cypress/e2e/core/vpc/vpc-details-page.spec.ts

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
mockDeleteSubnet,
1212
mockDeleteVPC,
1313
mockEditSubnet,
14+
mockGetSubnet,
1415
mockGetSubnets,
1516
mockGetVPC,
1617
mockGetVPCs,
@@ -177,6 +178,7 @@ describe('VPC details page', () => {
177178
cy.findByText(mockVPC.label).should('be.visible');
178179
cy.findByText('Subnets (1)').should('be.visible');
179180
cy.findByText(mockSubnet.label).should('be.visible');
181+
mockGetSubnet(mockVPC.id, mockSubnet.id, mockSubnet);
180182

181183
// edit a subnet
182184
const mockEditedSubnet = subnetFactory.build({
@@ -201,6 +203,7 @@ describe('VPC details page', () => {
201203
.should('be.visible')
202204
.click();
203205
ui.actionMenuItem.findByTitle('Edit').should('be.visible').click();
206+
mockGetSubnet(mockVPC.id, mockEditedSubnet.id, mockEditedSubnet);
204207

205208
ui.drawer
206209
.findByTitle('Edit Subnet')

packages/manager/cypress/e2e/core/vpc/vpc-landing-page.spec.ts

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
MOCK_DELETE_VPC_ERROR,
44
mockDeleteVPC,
55
mockDeleteVPCError,
6+
mockGetVPC,
67
mockGetVPCs,
78
mockUpdateVPC,
89
} from 'support/intercepts/vpc';
@@ -100,6 +101,7 @@ describe('VPC landing page', () => {
100101
};
101102

102103
mockGetVPCs([mockVPCs[1]]).as('getVPCs');
104+
mockGetVPC(mockVPCs[1]).as('getVPC');
103105
mockUpdateVPC(mockVPCs[1].id, mockUpdatedVPC).as('updateVPC');
104106

105107
cy.visitWithLogin('/vpcs');
@@ -165,6 +167,7 @@ describe('VPC landing page', () => {
165167

166168
// Delete VPCs Flow
167169
mockGetVPCs(mockVPCs).as('getVPCs');
170+
mockGetVPC(mockVPCs[0]).as('getVPC');
168171
mockDeleteVPC(mockVPCs[0].id).as('deleteVPC');
169172

170173
cy.visitWithLogin('/vpcs');
@@ -254,6 +257,7 @@ describe('VPC landing page', () => {
254257
];
255258

256259
mockGetVPCs(mockVPCs).as('getVPCs');
260+
mockGetVPC(mockVPCs[0]).as('getVPC');
257261
mockDeleteVPCError(mockVPCs[0].id).as('deleteVPCError');
258262

259263
cy.visitWithLogin('/vpcs');
@@ -302,6 +306,7 @@ describe('VPC landing page', () => {
302306
.click();
303307
});
304308

309+
mockGetVPC(mockVPCs[1]).as('getVPC');
305310
cy.findByText(mockVPCs[1].label)
306311
.should('be.visible')
307312
.closest('tr')

packages/manager/cypress/e2e/core/vpc/vpc-linodes-update.spec.ts

+5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
import { mockGetLinodes } from 'support/intercepts/linodes';
2020
import {
2121
mockCreateSubnet,
22+
mockGetSubnet,
2223
mockGetSubnets,
2324
mockGetVPC,
2425
mockGetVPCs,
@@ -110,6 +111,8 @@ describe('VPC assign/unassign flows', () => {
110111

111112
cy.wait(['@createSubnet', '@getVPC', '@getSubnets', '@getLinodes']);
112113

114+
mockGetSubnet(mockVPC.id, mockSubnet.id, mockSubnet);
115+
113116
// confirm that newly created subnet should now appear on VPC's detail page
114117
cy.findByText(mockVPC.label).should('be.visible');
115118
cy.findByText('Subnets (1)').should('be.visible');
@@ -231,6 +234,8 @@ describe('VPC assign/unassign flows', () => {
231234
cy.findByText('Subnets (1)').should('be.visible');
232235
cy.findByText(mockSubnet.label).should('be.visible');
233236

237+
mockGetSubnet(mockVPC.id, mockSubnet.id, mockSubnet);
238+
234239
// unassign a linode to the subnet
235240
ui.actionMenu
236241
.findByTitle(`Action menu for Subnet ${mockSubnet.label}`)

packages/manager/cypress/support/intercepts/vpc.ts

+21
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,27 @@ export const mockGetSubnets = (
132132
);
133133
};
134134

135+
/**
136+
* Intercepts GET request to get a specific subnet and mocks response.
137+
*
138+
* @param vpcId - ID of VPC for which to mock response.
139+
* @param subnetId - ID of subnet for which to mock response.
140+
* @param subnet - Subnet for which to mock response
141+
*
142+
* @returns Cypress chainable.
143+
*/
144+
export const mockGetSubnet = (
145+
vpcId: number,
146+
subnetId: number,
147+
subnet: Subnet
148+
): Cypress.Chainable<null> => {
149+
return cy.intercept(
150+
'GET',
151+
apiMatcher(`vpcs/${vpcId}/subnets/${subnetId}`),
152+
subnet
153+
);
154+
};
155+
135156
/**
136157
* Intercepts DELETE request to delete a subnet of a VPC and mocks response
137158
*

packages/manager/src/MainContent.tsx

+6-8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
import {
2+
useAccountSettings,
3+
useMutatePreferences,
4+
usePreferences,
5+
useProfile,
6+
} from '@linode/queries';
17
import { Box } from '@linode/ui';
28
import { useMediaQuery } from '@mui/material';
39
import Grid from '@mui/material/Grid2';
@@ -24,12 +30,6 @@ import {
2430
useNotificationContext,
2531
} from 'src/features/NotificationCenter/NotificationCenterContext';
2632
import { TopMenu } from 'src/features/TopMenu/TopMenu';
27-
import {
28-
useMutatePreferences,
29-
usePreferences,
30-
useAccountSettings,
31-
useProfile,
32-
} from '@linode/queries';
3333

3434
import { useIsPageScrollable } from './components/PrimaryNav/utils';
3535
import { ENABLE_MAINTENANCE_MODE } from './constants';
@@ -156,7 +156,6 @@ const AccountActivationLanding = React.lazy(
156156
() => import('src/components/AccountActivation/AccountActivationLanding')
157157
);
158158
const Databases = React.lazy(() => import('src/features/Databases'));
159-
const VPC = React.lazy(() => import('src/features/VPCs'));
160159

161160
const CloudPulseMetrics = React.lazy(() =>
162161
import('src/features/CloudPulse/Dashboard/CloudPulseDashboardLanding').then(
@@ -377,7 +376,6 @@ export const MainContent = () => {
377376
{isDatabasesEnabled && (
378377
<Route component={Databases} path="/databases" />
379378
)}
380-
<Route component={VPC} path="/vpcs" />
381379
{isACLPEnabled && (
382380
<Route
383381
component={CloudPulseMetrics}

packages/manager/src/features/Linodes/PowerActionsDialogOrDrawer.tsx

+11-9
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
1+
import {
2+
useAllLinodeConfigsQuery,
3+
useBootLinodeMutation,
4+
useRebootLinodeMutation,
5+
useShutdownLinodeMutation,
6+
} from '@linode/queries';
17
import { ActionsPanel, Autocomplete, Notice, Typography } from '@linode/ui';
28
import { useTheme } from '@mui/material/styles';
39
import * as React from 'react';
410

511
import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog';
612
import { Link } from 'src/components/Link';
713
import { useEventsPollingActions } from 'src/queries/events/events';
8-
import {
9-
useAllLinodeConfigsQuery,
10-
useBootLinodeMutation,
11-
useRebootLinodeMutation,
12-
useShutdownLinodeMutation,
13-
} from '@linode/queries';
1414

1515
import type { Config } from '@linode/api-v4/lib/linodes';
1616

1717
export type Action = 'Power Off' | 'Power On' | 'Reboot';
1818

1919
interface Props {
2020
action: Action;
21+
isFetching?: boolean;
2122
isOpen: boolean;
2223
linodeId: number | undefined;
2324
linodeLabel?: string | undefined;
@@ -36,7 +37,7 @@ export const selectDefaultConfig = (configs?: Config[]) =>
3637
configs?.length === 1 ? configs[0].id : undefined;
3738

3839
export const PowerActionsDialog = (props: Props) => {
39-
const { action, isOpen, linodeId, linodeLabel, onClose } = props;
40+
const { action, isFetching, isOpen, linodeId, linodeLabel, onClose } = props;
4041
const theme = useTheme();
4142

4243
const {
@@ -139,6 +140,7 @@ export const PowerActionsDialog = (props: Props) => {
139140
/>
140141
}
141142
error={error?.[0].reason}
143+
isFetching={isFetching}
142144
onClose={handleOnClose}
143145
open={isOpen}
144146
title={`${action} Linode ${linodeLabel ?? ''}?`}
@@ -170,15 +172,15 @@ export const PowerActionsDialog = (props: Props) => {
170172
autoHighlight
171173
disablePortal={false}
172174
errorText={configsError?.[0].reason}
175+
helperText="If no value is selected, the last booted config will be used."
173176
label="Config"
174177
loading={configsLoading}
175178
onChange={(_, option) => setSelectConfigID(option?.value ?? null)}
176179
options={configOptions}
177-
helperText="If no value is selected, the last booted config will be used."
178180
/>
179181
)}
180182
{props.action === 'Power Off' && (
181-
<Notice variant="warning" spacingBottom={0}>
183+
<Notice spacingBottom={0} variant="warning">
182184
<Typography>
183185
<strong>Note: </strong>Powered down Linodes will still accrue
184186
charges. See the&nbsp;

packages/manager/src/features/VPCs/VPCCreate/FormComponents/SubnetContent.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Notice } from '@linode/ui';
22
import { getQueryParamsFromQueryString } from '@linode/utilities';
33
import * as React from 'react';
44
import { useFormContext } from 'react-hook-form';
5+
// eslint-disable-next-line no-restricted-imports
56
import { useLocation } from 'react-router-dom';
67

78
import { Link } from 'src/components/Link';

packages/manager/src/features/VPCs/VPCCreate/FormComponents/VPCTopSectionContent.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { TextField } from '@linode/ui';
33
import { getQueryParamsFromQueryString } from '@linode/utilities';
44
import * as React from 'react';
55
import { Controller, useFormContext } from 'react-hook-form';
6+
// eslint-disable-next-line no-restricted-imports
67
import { useLocation } from 'react-router-dom';
78

89
import { Link } from 'src/components/Link';

packages/manager/src/features/VPCs/VPCCreate/SubnetNode.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ export const SubnetNode = (props: Props) => {
4343
<Grid key={idx} sx={{ maxWidth: 460 }}>
4444
<Grid container direction="row" spacing={2}>
4545
<Grid
46-
sx={{ ...(!showRemoveButton && { width: '100%' }), flexGrow: 1 }}
4746
size={showRemoveButton ? 11 : 12}
47+
sx={{ ...(!showRemoveButton && { width: '100%' }), flexGrow: 1 }}
4848
>
4949
<Controller
5050
render={({ field, fieldState }) => (

packages/manager/src/features/VPCs/VPCCreate/VPCCreate.tsx

-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { ActionsPanel, Notice, Paper } from '@linode/ui';
22
import Grid from '@mui/material/Grid2';
33
import { styled } from '@mui/material/styles';
4-
import { createLazyRoute } from '@tanstack/react-router';
54
import * as React from 'react';
65
import { FormProvider } from 'react-hook-form';
76

@@ -78,10 +77,6 @@ const VPCCreate = () => {
7877
);
7978
};
8079

81-
export const vpcCreateLazyRoute = createLazyRoute('/vpcs/create')({
82-
component: VPCCreate,
83-
});
84-
8580
const StyledActionsPanel = styled(ActionsPanel, {
8681
label: 'StyledActionsPanel',
8782
})(({ theme }) => ({

packages/manager/src/features/VPCs/VPCDetail/SubnetAssignLinodesDrawer.test.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import type { Subnet } from '@linode/api-v4';
1313
beforeAll(() => mockMatchMedia());
1414

1515
const props = {
16+
isFetching: false,
1617
onClose: vi.fn(),
1718
open: true,
1819
subnet: {

packages/manager/src/features/VPCs/VPCDetail/SubnetAssignLinodesDrawer.tsx

+14-7
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import type { ExtendedIP } from 'src/utilities/ipUtils';
5757
// @TODO VPC: if all subnet action menu item related components use (most of) this as their props, might be worth
5858
// putting this in a common file and naming it something like SubnetActionMenuItemProps or something
5959
interface SubnetAssignLinodesDrawerProps {
60+
isFetching: boolean;
6061
onClose: () => void;
6162
open: boolean;
6263
subnet?: Subnet;
@@ -73,7 +74,7 @@ interface LinodeAndConfigData extends Linode {
7374
export const SubnetAssignLinodesDrawer = (
7475
props: SubnetAssignLinodesDrawerProps
7576
) => {
76-
const { onClose, open, subnet, vpcId, vpcRegion } = props;
77+
const { isFetching, onClose, open, subnet, vpcId, vpcRegion } = props;
7778
const {
7879
invalidateQueries,
7980
setUnassignLinodesErrors,
@@ -413,6 +414,7 @@ export const SubnetAssignLinodesDrawer = (
413414
subnet?.ipv4 ?? subnet?.ipv6
414415
})`}
415416
NotFoundComponent={NotFound}
417+
isFetching={isFetching}
416418
onClose={handleOnClose}
417419
open={open}
418420
>
@@ -444,12 +446,17 @@ export const SubnetAssignLinodesDrawer = (
444446
// We only want to be able to assign linodes that were not already assigned to this subnet
445447
options={linodeOptionsToAssign}
446448
placeholder="Select Linode or type to search"
447-
sx={{ marginBottom: '8px' }}
449+
sx={(theme) => ({ marginBottom: theme.spacingFunction(8) })}
448450
value={values.selectedLinode?.id || null}
449451
/>
450452
{values.selectedLinode?.id && (
451453
<>
452-
<Box alignItems="center" display="flex" flexDirection="row">
454+
<Box
455+
alignItems="center"
456+
display="flex"
457+
flexDirection="row"
458+
sx={(theme) => ({ marginLeft: theme.spacingFunction(2) })}
459+
>
453460
<FormControlLabel
454461
control={
455462
<Checkbox
@@ -477,7 +484,7 @@ export const SubnetAssignLinodesDrawer = (
477484
disabled={userCannotAssignLinodes}
478485
errorText={assignLinodesErrors['ipv4.vpc']}
479486
label="VPC IPv4"
480-
sx={{ marginBottom: '8px' }}
487+
sx={(theme) => ({ marginBottom: theme.spacingFunction(8) })}
481488
value={values.chosenIP}
482489
/>
483490
)}
@@ -511,11 +518,11 @@ export const SubnetAssignLinodesDrawer = (
511518
linodeConfigs.length === 1) && (
512519
<AssignIPRanges
513520
sx={{
514-
marginBottom: theme.spacing(),
521+
marginBottom: theme.spacingFunction(8),
515522
marginTop:
516523
linodeConfigs.length > 1
517-
? theme.spacing(2)
518-
: theme.spacing(),
524+
? theme.spacingFunction(16)
525+
: theme.spacingFunction(8),
519526
}}
520527
handleIPRangeChange={handleIPRangeChange}
521528
ipRanges={values.ipRanges}

packages/manager/src/features/VPCs/VPCDetail/SubnetCreateDrawer.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,12 @@ export const SubnetCreateDrawer = (props: Props) => {
6161
setError,
6262
watch,
6363
} = useForm<CreateSubnetPayload>({
64-
defaultValues: {
64+
mode: 'onBlur',
65+
resolver: yupResolver(createSubnetSchemaIPv4),
66+
values: {
6567
ipv4: recommendedIPv4,
6668
label: '',
6769
},
68-
mode: 'onBlur',
69-
resolver: yupResolver(createSubnetSchemaIPv4),
7070
});
7171

7272
const ipv4 = watch('ipv4');

packages/manager/src/features/VPCs/VPCDetail/SubnetDeleteDialog.test.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { SubnetDeleteDialog } from './SubnetDeleteDialog';
88
import type { ManagerPreferences } from '@linode/utilities';
99

1010
const props = {
11+
isFetching: false,
1112
onClose: vi.fn(),
1213
open: true,
1314
subnet: subnetFactory.build({ label: 'some subnet' }),

0 commit comments

Comments
 (0)