Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
d83b3ea
Save progress
pmakode-akamai Nov 10, 2025
9c0f0e7
Update tests
pmakode-akamai Nov 10, 2025
065f133
Few more changes
pmakode-akamai Nov 10, 2025
6292e35
Add more changes
pmakode-akamai Nov 10, 2025
743e7b7
Clean up tests
pmakode-akamai Nov 10, 2025
dd7bd2a
Few changes
pmakode-akamai Nov 10, 2025
2024d14
Layout updates
pmakode-akamai Nov 10, 2025
c2e869a
Update tests
pmakode-akamai Nov 10, 2025
e3a138e
Add ruleset loading state
pmakode-akamai Nov 10, 2025
99275ce
Merge branch 'develop' into UIE-9507-9510-mocks-factories-and-firewal…
pmakode-akamai Nov 11, 2025
46ab03b
Clean up mocks
pmakode-akamai Nov 11, 2025
d7e0e96
Fix mocks
pmakode-akamai Nov 11, 2025
c4976e6
Add comments to the type
pmakode-akamai Nov 11, 2025
67c6dc7
Merge branch 'develop' into UIE-9507-9510-mocks-factories-and-firewal…
pmakode-akamai Nov 11, 2025
36beab9
Added changeset: Update FirewallRuleType to support ruleset
pmakode-akamai Nov 11, 2025
2cdbeae
Added changeset: Update FirewallRuleTypeSchema to support ruleset
pmakode-akamai Nov 11, 2025
d32b0c0
Added changeset: Add new Firewall RuleSet row layout
pmakode-akamai Nov 11, 2025
c7df617
Update ruleset action text - Delete to Remove
pmakode-akamai Nov 12, 2025
125ff60
Merge branch 'develop' into UIE-9507-9510-mocks-factories-and-firewal…
pmakode-akamai Nov 12, 2025
1751ca0
Save progress...
pmakode-akamai Nov 12, 2025
904eee7
Update comment
pmakode-akamai Nov 12, 2025
4171b78
Exclude 'addresses' from rulesets reference payloads
pmakode-akamai Nov 12, 2025
65762ca
Some fixes
pmakode-akamai Nov 12, 2025
7452795
Add more details to the drawer for rulset
pmakode-akamai Nov 12, 2025
6291906
More changes...
pmakode-akamai Nov 12, 2025
47273ae
Merge branch 'develop' into UIE-9507-9510-mocks-factories-and-firewal…
pmakode-akamai Nov 13, 2025
e89a24b
Move Action column and improve table responsiveness for long labels
pmakode-akamai Nov 13, 2025
2e0d39a
Merge branch 'develop' into UIE-9507-9510-mocks-factories-and-firewal…
pmakode-akamai Nov 13, 2025
b731488
Update Cypress component test
pmakode-akamai Nov 13, 2025
e4651d2
Merge branch 'UIE-9507-9510-mocks-factories-and-firewall-ruleset-row-…
pmakode-akamai Nov 13, 2025
af8fb56
Add more changes to the drawer for rulesets
pmakode-akamai Nov 13, 2025
7347405
Update gap & fontsize of firwall add rules selection card
pmakode-akamai Nov 13, 2025
5817603
Fix Chip shrink issue
pmakode-akamai Nov 13, 2025
c500b85
Revert Action column movement since its not yet confirmed
pmakode-akamai Nov 14, 2025
3fdd8ed
Merge branch 'develop' into UIE-9507-9510-mocks-factories-and-firewal…
pmakode-akamai Nov 14, 2025
6293ed0
Merge branch 'develop' into UIE-9514-update-firewall-rule-drawer-to-s…
pmakode-akamai Nov 14, 2025
4a2f305
Merge branch 'UIE-9507-9510-mocks-factories-and-firewall-ruleset-row-…
pmakode-akamai Nov 14, 2025
cd225a9
More Refactoring + better formstate typesaftey
pmakode-akamai Nov 15, 2025
f857b01
Add renderOptions for Add ruleset Autocomplete
pmakode-akamai Nov 15, 2025
75cd158
Fix typos
pmakode-akamai Nov 15, 2025
7331cea
Few updates
pmakode-akamai Nov 15, 2025
d54af02
Few fixes
pmakode-akamai Nov 17, 2025
ff9d267
Update cypress component tests
pmakode-akamai Nov 17, 2025
c33df38
Merge branch 'develop' into UIE-9507-9510-mocks-factories-and-firewal…
pmakode-akamai Nov 17, 2025
712890c
Merge branch 'develop' into UIE-9514-update-firewall-rule-drawer-to-s…
pmakode-akamai Nov 17, 2025
e392361
Merge branch 'UIE-9507-9510-mocks-factories-and-firewall-ruleset-row-…
pmakode-akamai Nov 17, 2025
fb5f838
More changes
pmakode-akamai Nov 17, 2025
3673196
Update Add rulesets button copy
pmakode-akamai Nov 17, 2025
2c795d7
More Updates
pmakode-akamai Nov 17, 2025
6ed18a4
Feature flag create entity selection for ruleset
pmakode-akamai Nov 17, 2025
3a6da27
More refactoring - separating form states
pmakode-akamai Nov 17, 2025
af42935
Add ruleset details drawer
pmakode-akamai Nov 17, 2025
81c11e9
Some clean up...
pmakode-akamai Nov 17, 2025
0712d06
Resolve merge conflict
pmakode-akamai Nov 17, 2025
5544f71
Save progress
pmakode-akamai Nov 18, 2025
3bf3858
Add more changes
pmakode-akamai Nov 18, 2025
42cceb1
Show only rulsets in dropdown applicable to the given catergory
pmakode-akamai Nov 18, 2025
03eb6a5
Fix conflicts
pmakode-akamai Nov 18, 2025
0137d06
Update Date format and some minor changes
pmakode-akamai Nov 18, 2025
9cc0aa2
Update mark for deletion date format
pmakode-akamai Nov 18, 2025
6b3b2de
Update date format
pmakode-akamai Nov 18, 2025
015f886
Merge branch 'UIE-9514-update-firewall-rule-drawer-to-support-referen…
pmakode-akamai Nov 18, 2025
8723399
Merge branch 'develop' into UIE-9512-9530-new-ruleset-details-drawer-…
pmakode-akamai Nov 19, 2025
ed9eb3a
Resolve merge conflicts
pmakode-akamai Nov 19, 2025
977db52
Update badge color tokens
pmakode-akamai Nov 19, 2025
d624461
Capitalize action label in chip
pmakode-akamai Nov 19, 2025
0e1f3e0
Update Chip width
pmakode-akamai Nov 19, 2025
1d5fc46
Added changeset: Update Firewall Rule Drawer to support referencing R…
pmakode-akamai Nov 19, 2025
ce264c4
Merge branch 'UIE-9514-update-firewall-rule-drawer-to-support-referen…
pmakode-akamai Nov 19, 2025
ba5de42
Use right color tokens for badge
pmakode-akamai Nov 19, 2025
3e1d0b6
Update placeholder for Select Rule Set
pmakode-akamai Nov 19, 2025
b38abda
Merge branch 'UIE-9514-update-firewall-rule-drawer-to-support-referen…
pmakode-akamai Nov 19, 2025
c560f64
Some clean up
pmakode-akamai Nov 19, 2025
c63ed4a
Few updates and clean up
pmakode-akamai Nov 20, 2025
c0c9bc7
Make cy test work
pmakode-akamai Nov 20, 2025
58d5247
Clean up: remove duplicate validation
pmakode-akamai Nov 20, 2025
883b2a2
Resolve merge conflicts
pmakode-akamai Nov 20, 2025
24c870a
Add cancel btn for rules form + some design tokens for dropdown options
pmakode-akamai Nov 20, 2025
756fd24
Merge branch 'UIE-9514-update-firewall-rule-drawer-to-support-referen…
pmakode-akamai Nov 20, 2025
43b4807
Add cancel btn and some styling fixes
pmakode-akamai Nov 20, 2025
9049305
Add mocks for Marked for deletion status
pmakode-akamai Nov 20, 2025
042842b
Add unit tests for Add Rule Set Drawer
pmakode-akamai Nov 20, 2025
05d9d94
Update test title
pmakode-akamai Nov 20, 2025
21f481c
Mock useIsFirewallRulesetsPrefixlistsEnabled instead of feature flag
pmakode-akamai Nov 20, 2025
755f8e6
Merge branch 'UIE-9514-update-firewall-rule-drawer-to-support-referen…
pmakode-akamai Nov 20, 2025
a2be442
Fix styling and a bit of clean up
pmakode-akamai Nov 21, 2025
ab45c69
Merge branch 'UIE-9514-update-firewall-rule-drawer-to-support-referen…
pmakode-akamai Nov 21, 2025
b7467b5
Clean up and refactor
pmakode-akamai Nov 21, 2025
65c29aa
Minor styling fixes
pmakode-akamai Nov 21, 2025
5973080
Add unit tests
pmakode-akamai Nov 21, 2025
d4424e0
Add omitted props for StyledListItem
pmakode-akamai Nov 21, 2025
9c76b83
pull latest from dev and resolve merge conflicts
pmakode-akamai Nov 21, 2025
80a8a1d
Added changeset: New Rule Set Details drawer with Marked for Deletion…
pmakode-akamai Nov 21, 2025
a0e78d3
Some clean up
pmakode-akamai Nov 24, 2025
9112a01
Merge branch 'develop' into UIE-9512-9530-new-ruleset-details-drawer-…
pmakode-akamai Nov 24, 2025
afb2851
Update unit tests
pmakode-akamai Nov 24, 2025
e02e98d
Fix typo
pmakode-akamai Nov 24, 2025
c3c26fd
Make Rule Drawer accessible via routes
pmakode-akamai Nov 24, 2025
f618786
Improve tests
pmakode-akamai Nov 24, 2025
27cf841
Add error state
pmakode-akamai Nov 24, 2025
17a0058
Mock getUserTimezone
pmakode-akamai Nov 24, 2025
1af2bb8
Some Clean up and allow route-based access only for view and create m…
pmakode-akamai Nov 24, 2025
19f4b8b
Few changes
pmakode-akamai Nov 24, 2025
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
---

New Rule Set Details drawer with Marked for Deletion status ([#13108](https://github.com/linode/manager/pull/13108))
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { capitalize } from '@linode/utilities';
import userEvent from '@testing-library/user-event';
import * as React from 'react';

import { firewallRuleSetFactory } from 'src/factories';
import { allIPs } from 'src/features/Firewalls/shared';
import { stringToExtendedIP } from 'src/utilities/ipUtils';
import { renderWithTheme } from 'src/utilities/testHelpers';
Expand All @@ -18,12 +20,35 @@ import {
validateForm,
validateIPs,
} from './FirewallRuleDrawer.utils';
import { PORT_PRESETS } from './shared';
import { PORT_PRESETS, RULESET_MARKED_FOR_DELETION_TEXT } from './shared';

import type { FirewallRuleDrawerProps } from './FirewallRuleDrawer.types';
import type { ExtendedFirewallRule } from './firewallRuleEditor';
import type { FirewallRuleError } from './shared';
import type { FirewallPolicyType } from '@linode/api-v4/lib/firewalls/types';
import type { Category, FirewallRuleError } from './shared';
import type {
FirewallPolicyType,
FirewallRuleSet,
} from '@linode/api-v4/lib/firewalls/types';

const queryMocks = vi.hoisted(() => ({
useFirewallRuleSetQuery: vi.fn().mockReturnValue({}),
}));

vi.mock('@linode/queries', async () => {
const actual = await vi.importActual('@linode/queries');
return {
...actual,
useFirewallRuleSetQuery: queryMocks.useFirewallRuleSetQuery,
};
});

vi.mock('@linode/utilities', async () => {
const actual = await vi.importActual('@linode/utilities');
return {
...actual,
getUserTimezone: vi.fn().mockReturnValue('utc'),
};
});

const mockOnClose = vi.fn();
const mockOnSubmit = vi.fn();
Expand Down Expand Up @@ -144,6 +169,92 @@ describe('AddRuleSetDrawer', () => {
});
});

describe('ViewRuleSetDetailsDrawer', () => {
beforeEach(() => {
spy.mockReturnValue({ isFirewallRulesetsPrefixlistsEnabled: true });
});

const activeRuleSet = firewallRuleSetFactory.build({ id: 123 });
const deletedRuleSet = firewallRuleSetFactory.build({
id: 456,
deleted: '2025-07-24T04:23:17',
});

it.each([
['inbound', activeRuleSet],
['outbound', activeRuleSet],
['inbound', deletedRuleSet],
['outbound', deletedRuleSet],
] as [Category, FirewallRuleSet][])(
'renders %s ruleset drawer (%s)',
async (category, mockData) => {
queryMocks.useFirewallRuleSetQuery.mockReturnValue({
data: mockData,
isFetching: false,
error: null,
});

const { getByText, getByRole, getByTestId, findByText, queryByText } =
renderWithTheme(
<FirewallRuleDrawer
{...props}
category={category}
mode="view"
ruleToModifyOrView={{
ruleset: mockData.id,
originalIndex: 0,
status: 'NEW',
}}
/>
);

// Drawer title
expect(
getByText(`${capitalize(category)} Rule Set details`)
).toBeVisible();

// Labels
const labels = [
'Label',
'ID',
'Description',
'Service Defined',
'Version',
'Created',
'Updated',
];
labels.forEach((label) => expect(getByText(`${label}:`)).toBeVisible());

// Check ID value
expect(getByText(`${mockData.id}`)).toBeVisible();

if (mockData.deleted) {
// Marked for deletion status section
expect(getByText('Marked for deletion:')).toBeVisible();
expect(getByText('2025-07-24 04:23')).toBeVisible();
// Tooltip icon should exist
const tooltipIcon = getByTestId('tooltip-info-icon');
expect(tooltipIcon).toBeInTheDocument();

// Tooltip text should exist
await userEvent.hover(tooltipIcon);
expect(
await findByText(RULESET_MARKED_FOR_DELETION_TEXT)
).toBeVisible();
} else {
// Marked for deletion status section should not exist
expect(queryByText('Marked for deletion:')).not.toBeInTheDocument();
}

// Rules section
expect(getByText(`${capitalize(category)} Rules`)).toBeVisible();

// Cancel button
expect(getByRole('button', { name: 'Cancel' })).toBeVisible();
}
);
});

describe('utilities', () => {
describe('formValueToIPs', () => {
it('returns a complete set of IPs given a string form value', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ import * as React from 'react';

import { SelectionCard } from 'src/components/SelectionCard/SelectionCard';

import {
type FirewallOptionItem,
useIsFirewallRulesetsPrefixlistsEnabled,
} from '../../shared';
import { useIsFirewallRulesetsPrefixlistsEnabled } from '../../shared';
import {
formValueToIPs,
getInitialFormValues,
Expand All @@ -20,9 +17,11 @@ import {
validateIPs,
} from './FirewallRuleDrawer.utils';
import { FirewallRuleForm } from './FirewallRuleForm';
import { FirewallRuleSetDetailsView } from './FirewallRuleSetDetailsView';
import { FirewallRuleSetForm } from './FirewallRuleSetForm';
import { firewallRuleCreateOptions } from './shared';

import type { FirewallOptionItem } from '../../shared';
import type {
FirewallCreateEntityType,
FirewallRuleDrawerProps,
Expand All @@ -40,7 +39,7 @@ import type { ExtendedIP } from 'src/utilities/ipUtils';
// =============================================================================
export const FirewallRuleDrawer = React.memo(
(props: FirewallRuleDrawerProps) => {
const { category, isOpen, mode, onClose, ruleToModify } = props;
const { category, isOpen, mode, onClose, ruleToModifyOrView } = props;

const { isFirewallRulesetsPrefixlistsEnabled } =
useIsFirewallRulesetsPrefixlistsEnabled();
Expand Down Expand Up @@ -69,9 +68,9 @@ export const FirewallRuleDrawer = React.memo(
React.useEffect(() => {
// Reset state. If we're in EDIT mode, set IPs to the addresses of the rule we're modifying
// (along with any errors we may have).
if (mode === 'edit' && ruleToModify) {
setIPs(getInitialIPs(ruleToModify));
setPresetPorts(portStringToItems(ruleToModify.ports)[0]);
if (mode === 'edit' && ruleToModifyOrView) {
setIPs(getInitialIPs(ruleToModifyOrView));
setPresetPorts(portStringToItems(ruleToModifyOrView.ports)[0]);
} else if (isOpen) {
setPresetPorts([]);
} else {
Expand All @@ -87,14 +86,21 @@ export const FirewallRuleDrawer = React.memo(
) {
setCreateEntityType('rule');
}
}, [mode, isOpen, ruleToModify, isFirewallRulesetsPrefixlistsEnabled]);
}, [
mode,
isOpen,
ruleToModifyOrView,
isFirewallRulesetsPrefixlistsEnabled,
]);

const title =
mode === 'create'
? `Add an ${capitalize(category)} Rule${
isFirewallRulesetsPrefixlistsEnabled ? ' or Rule Set' : ''
}`
: 'Edit Rule';
: mode === 'edit'
? 'Edit Rule'
: `${capitalize(category)} Rule Set details`;

const addressesLabel = category === 'inbound' ? 'source' : 'destination';

Expand Down Expand Up @@ -185,9 +191,10 @@ export const FirewallRuleDrawer = React.memo(
</Grid>
)}

{(mode === 'edit' || createEntityType === 'rule') && (
{(mode === 'edit' ||
(mode === 'create' && createEntityType === 'rule')) && (
<Formik<FormState>
initialValues={getInitialFormValues(ruleToModify)}
initialValues={getInitialFormValues(ruleToModifyOrView)}
onSubmit={onSubmitRule}
validate={onValidateRule}
validateOnBlur={false}
Expand All @@ -210,7 +217,7 @@ export const FirewallRuleDrawer = React.memo(
ips={ips}
mode={mode}
presetPorts={presetPorts}
ruleErrors={ruleToModify?.errors}
ruleErrors={ruleToModifyOrView?.errors}
setIPs={setIPs}
setPresetPorts={setPresetPorts}
{...formikProps}
Expand Down Expand Up @@ -246,17 +253,28 @@ export const FirewallRuleDrawer = React.memo(
<FirewallRuleSetForm
category={category}
closeDrawer={onClose}
ruleErrors={ruleToModify?.errors}
ruleErrors={ruleToModifyOrView?.errors}
{...formikProps}
/>
</>
)}
</Formik>
)}
<Typography variant="body1">
Rule changes don&rsquo;t take effect immediately. You can add or
delete rules before saving all your changes to this Firewall.
</Typography>

{mode === 'view' && (
<FirewallRuleSetDetailsView
category={category}
closeDrawer={onClose}
ruleset={ruleToModifyOrView?.ruleset}
/>
)}

{(mode === 'create' || mode === 'edit') && (
<Typography variant="body1">
Rule changes don&rsquo;t take effect immediately. You can add or
delete rules before saving all your changes to this Firewall.
</Typography>
)}
</Drawer>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import type {
import type { FormikProps } from 'formik';
import type { ExtendedIP } from 'src/utilities/ipUtils';

export type FirewallRuleDrawerMode = 'create' | 'edit';
export type FirewallRuleDrawerMode = 'create' | 'edit' | 'view';

export interface FirewallRuleDrawerProps {
category: Category;
isOpen: boolean;
mode: FirewallRuleDrawerMode;
onClose: () => void;
onSubmit: (category: 'inbound' | 'outbound', rule: FirewallRuleType) => void;
ruleToModify?: ExtendedFirewallRule;
ruleToModifyOrView?: ExtendedFirewallRule;
}

export interface FormState {
Expand Down
Loading