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

fix: [M3-8533] - Broken firewall rules table #11109

Closed
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
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-11109-fixed-1729070494828.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Fixed
---

Broken firewall rules table ([#11109](https://github.com/linode/manager/pull/11109))
pmakode-akamai marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,14 @@ export const sxBox = {
width: '100%',
};

export const sxItemSpacing = {
padding: `0 8px`,
};

export const StyledFirewallRuleBox = styled(Box, {
label: 'StyledFirewallRuleBox',
shouldForwardProp: omittedProps(['originalIndex', 'ruleId']),
})<StyledFirewallRuleBoxProps>(
({ disabled, originalIndex, ruleId, status, theme }) => ({
borderBottom: `1px solid ${theme.borderColors.borderTable}`,
borderLeft: `1px solid ${theme.borderColors.borderTable}`,
borderRight: `1px solid ${theme.borderColors.borderTable}`,
color: theme.textColors.tableStatic,
fontSize: '0.875rem',
margin: 0,
Expand All @@ -60,13 +58,42 @@ export const StyledFirewallRuleBox = styled(Box, {
export const StyledInnerBox = styled(Box, { label: 'StyledInnerBox' })(
({ theme }) => ({
backgroundColor: theme.bg.tableHeader,
color: theme.textColors.tableHeader,
fontFamily: theme.font.bold,
fontSize: '.875rem',
height: '46px',
})
);

export const StyledHeaderItemBox = styled(Box, {
label: 'StyledHeaderItemBox',
})(({ theme }) => ({
'&:last-child': {
borderRight: `1px solid ${theme.borderColors.borderTable}`,
paddingRight: '0px',
},
alignContent: 'center',
borderBottom: `1px solid ${theme.borderColors.borderTable}`,
borderLeft: `1px solid ${theme.borderColors.borderTable}`,
borderTop: `1px solid ${theme.borderColors.borderTable}`,
height: '46px',
lineHeight: '12px',
padding: '10px 15px',
}));

export const StyledCellItemBox = styled(Box, {
label: 'StyledCellItemBox',
})(({ theme }) => ({
'&:not(:last-child)': {
padding: '0px 15px',
},
alignContent: 'center',
minHeight: '40px',
[theme.breakpoints.down('sm')]: {
'&:last-child': {
paddingLeft: '15px',
},
},
}));

export const StyledUlBox = styled(Box, { label: 'StyledUlBox' })(
({ theme }) => ({
alignItems: 'center',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { FirewallPolicyType } from '@linode/api-v4/lib/firewalls/types';
import { useTheme } from '@mui/material/styles';
import { Theme } from '@mui/material/styles';
import useMediaQuery from '@mui/material/useMediaQuery';
import { prop, uniqBy } from 'ramda';
import * as React from 'react';
Expand All @@ -17,33 +15,37 @@ import { Box } from 'src/components/Box';
import { Hidden } from 'src/components/Hidden';
import { Typography } from 'src/components/Typography';
import {
FirewallOptionItem,
generateAddressesLabel,
generateRuleLabel,
predefinedFirewallFromRule as ruleToPredefinedFirewall,
} from 'src/features/Firewalls/shared';
import { capitalize } from 'src/utilities/capitalize';

import { FirewallRuleActionMenu } from './FirewallRuleActionMenu';
import { ExtendedFirewallRule, RuleStatus } from './firewallRuleEditor';
import {
MoreStyledLinkButton,
StyledButtonDiv,
StyledCellItemBox,
StyledDragIndicator,
StyledErrorDiv,
StyledFirewallRuleBox,
StyledFirewallRuleButton,
StyledFirewallTableButton,
StyledHeaderDiv,
StyledHeaderItemBox,
StyledInnerBox,
StyledUl,
StyledUlBox,
sxBox,
sxItemSpacing,
} from './FirewallRuleTable.styles';
import { Category, FirewallRuleError, sortPortString } from './shared';
import { sortPortString } from './shared';

import type { FirewallRuleDrawerMode } from './FirewallRuleDrawer.types';
import type { ExtendedFirewallRule, RuleStatus } from './firewallRuleEditor';
import type { Category, FirewallRuleError } from './shared';
import type { FirewallPolicyType } from '@linode/api-v4/lib/firewalls/types';
import type { Theme } from '@mui/material/styles';
import type { FirewallOptionItem } from 'src/features/Firewalls/shared';

interface RuleRow {
action?: string;
Expand Down Expand Up @@ -100,6 +102,7 @@ export const FirewallRuleTable = (props: FirewallRuleTableProps) => {

const theme: Theme = useTheme();
const xsDown = useMediaQuery(theme.breakpoints.down('sm'));
const betweenSmAndLg = useMediaQuery(theme.breakpoints.between('sm', 'lg'));

const addressColumnLabel =
category === 'inbound' ? 'sources' : 'destinations';
Expand Down Expand Up @@ -146,32 +149,30 @@ export const FirewallRuleTable = (props: FirewallRuleTableProps) => {
sx={sxBox}
tabIndex={0}
>
<Box
<StyledHeaderItemBox
sx={{
...sxItemSpacing,
paddingLeft: '27px',
width: xsDown ? '50%' : '32%',
width: xsDown ? '50%' : '30%',
}}
>
Label
</Box>
</StyledHeaderItemBox>
<Hidden lgDown>
<Box sx={{ ...sxItemSpacing, width: '10%' }}>Protocol</Box>
<StyledHeaderItemBox sx={{ width: '10%' }}>
Protocol
</StyledHeaderItemBox>
</Hidden>
<Hidden smDown>
<Box
sx={{
...sxItemSpacing,
width: '15%',
}}
>
<StyledHeaderItemBox sx={{ width: betweenSmAndLg ? '14%' : '10%' }}>
Port Range
</Box>
<Box sx={{ ...sxItemSpacing, width: '15%' }}>
</StyledHeaderItemBox>
<StyledHeaderItemBox sx={{ width: betweenSmAndLg ? '20%' : '14%' }}>
{capitalize(addressColumnLabel)}
</Box>
</StyledHeaderItemBox>
</Hidden>
<Box sx={{ ...sxItemSpacing, width: '5%' }}>Action</Box>
<StyledHeaderItemBox sx={{ width: xsDown ? '30%' : '12%' }}>
Action
</StyledHeaderItemBox>
<StyledHeaderItemBox flexGrow={1} />
</StyledInnerBox>
<Box sx={{ ...sxBox, flexDirection: 'column' }}>
<DragDropContext onDragEnd={onDragEnd}>
Expand Down Expand Up @@ -258,6 +259,7 @@ export interface FirewallRuleTableRowProps extends RuleRow {
const FirewallRuleTableRow = React.memo((props: FirewallRuleTableRowProps) => {
const theme: Theme = useTheme();
const xsDown = useMediaQuery(theme.breakpoints.down('sm'));
const betweenSmAndLg = useMediaQuery(theme.breakpoints.between('sm', 'lg'));

const {
action,
Expand Down Expand Up @@ -293,12 +295,11 @@ const FirewallRuleTableRow = React.memo((props: FirewallRuleTableRowProps) => {
ruleId={id}
status={status}
>
<Box
<StyledCellItemBox
sx={{
...sxItemSpacing,
overflowWrap: 'break-word',
paddingLeft: '8px',
width: xsDown ? '50%' : '32%',
paddingLeft: '10px !important',
width: xsDown ? '50%' : '30%',
}}
aria-label={`Label: ${label}`}
>
Expand All @@ -311,38 +312,41 @@ const FirewallRuleTableRow = React.memo((props: FirewallRuleTableRowProps) => {
Add a label
</MoreStyledLinkButton>
)}{' '}
</Box>
</StyledCellItemBox>
<Hidden lgDown>
<Box
<StyledCellItemBox
aria-label={`Protocol: ${protocol}`}
sx={{ ...sxItemSpacing, width: '10%' }}
sx={{ width: '10%' }}
>
{protocol}
<ConditionalError errors={errors} formField="protocol" />
</Box>
</StyledCellItemBox>
</Hidden>
<Hidden smDown>
<Box
<StyledCellItemBox
aria-label={`Ports: ${ports}`}
sx={{ ...sxItemSpacing, width: '15%' }}
sx={{ width: betweenSmAndLg ? '14%' : '10%' }}
>
{ports === '1-65535' ? 'All Ports' : ports}
<ConditionalError errors={errors} formField="ports" />
</Box>
<Box
</StyledCellItemBox>
<StyledCellItemBox
sx={{
overflowWrap: 'break-word',
width: betweenSmAndLg ? '20%' : '14%',
}}
aria-label={`Addresses: ${addresses}`}
sx={{ ...sxItemSpacing, overflowWrap: 'break-word', width: '15%' }}
>
{addresses} <ConditionalError errors={errors} formField="addresses" />
</Box>
</StyledCellItemBox>
</Hidden>
<Box
<StyledCellItemBox
aria-label={`Action: ${action}`}
sx={{ ...sxItemSpacing, width: '5%' }}
sx={{ width: xsDown ? '30%' : '12%' }}
>
{capitalize(action?.toLocaleLowerCase() ?? '')}
</Box>
<Box sx={{ ...sxItemSpacing, marginLeft: 'auto' }}>
</StyledCellItemBox>
<StyledCellItemBox sx={{ marginLeft: 'auto' }}>
{status !== 'NOT_MODIFIED' ? (
<StyledButtonDiv>
<StyledFirewallRuleButton
Expand All @@ -358,7 +362,7 @@ const FirewallRuleTableRow = React.memo((props: FirewallRuleTableRowProps) => {
) : (
<FirewallRuleActionMenu {...actionMenuProps} />
)}
</Box>
</StyledCellItemBox>
</StyledFirewallRuleBox>
);
});
Expand Down Expand Up @@ -390,21 +394,21 @@ export const PolicyRow = React.memo((props: PolicyRowProps) => {
);

// Using a grid here to keep the Select and the helper text aligned
// with the Action column.
// with the Action column for screens < 'lg', and with the last column for screens >= 'lg'.
const sxBoxGrid = {
alignItems: 'center',
backgroundColor: theme.bg.bgPaper,
borderBottom: `1px solid ${theme.borderColors.borderTable}`,
border: `1px solid ${theme.borderColors.borderTable}`,
color: theme.textColors.tableStatic,
display: 'grid',
fontSize: '.875rem',
gridTemplateAreas: `'one two three four five'`,
gridTemplateColumns: '32% 10% 10% 15% 120px',
gridTemplateAreas: `'one two three four five six'`,
gridTemplateColumns: '30% 10% 10% 14% 12% 120px',
height: '40px',
marginTop: '10px',
[theme.breakpoints.down('lg')]: {
gridTemplateAreas: `'one two three four'`,
gridTemplateColumns: '32% 15% 15% 120px',
gridTemplateAreas: `'one two three four five'`,
gridTemplateColumns: '30% 14% 20% 12% 120px',
},
[theme.breakpoints.down('sm')]: {
gridTemplateAreas: `'one two'`,
Expand All @@ -414,9 +418,8 @@ export const PolicyRow = React.memo((props: PolicyRowProps) => {
};

const sxBoxPolicyText = {
gridArea: '1 / 1 / 1 / 5',
gridArea: '1 / 1 / 1 / 6',
padding: '0px 15px 0px 15px',

textAlign: 'right',
[theme.breakpoints.down('lg')]: {
gridArea: '1 / 1 / 1 / 4',
Expand All @@ -427,7 +430,7 @@ export const PolicyRow = React.memo((props: PolicyRowProps) => {
};

const sxBoxPolicySelect = {
gridArea: 'five',
gridArea: 'six',
[theme.breakpoints.down('lg')]: {
gridArea: 'four',
},
Expand All @@ -444,14 +447,14 @@ export const PolicyRow = React.memo((props: PolicyRowProps) => {
textFieldProps={{
hideLabel: true,
}}
autoHighlight
onChange={(_, selected) => handlePolicyChange(selected?.value)}
value={policyOptions.find(
(thisOption) => thisOption.value === policy
)}
disabled={disabled}
autoHighlight
disableClearable
disabled={disabled}
label={`${category} policy`}
onChange={(_, selected) => handlePolicyChange(selected?.value)}
options={policyOptions}
/>
</Box>
Expand Down