From df645758f9247ddefe69b6a7c8c46b4d1b3de621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20W=C3=B3jcik?= Date: Tue, 24 Mar 2026 10:02:36 +0100 Subject: [PATCH 1/2] remove permissions & restrictions columns --- web/src/pages/RulesPage/RulesTable.tsx | 103 +----------------- .../pages/RulesPage/tabs/RulesDeployedTab.tsx | 9 +- .../pages/RulesPage/tabs/RulesPendingTab.tsx | 9 +- 3 files changed, 3 insertions(+), 118 deletions(-) diff --git a/web/src/pages/RulesPage/RulesTable.tsx b/web/src/pages/RulesPage/RulesTable.tsx index 2a17257999..afa2ff8af8 100644 --- a/web/src/pages/RulesPage/RulesTable.tsx +++ b/web/src/pages/RulesPage/RulesTable.tsx @@ -5,7 +5,7 @@ import { getCoreRowModel, useReactTable, } from '@tanstack/react-table'; -import { cloneDeep, flat } from 'radashi'; +import { cloneDeep } from 'radashi'; import { useCallback, useMemo, useState } from 'react'; import './RulesTable.scss'; import { m } from '../../paraglide/messages'; @@ -16,12 +16,9 @@ import { type AclRule, AclStatus, type AclStatusValue, - type GroupInfo, type LicenseInfo, - type NetworkDevice, type NetworkLocation, type ResourceById, - type User, } from '../../shared/api/types'; import { TableValuesListCell } from '../../shared/components/TableValuesListCell/TableValuesListCell'; import { Badge } from '../../shared/defguard-ui/components/Badge/Badge'; @@ -40,18 +37,8 @@ import { TableCell } from '../../shared/defguard-ui/components/table/TableCell/T import { TableEditCell } from '../../shared/defguard-ui/components/table/TableEditCell/TableEditCell'; import { TableTop } from '../../shared/defguard-ui/components/table/TableTop/TableTop'; import { Snackbar } from '../../shared/defguard-ui/providers/snackbar/snackbar'; -import { isPresent } from '../../shared/defguard-ui/utils/isPresent'; import { canUseBusinessFeature, licenseActionCheck } from '../../shared/utils/license'; -const displayUser = (user?: User): string => { - if (!isPresent(user)) return ''; - - if (user.first_name || user.last_name) { - return `${user.first_name} ${user.last_name}`.trim(); - } - return user.username; -}; - type RowData = AclRule; const columnHelper = createColumnHelper(); @@ -60,9 +47,6 @@ type Props = { license: LicenseInfo | null; aliases: ResourceById; destinations: ResourceById; - groups: ResourceById; - users: ResourceById; - devices: ResourceById; locations: ResourceById; data: AclRule[]; title: string; @@ -83,9 +67,6 @@ export const RulesTable = ({ enableSearch, aliases, destinations, - devices, - groups, - users, locations, data, license, @@ -119,53 +100,6 @@ export const RulesTable = ({ const [search, setSearch] = useState(''); - const renderPermissionCell = useCallback( - ( - permission: 'deny' | 'allow', - permissionUsers: boolean, - permissionGroup: boolean, - permissionDevice: boolean, - includedUsers: number[], - includedGroups: number[], - includedDevices: number[], - ) => { - if (permissionDevice && permissionGroup && permissionUsers) { - return ( - - {permission === 'allow' && ( - - )} - {permission === 'deny' && ( - - )} - - ); - } - const display = flat([ - permissionUsers - ? ['All users'] - : includedUsers.map((userId) => displayUser(users[userId])), - permissionGroup - ? ['All groups'] - : includedGroups.map((groupId) => groups[groupId]?.name ?? ''), - permissionDevice - ? ['All network devices'] - : includedDevices.map((deviceId) => devices[deviceId]?.name ?? ''), - ]).filter((value) => value.length > 0); - - return ; - }, - [users, devices, groups], - ); - const renderStatusCell = useCallback( (ruleState: AclStatusValue, isEnabled: boolean) => { // handle applied rules first @@ -254,40 +188,6 @@ export const RulesTable = ({ ); }, }), - columnHelper.display({ - id: 'permissions', - header: 'Permissions', - minSize: 220, - cell: (info) => { - const row = info.row.original; - return renderPermissionCell( - 'allow', - row.allow_all_users, - row.allow_all_groups, - row.allow_all_network_devices, - row.allowed_users, - row.allowed_groups, - row.allowed_network_devices, - ); - }, - }), - columnHelper.display({ - id: 'restrictions', - header: 'Restrictions', - minSize: 220, - cell: (info) => { - const row = info.row.original; - return renderPermissionCell( - 'deny', - row.deny_all_users, - row.deny_all_groups, - row.deny_all_network_devices, - row.denied_users, - row.denied_groups, - row.denied_network_devices, - ); - }, - }), columnHelper.display({ id: 'locations', header: 'Locations', @@ -408,7 +308,6 @@ export const RulesTable = ({ [ aliases, destinations, - renderPermissionCell, deleteRule, locations, navigate, diff --git a/web/src/pages/RulesPage/tabs/RulesDeployedTab.tsx b/web/src/pages/RulesPage/tabs/RulesDeployedTab.tsx index 0990d80f51..fa996a984a 100644 --- a/web/src/pages/RulesPage/tabs/RulesDeployedTab.tsx +++ b/web/src/pages/RulesPage/tabs/RulesDeployedTab.tsx @@ -21,8 +21,7 @@ export const RulesDeployedTab = () => { const navigate = useNavigate(); - const { aliases, destinations, groups, locations, users, devices, license, loading } = - useRuleDeps(); + const { aliases, destinations, locations, license, loading } = useRuleDeps(); const buttonProps = useMemo( (): ButtonProps => ({ @@ -55,10 +54,7 @@ export const RulesDeployedTab = () => { {!isEmpty && isPresent(aliases) && isPresent(destinations) && - isPresent(groups) && isPresent(locations) && - isPresent(users) && - isPresent(devices) && license !== undefined && ( { data={rules} aliases={aliases} destinations={destinations} - groups={groups} - devices={devices} - users={users} locations={locations} license={license} enableSearch diff --git a/web/src/pages/RulesPage/tabs/RulesPendingTab.tsx b/web/src/pages/RulesPage/tabs/RulesPendingTab.tsx index f0ff2ac3c6..a229aa237a 100644 --- a/web/src/pages/RulesPage/tabs/RulesPendingTab.tsx +++ b/web/src/pages/RulesPage/tabs/RulesPendingTab.tsx @@ -25,8 +25,7 @@ export const RulesPendingTab = () => { }, }); - const { aliases, destinations, groups, locations, users, devices, license, loading } = - useRuleDeps(); + const { aliases, destinations, locations, license, loading } = useRuleDeps(); const buttonProps = useMemo( (): ButtonProps => ({ @@ -59,10 +58,7 @@ export const RulesPendingTab = () => { {!isEmpty && isPresent(aliases) && isPresent(destinations) && - isPresent(groups) && isPresent(locations) && - isPresent(users) && - isPresent(devices) && license !== undefined && ( { data={rules} aliases={aliases} destinations={destinations} - groups={groups} - devices={devices} - users={users} locations={locations} license={license} /> From b53774509691c2c66dbad82c98a1be8239248e16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20W=C3=B3jcik?= Date: Tue, 24 Mar 2026 11:41:32 +0100 Subject: [PATCH 2/2] split destination column into predefined and manual --- web/src/pages/RulesPage/RulesTable.tsx | 68 ++++++++++++++++---------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/web/src/pages/RulesPage/RulesTable.tsx b/web/src/pages/RulesPage/RulesTable.tsx index afa2ff8af8..3df6d18cf8 100644 --- a/web/src/pages/RulesPage/RulesTable.tsx +++ b/web/src/pages/RulesPage/RulesTable.tsx @@ -74,6 +74,19 @@ export const RulesTable = ({ }: Props) => { const navigate = useNavigate(); + const renderResourceBadge = useCallback( + (marker: 'A' | 'D', key: string, text: string) => ( + + ), + [], + ); + const { mutate: deleteRule } = useMutation({ mutationFn: api.acl.rule.deleteRule, meta: { @@ -146,43 +159,47 @@ export const RulesTable = ({ ), }), columnHelper.display({ - id: 'destination', - header: 'Destination', - minSize: 350, + id: 'predefined-destinations', + header: 'Predefined destinations', + minSize: 300, cell: (info) => { const row = info.row.original; - const manualAddresses = row.addresses.trim(); - const hasManualAddresses = manualAddresses.length > 0; - return ( - + {row.destinations.map((destinationId) => { const destination = destinations[destinationId]; if (!destination) return null; - return ( - + return renderResourceBadge( + 'D', + `destination-${destinationId}`, + destination.name, ); })} + + ); + }, + }), + columnHelper.display({ + id: 'manual-destinations', + header: 'Manually configured destination', + minSize: 300, + cell: (info) => { + const row = info.row.original; + + if (!row.use_manual_destination_settings) { + return ; + } + + const manualAddresses = row.addresses.trim(); + const hasManualAddresses = manualAddresses.length > 0; + + return ( + {hasManualAddresses && {manualAddresses}} {row.aliases.map((aliasId) => { const alias = aliases[aliasId]; if (!alias) return null; - - return ( - - ); + return renderResourceBadge('A', `alias-${aliasId}`, alias.name); })} ); @@ -312,6 +329,7 @@ export const RulesTable = ({ locations, navigate, renderStatusCell, + renderResourceBadge, license, variant, toggleRule,