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-7169, M3-7193, M3-7211, M3-7255, M3-7258] - VPC UX feedback #9832

Merged
merged 13 commits into from
Oct 27, 2023
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Upcoming Features
---

VPC UX feedback ([#9832](https://github.com/linode/manager/pull/9832))
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ describe('VPC details page', () => {

// Confirm that user is redirected to VPC landing page.
cy.url().should('endWith', '/vpcs');
cy.findByText('Create a private and isolated network.');
cy.findByText('Create a private and isolated network');
});

/**
Expand Down
11 changes: 4 additions & 7 deletions packages/manager/cypress/e2e/core/vpc/vpc-landing-page.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { vpcFactory } from '@src/factories';
import { ui } from 'support/ui';
import { randomLabel, randomPhrase } from 'support/util/random';
import { chooseRegion, getRegionById } from 'support/util/regions';
import { VPC_LABEL } from 'src/features/VPCs/constants';

// TODO Remove feature flag mocks when feature flag is removed from codebase.
describe('VPC landing page', () => {
Expand Down Expand Up @@ -65,10 +66,8 @@ describe('VPC landing page', () => {
cy.wait(['@getFeatureFlags', '@getClientStream', '@getVPCs']);

// Confirm that empty state is shown and that each section is present.
cy.findByText('VPCs').should('be.visible');
cy.findByText('Create a private and isolated network.').should(
'be.visible'
);
cy.findByText(VPC_LABEL).should('be.visible');
cy.findByText('Create a private and isolated network').should('be.visible');
cy.findByText('Getting Started Guides').should('be.visible');
cy.findByText('Video Playlist').should('be.visible');

Expand Down Expand Up @@ -268,9 +267,7 @@ describe('VPC landing page', () => {
cy.wait(['@deleteVPC', '@getVPCs']);
ui.toast.assertMessage('VPC deleted successfully.');
cy.findByText(mockVPCs[1].label).should('not.exist');
cy.findByText('Create a private and isolated network.').should(
'be.visible'
);
cy.findByText('Create a private and isolated network').should('be.visible');
});

/*
Expand Down
7 changes: 3 additions & 4 deletions packages/manager/src/assets/icons/entityIcons/vpc.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Stack } from 'src/components/Stack';
import { useTheme } from '@mui/material/styles';
import useMediaQuery from '@mui/material/useMediaQuery';
import * as React from 'react';
Expand All @@ -9,10 +8,12 @@ import Select, { Item } from 'src/components/EnhancedSelect';
import { FormControlLabel } from 'src/components/FormControlLabel';
import { Link } from 'src/components/Link';
import { Paper } from 'src/components/Paper';
import { Stack } from 'src/components/Stack';
import { TextField } from 'src/components/TextField';
import { TooltipIcon } from 'src/components/TooltipIcon';
import { Typography } from 'src/components/Typography';
import { APP_ROOT } from 'src/constants';
import { VPC_AUTO_ASSIGN_IPV4_TOOLTIP } from 'src/features/VPCs/constants';
import { useAccountManagement } from 'src/hooks/useAccountManagement';
import { useFlags } from 'src/hooks/useFlags';
import { useRegionsQuery } from 'src/queries/regions';
Expand Down Expand Up @@ -255,10 +256,8 @@ export const VPCPanel = (props: VPCPanelProps) => {
Auto-assign a VPC IPv4 address for this Linode in the VPC
</Typography>
<TooltipIcon
text={
'A range of non-internet facing IP addresses used in an internal network.'
}
status="help"
text={VPC_AUTO_ASSIGN_IPV4_TOOLTIP}
/>
</Box>
}
Expand Down
21 changes: 11 additions & 10 deletions packages/manager/src/features/OneClickApps/oneClickApps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1137,11 +1137,11 @@ export const oneClickApps: OCA[] = [
{
href:
'https://www.linode.com/docs/products/tools/marketplace/guides/mcffmpegplugins/',
title: 'Deploy MainConcept FFmpeg Plugins through the Linode Marketplace',
title:
'Deploy MainConcept FFmpeg Plugins through the Linode Marketplace',
},
],
summary:
'MainConcept FFmpeg Plugins are advanced video encoding tools.',
summary: 'MainConcept FFmpeg Plugins are advanced video encoding tools.',
website: 'https://www.mainconcept.com/ffmpeg',
},
{
Expand All @@ -1162,8 +1162,7 @@ export const oneClickApps: OCA[] = [
title: 'Deploy MainConcept Live Encoder through the Linode Marketplace',
},
],
summary:
'MainConcept Live Encoder is a real time video encoding engine.',
summary: 'MainConcept Live Encoder is a real time video encoding engine.',
website: 'https://www.mainconcept.com/live-encoder',
},
{
Expand All @@ -1181,7 +1180,8 @@ export const oneClickApps: OCA[] = [
{
href:
'https://www.linode.com/docs/products/tools/marketplace/guides/mcp2avcultratranscoder/',
title: 'Deploy MainConcept P2 AVC Ultra Transcoder through the Linode Marketplace',
title:
'Deploy MainConcept P2 AVC Ultra Transcoder through the Linode Marketplace',
},
],
summary:
Expand All @@ -1203,7 +1203,8 @@ export const oneClickApps: OCA[] = [
{
href:
'https://www.linode.com/docs/products/tools/marketplace/guides/mcp2xavc/',
title: 'Deploy MainConcept XAVC Transcoder through the Linode Marketplace',
title:
'Deploy MainConcept XAVC Transcoder through the Linode Marketplace',
},
],
summary:
Expand All @@ -1225,7 +1226,8 @@ export const oneClickApps: OCA[] = [
{
href:
'https://www.linode.com/docs/products/tools/marketplace/guides/mcp2xdcam/',
title: 'Deploy MainConcept XDCAM Transcoder through the Linode Marketplace',
title:
'Deploy MainConcept XDCAM Transcoder through the Linode Marketplace',
},
],
summary:
Expand Down Expand Up @@ -2250,8 +2252,7 @@ export const oneClickApps: OCA[] = [
website: 'https://docs.splunk.com/Documentation/Splunk',
},
{
alt_description:
'A private by design messaging platform.',
alt_description: 'A private by design messaging platform.',
alt_name: 'Anonymous messaging platform.',
categories: ['Productivity'],
colors: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,20 @@ import { useFormik } from 'formik';
import * as React from 'react';

import { Autocomplete } from 'src/components/Autocomplete/Autocomplete';
import { Box } from 'src/components/Box';
import { Button } from 'src/components/Button/Button';
import { Checkbox } from 'src/components/Checkbox';
import { DownloadCSV } from 'src/components/DownloadCSV/DownloadCSV';
import { Drawer } from 'src/components/Drawer';
import { FormControlLabel } from 'src/components/FormControlLabel';
import { FormHelperText } from 'src/components/FormHelperText';
import { Link } from 'src/components/Link';
import { Notice } from 'src/components/Notice/Notice';
import { RemovableSelectionsList } from 'src/components/RemovableSelectionsList/RemovableSelectionsList';
import { TextField } from 'src/components/TextField';
import { TooltipIcon } from 'src/components/TooltipIcon';
import { Typography } from 'src/components/Typography';
import { VPC_AUTO_ASSIGN_IPV4_TOOLTIP } from 'src/features/VPCs/constants';
import { useFormattedDate } from 'src/hooks/useFormattedDate';
import { useUnassignLinode } from 'src/hooks/useUnassignLinode';
import { useAllLinodesQuery } from 'src/queries/linodes/linodes';
Expand Down Expand Up @@ -371,16 +376,25 @@ export const SubnetAssignLinodesDrawer = (
sx={{ marginBottom: '8px' }}
value={values.selectedLinode || null}
/>
<Checkbox
toolTipText={
'A range of non-internet facing IP used in an internal network'
}
checked={autoAssignIPv4}
disabled={userCannotAssignLinodes}
onChange={handleAutoAssignIPv4Change}
sx={{ marginLeft: `2px`, marginTop: `8px` }}
text={'Auto-assign a VPC IPv4 address for this Linode'}
/>
<Box alignItems="center" display="flex" flexDirection="row">
<FormControlLabel
hana-akamai marked this conversation as resolved.
Show resolved Hide resolved
control={
<Checkbox
checked={autoAssignIPv4}
onChange={handleAutoAssignIPv4Change}
/>
}
label={
<Typography>
Auto-assign a VPC IPv4 address for this Linode
</Typography>
}
data-testid="vpc-ipv4-checkbox"
disabled={userCannotAssignLinodes}
sx={{ marginRight: 0 }}
/>
<TooltipIcon status="help" text={VPC_AUTO_ASSIGN_IPV4_TOOLTIP} />
</Box>
{!autoAssignIPv4 && (
<TextField
onChange={(e) => {
Expand Down Expand Up @@ -450,22 +464,24 @@ export const SubnetAssignLinodesDrawer = (
preferredDataLabel="linodeConfigLabel"
selectionData={assignedLinodesAndConfigData}
/>
<DownloadCSV
sx={{
alignItems: 'flex-start',
display: 'flex',
gap: 1,
marginTop: 2,
textAlign: 'left',
}}
buttonType="styledLink"
csvRef={csvRef}
data={assignedLinodesAndConfigData}
filename={`linodes-assigned-${formattedDate}.csv`}
headers={SUBNET_LINODE_CSV_HEADERS}
onClick={downloadCSV}
text={'Download List of Assigned Linodes (.csv)'}
/>
{assignedLinodesAndConfigData.length > 0 && (
<DownloadCSV
sx={{
alignItems: 'flex-start',
display: 'flex',
gap: 1,
marginTop: 2,
textAlign: 'left',
}}
buttonType="styledLink"
csvRef={csvRef}
data={assignedLinodesAndConfigData}
filename={`linodes-assigned-${formattedDate}.csv`}
headers={SUBNET_LINODE_CSV_HEADERS}
onClick={downloadCSV}
text={'Download List of Assigned Linodes (.csv)'}
/>
)}
<StyledButtonBox>
<Button buttonType="outlined" onClick={handleOnClose}>
Done
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export const SubnetLinodeRow = (props: Props) => {
if (linodeLoading || !linode) {
return (
<TableRow>
<TableCell sx={{ marginLeft: 6 }}>
<TableCell colSpan={6}>
<CircleProgress mini />
</TableCell>
</TableRow>
Expand All @@ -69,7 +69,7 @@ export const SubnetLinodeRow = (props: Props) => {
if (linodeError) {
return (
<TableRow data-testid="subnet-linode-row-error">
<TableCell colSpan={5} style={{ paddingLeft: 48 }}>
<TableCell colSpan={5} style={{ paddingLeft: 24 }}>
<Box alignItems="center" display="flex">
<ErrorOutline
data-qa-error-icon
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,22 +284,24 @@ export const SubnetUnassignLinodesDrawer = React.memo(
onRemove={handleRemoveLinode}
selectionData={selectedLinodes}
/>
<DownloadCSV
sx={{
alignItems: 'flex-start',
display: 'flex',
gap: 1,
marginTop: 2,
textAlign: 'left',
}}
buttonType="styledLink"
csvRef={csvRef}
data={selectedLinodes}
filename={`linodes-unassigned-${formattedDate}.csv`}
headers={SUBNET_LINODE_CSV_HEADERS}
onClick={downloadCSV}
text={'Download List of Unassigned Linodes (.csv)'}
/>
{selectedLinodes.length > 0 && (
<DownloadCSV
sx={{
alignItems: 'flex-start',
display: 'flex',
gap: 1,
marginTop: 2,
textAlign: 'left',
}}
buttonType="styledLink"
csvRef={csvRef}
data={selectedLinodes}
filename={`linodes-unassigned-${formattedDate}.csv`}
headers={SUBNET_LINODE_CSV_HEADERS}
onClick={downloadCSV}
text={'Download List of Unassigned Linodes (.csv)'}
/>
)}
<ActionsPanel
primaryButtonProps={{
'data-testid': 'unassign-submit-button',
Expand Down
23 changes: 17 additions & 6 deletions packages/manager/src/features/VPCs/VPCDetail/VPCDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { DocumentTitleSegment } from 'src/components/DocumentTitle';
import { EntityHeader } from 'src/components/EntityHeader/EntityHeader';
import { ErrorState } from 'src/components/ErrorState/ErrorState';
import { LandingHeader } from 'src/components/LandingHeader';
import { VPC_LABEL } from 'src/features/VPCs/constants';
import { useRegionsQuery } from 'src/queries/regions';
import { useVPCQuery } from 'src/queries/vpcs';
import { truncate } from 'src/utilities/truncate';
Expand Down Expand Up @@ -99,7 +100,7 @@ const VPCDetail = () => {
breadcrumbProps={{
crumbOverrides: [
{
label: 'Virtual Private Cloud (VPC)',
label: VPC_LABEL,
position: 1,
},
],
Expand Down Expand Up @@ -132,15 +133,21 @@ const VPCDetail = () => {
</Box>
</EntityHeader>
<StyledPaper>
<StyledSummaryBox display="flex" flex={1} data-qa-vpc-summary>
<StyledSummaryBox data-qa-vpc-summary display="flex" flex={1}>
{summaryData.map((col) => {
return (
<Box key={col[0].label} paddingRight={6}>
<StyledSummaryTextTypography>
<strong>{col[0].label}</strong> {col[0].value}
<span style={{ fontFamily: theme.font.bold }}>
{col[0].label}
</span>{' '}
{col[0].value}
</StyledSummaryTextTypography>
<StyledSummaryTextTypography>
<strong>{col[1].label}</strong> {col[1].value}
<span style={{ fontFamily: theme.font.bold }}>
{col[1].label}
</span>{' '}
{col[1].value}
</StyledSummaryTextTypography>
</Box>
);
Expand All @@ -149,7 +156,9 @@ const VPCDetail = () => {
{vpc.description.length > 0 && (
<StyledDescriptionBox display="flex" flex={1}>
<Typography>
<strong style={{ paddingRight: 8 }}>Description</strong>{' '}
<span style={{ fontFamily: theme.font.bold, paddingRight: 8 }}>
Description
</span>{' '}
</Typography>
<Typography>
{description}{' '}
Expand Down Expand Up @@ -184,7 +193,9 @@ const VPCDetail = () => {
})}
padding={`${theme.spacing(2)} ${theme.spacing()}`}
>
<Typography variant="h2">Subnets ({vpc.subnets.length})</Typography>
<Typography sx={{ fontSize: '1rem' }} variant="h2">
Subnets ({vpc.subnets.length})
</Typography>
</Box>
{numLinodes > 0 && (
<DismissibleBanner
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import {
gettingStartedGuides,
youtubeLinkData,
} from 'src/features/Linodes/LinodesLanding/LinodesLandingEmptyStateData';
import { headers, linkAnalyticsEvent } from './VPCEmptyStateData';
import { sendEvent } from 'src/utilities/analytics';

import { headers, linkAnalyticsEvent } from './VPCEmptyStateData';

export const VPCEmptyState = () => {
const { push } = useHistory();

Expand Down
Loading