Skip to content

Commit

Permalink
upcoming: [M3-7296] - Create Load Balancer Summary page (#10018)
Browse files Browse the repository at this point in the history
* Create EditLoadBalancerLabel

* Added changeset: Create Load Balancer Summary page.

* Create EditLoadBalancerRegions

* rename EditLoadBalancerLabel

* Create LoadBalancerSummary

* Create LoadBalancerCreateFormWrapper

* Code cleanup

* Billing Summary sections

* EditConfigurationDetails

* EditRoutes

* EditLoadBalancerConfigurations

* Update LoadBalancerSummary.styles.ts

* Disabel Review button incase of validation errors

* Code cleanup

* test coverage - EditRouteDrawer

* Update EditRouteDrawer.test.tsx

* test coverage - ConfigurationAccordionHeader

* test coverage - RouteAccordionHeader

* test coverage - ConfigurationAccordion

* Update with comments

* Update packages/manager/.changeset/pr-10018-upcoming-features-1703185915854.md

Co-authored-by: Mariah Jacobs <114685994+mjac0bs@users.noreply.github.com>

* Add Todo item to update links

* Update LoadBalancerSummary.tsx

* PR feedback.

* Update packages/manager/src/features/LoadBalancers/LoadBalancerCreate/LoadBalancerSummary/LoadBalancerSummary.tsx

Co-authored-by: Mariah Jacobs <114685994+mjac0bs@users.noreply.github.com>

* Revert "PR feedback."

This reverts commit 5cb1279.

* PR - Feedback - Remove background color, and align regions title

* Reduce spacing around summary section

* PR -feedback - control opening accordion upon clicking edit button

* PR - feedback @bnussman-akamai @hana-linode

* Copy updates

---------

Co-authored-by: Mariah Jacobs <114685994+mjac0bs@users.noreply.github.com>
  • Loading branch information
cpathipa and mjac0bs authored Jan 29, 2024
1 parent 61f95ba commit e181795
Show file tree
Hide file tree
Showing 42 changed files with 1,320 additions and 109 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Upcoming Features
---

Create Load Balancer Summary page ([#10018](https://github.com/linode/manager/pull/10018))
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import React from 'react';
import { renderWithThemeAndFormik } from 'src/utilities/testHelpers';

import { AddRouteDrawer } from './AddRouteDrawer';
import { initialValues } from './LoadBalancerCreate';
import { initialValues } from './LoadBalancerCreateFormWrapper';

describe('AddRouteDrawer (AGLB full create flow)', () => {
it('renders a title', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { getNextLabel } from 'src/utilities/stringUtils';

import { ROUTE_COPY } from '../LoadBalancerDetail/Routes/constants';
import { getRouteProtocolFromConfigurationProtocol } from '../LoadBalancerDetail/Routes/utils';
import { LoadBalancerCreateFormData } from './LoadBalancerCreate';
import { LoadBalancerCreateFormData } from './LoadBalancerCreateFormWrapper';

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
} from '../LoadBalancerDetail/Configurations/constants';

import type { Handlers } from './LoadBalancerConfigurations';
import type { LoadBalancerCreateFormData } from './LoadBalancerCreate';
import type { LoadBalancerCreateFormData } from './LoadBalancerCreateFormWrapper';

interface Props {
handlers: Handlers;
Expand Down Expand Up @@ -102,11 +102,7 @@ export const ConfigurationDetails = ({ index }: Props) => {
</Stack>
</Stack>
<TextField
errorText={
touched.configurations?.[index]?.label
? getIn(errors, `configurations[${index}].label`)
: ''
}
errorText={getIn(errors, `configurations[${index}].label`) ?? ''}
inputId={`configuration-${index}-label`}
label="Configuration Label"
labelTooltipText={CONFIGURATION_COPY.configuration}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { EditRouteDrawer } from './EditRouteDrawer';
import {
LoadBalancerCreateFormData,
initialValues,
} from './LoadBalancerCreate';
} from './LoadBalancerCreateFormWrapper';

describe('EditRouteDrawer (AGLB full create flow)', () => {
it('renders a title', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel';
import { Drawer } from 'src/components/Drawer';
import { TextField } from 'src/components/TextField';

import { LoadBalancerCreateFormData } from './LoadBalancerCreate';
import { LoadBalancerCreateFormData } from './LoadBalancerCreateFormWrapper';

interface Props {
configurationIndex: number;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,33 @@
import { useFormikContext, FieldArray } from 'formik';
import { FieldArray, useFormikContext } from 'formik';
import * as React from 'react';
import { useHistory } from 'react-router-dom';

import { Box } from 'src/components/Box';
import { Button } from 'src/components/Button/Button';
import { initialValues } from './LoadBalancerCreate';

import { initialValues } from './LoadBalancerCreateFormWrapper';

import type { LoadBalancerCreateFormData } from './LoadBalancerCreateFormWrapper';

export const LoadBalancerActionPanel = () => {
const { submitForm } = useFormikContext();
const history = useHistory<{
contactDrawerOpen?: boolean;
focusEmail?: boolean;
}>();

const {
errors,
validateForm,
} = useFormikContext<LoadBalancerCreateFormData>();

const handleButtonClick = async () => {
const errors = await validateForm();
if (Object.keys(errors).length === 0) {
// No errors, proceed with the action
history.push('/loadbalancers/create/summary');
}
};

return (
<Box
columnGap={1}
Expand All @@ -16,7 +37,6 @@ export const LoadBalancerActionPanel = () => {
rowGap={3}
>
<FieldArray
name="configurations"
render={({ push }) => (
<Button
buttonType="outlined"
Expand All @@ -25,12 +45,14 @@ export const LoadBalancerActionPanel = () => {
Add Another Configuration
</Button>
)}
name="configurations"
/>
<Button
buttonType="primary"
onClick={submitForm}
disabled={Object.keys(errors)?.length > 0}
onClick={handleButtonClick}
sx={{ marginLeft: 'auto' }}
type="submit"
type="button"
>
Review Load Balancer
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { LoadBalancerConfiguration } from './LoadBalancerConfiguration';
import {
LoadBalancerCreateFormData,
initialValues,
} from './LoadBalancerCreate';
} from './LoadBalancerCreateFormWrapper';

import type { Handlers } from './LoadBalancerConfigurations';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Handlers } from './LoadBalancerConfigurations';
import { Routes } from './Routes';
import { ServiceTargets } from './ServiceTargets';

import type { LoadBalancerCreateFormData } from './LoadBalancerCreate';
import type { LoadBalancerCreateFormData } from './LoadBalancerCreateFormWrapper';

interface Props {
handlers: Handlers;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { CreateLoadBalancerSchema } from '@linode/validation';
import Stack from '@mui/material/Stack';
import { Formik, Form as FormikForm } from 'formik';
import * as React from 'react';
import React from 'react';

import { DocumentTitleSegment } from 'src/components/DocumentTitle/DocumentTitle';
import { LandingHeader } from 'src/components/LandingHeader';
Expand All @@ -12,39 +10,7 @@ import { LoadBalancerConfigurations } from './LoadBalancerConfigurations';
import { LoadBalancerLabel } from './LoadBalancerLabel';
import { LoadBalancerRegions } from './LoadBalancerRegions';

import type {
ConfigurationPayload,
CreateLoadbalancerPayload,
ServiceTargetPayload,
} from '@linode/api-v4';

export interface LoadBalancerCreateFormData
extends Omit<CreateLoadbalancerPayload, 'configurations'> {
configurations: (ConfigurationPayload & {
service_targets: ServiceTargetPayload[];
})[];
}

export const initialValues: LoadBalancerCreateFormData = {
configurations: [
{
certificates: [],
label: '',
port: 443,
protocol: 'https',
routes: [],
service_targets: [],
},
],
label: '',
regions: [],
};

export const LoadBalancerCreate = () => {
const handleSubmit = (values: LoadBalancerCreateFormData) => {
// console.log('Submitted values:', values);
};

return (
<>
<DocumentTitleSegment segment="Create a Load Balancer" />
Expand All @@ -61,20 +27,13 @@ export const LoadBalancerCreate = () => {
betaFeedbackLink={AGLB_FEEDBACK_FORM_URL}
title="Create"
/>
<Formik
initialValues={initialValues}
onSubmit={handleSubmit}
validationSchema={CreateLoadBalancerSchema}
>
<FormikForm>
<Stack spacing={3}>
<LoadBalancerLabel />
<LoadBalancerRegions />
<LoadBalancerConfigurations />
<LoadBalancerActionPanel />
</Stack>
</FormikForm>
</Formik>

<Stack spacing={3}>
<LoadBalancerLabel />
<LoadBalancerRegions />
<LoadBalancerConfigurations />
<LoadBalancerActionPanel />
</Stack>
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { CreateLoadBalancerSchema } from '@linode/validation';
import { Formik } from 'formik';
import React from 'react';
import { Route, Switch } from 'react-router-dom';

import { useFlags } from 'src/hooks/useFlags';

import type {
ConfigurationPayload,
CreateLoadbalancerPayload,
ServiceTargetPayload,
} from '@linode/api-v4';

const LoadBalancerCreate = React.lazy(() =>
import('./LoadBalancerCreate').then((module) => ({
default: module.LoadBalancerCreate,
}))
);

const LoadBalancerBasicCreate = React.lazy(() =>
import('./LoadBalancerBasicCreate').then((module) => ({
default: module.LoadBalancerBasicCreate,
}))
);

const LoadBalancerSummary = React.lazy(() =>
import('./LoadBalancerSummary/LoadBalancerSummary').then((module) => ({
default: module.LoadBalancerSummary,
}))
);

export interface LoadBalancerCreateFormData
extends Omit<CreateLoadbalancerPayload, 'configurations'> {
configurations: (ConfigurationPayload & {
service_targets: ServiceTargetPayload[];
})[];
}

export const initialValues: LoadBalancerCreateFormData = {
configurations: [
{
certificates: [],
label: '',
port: 443,
protocol: 'https',
routes: [],
service_targets: [],
},
],
label: '',
regions: [],
};

export const LoadBalancerCreateFormWrapper = () => {
const flags = useFlags();

const handleSubmit = (values: LoadBalancerCreateFormData) => {
// Handle form submission
};

return (
<Formik
initialValues={initialValues}
onSubmit={handleSubmit}
validationSchema={CreateLoadBalancerSchema}
>
{() => (
<Switch>
<Route
render={() =>
flags.aglbFullCreateFlow ? (
<LoadBalancerCreate />
) : (
<LoadBalancerBasicCreate />
)
}
exact
path="/loadbalancers/create"
/>
{flags.aglbFullCreateFlow && (
<Route
path="/loadbalancers/create/summary"
render={() => <LoadBalancerSummary />}
/>
)}
</Switch>
)}
</Formik>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { renderWithThemeAndFormik } from 'src/utilities/testHelpers';

import { LoadBalancerLabel } from './LoadBalancerLabel';

import type { LoadBalancerCreateFormData } from './LoadBalancerCreate';
import type { LoadBalancerCreateFormData } from './LoadBalancerCreateFormWrapper';

const loadBalancerLabelValue = 'Test Label';
const loadBalancerTestId = 'textfield-input';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export const LoadBalancerLabel = () => {
errors,
handleBlur,
handleChange,
touched,
values,
} = useFormikContext<CreateLoadbalancerPayload>();

Expand All @@ -25,7 +24,7 @@ export const LoadBalancerLabel = () => {
>
<TextField
disabled={false}
errorText={touched.label && errors.label ? errors.label : undefined} // Display errors if the field is touched and there's an error
errorText={errors.label ? errors.label : undefined} // Display errors if the field has an error
label="Load Balancer Label"
name="label"
noMarginTop
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import Stack from '@mui/material/Stack';
import { Theme } from '@mui/material/styles';
import { SxProps } from '@mui/system';
import * as React from 'react';

import { BetaChip } from 'src/components/BetaChip/BetaChip';
Expand All @@ -7,22 +9,23 @@ import { Typography } from 'src/components/Typography';

import { LoadBalancerRegions as Regions } from '../LoadBalancerDetail/LoadBalancerRegions';

export const LoadBalancerRegions = () => {
interface Props {
sx?: SxProps<Theme>;
}

export const LoadBalancerRegions = ({ sx }: Props) => {
return (
<Paper>
<Paper sx={sx}>
<Stack spacing={2}>
<Typography variant="h2">Regions</Typography>
<Stack spacing={1}>
<Typography>
Where this Load Balancer instance will be deployed.
</Typography>
<Typography>
<BetaChip
component="span"
sx={{ marginLeft: '0 !important', marginRight: '8px !important' }}
/>
Load Balancers will be automatically provisioned in these 5 Regions.
No charges with be incurred.
No charges will be incurred.
</Typography>
</Stack>
<Regions />
Expand Down
Loading

0 comments on commit e181795

Please sign in to comment.