[AI] replace custom styles with MenuItem and SidePanelGroup in AI agent persmissions tab (#19003)

closes
https://discord.com/channels/1130383047699738754/1486666682553598032
This commit is contained in:
nitin
2026-03-26 20:03:07 +05:30
committed by GitHub
parent f771b13a20
commit b171a23216
9 changed files with 199 additions and 340 deletions
@@ -1,11 +1,11 @@
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
import { type SettingsRoleObjectPermissionKey } from '@/settings/roles/role-permissions/objects-permissions/constants/SettingsRoleObjectPermissionIconConfig';
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
import { t } from '@lingui/core/macro';
import { type ObjectPermission } from '~/generated-metadata/graphql';
import { filterBySearchQuery } from '~/utils/filterBySearchQuery';
import { CRUD_PERMISSIONS } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/constants/WorkflowAiAgentCrudPermissions';
import { WorkflowAiAgentPermissionsPermissionRow } from './WorkflowAiAgentPermissionsPermissionRow';
import { StyledLabel, StyledList } from './WorkflowAiAgentPermissionsStyles';
const CRUD_PERMISSION_ORDER = CRUD_PERMISSIONS.reduce<
Record<SettingsRoleObjectPermissionKey, number>
@@ -94,27 +94,24 @@ export const WorkflowAiAgentPermissionList = ({
}
return (
<div>
<StyledLabel>{t`CRUD`}</StyledLabel>
<StyledList>
{filteredPermissions.map((permission) => (
<WorkflowAiAgentPermissionsPermissionRow
key={`${permission.objectMetadataId}-${permission.permissionKey}`}
permission={{
key: permission.permissionKey,
label: permission.permissionLabel,
}}
isEnabled={true}
readonly={readonly}
onDelete={() =>
onDeletePermission(
permission.objectMetadataId,
permission.permissionKey,
)
}
/>
))}
</StyledList>
</div>
<SidePanelGroup heading={t`CRUD`}>
{filteredPermissions.map((permission) => (
<WorkflowAiAgentPermissionsPermissionRow
key={`${permission.objectMetadataId}-${permission.permissionKey}`}
permission={{
key: permission.permissionKey,
label: permission.permissionLabel,
}}
isEnabled={true}
readonly={readonly}
onDelete={() =>
onDeletePermission(
permission.objectMetadataId,
permission.permissionKey,
)
}
/>
))}
</SidePanelGroup>
);
};
@@ -1,8 +1,9 @@
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
import { type SettingsRoleObjectPermissionKey } from '@/settings/roles/role-permissions/objects-permissions/constants/SettingsRoleObjectPermissionIconConfig';
import { t } from '@lingui/core/macro';
import { type ObjectPermission } from '~/generated-metadata/graphql';
import { WorkflowAiAgentPermissionsPermissionRow } from './WorkflowAiAgentPermissionsPermissionRow';
import { StyledLabel, StyledList } from './WorkflowAiAgentPermissionsStyles';
type WorkflowAiAgentPermissionsCrudListProps = {
permissions: Array<{
key: SettingsRoleObjectPermissionKey;
@@ -25,25 +26,22 @@ export const WorkflowAiAgentPermissionsCrudList = ({
objectMetadataId,
}: WorkflowAiAgentPermissionsCrudListProps) => {
return (
<div>
<StyledLabel>{t`CRUD`}</StyledLabel>
<StyledList>
{permissions.map((permission) => {
const isEnabled = Boolean(objectPermissions?.[permission.key]);
<SidePanelGroup heading={t`CRUD`}>
{permissions.map((permission) => {
const isEnabled = Boolean(objectPermissions?.[permission.key]);
return (
<WorkflowAiAgentPermissionsPermissionRow
key={permission.key}
permission={permission}
isEnabled={isEnabled}
readonly={readonly}
showDeleteButton={false}
alwaysShowGranted={true}
onAdd={() => onAddPermission(objectMetadataId, permission.key)}
/>
);
})}
</StyledList>
</div>
return (
<WorkflowAiAgentPermissionsPermissionRow
key={permission.key}
permission={permission}
isEnabled={isEnabled}
readonly={readonly}
showDeleteButton={false}
alwaysShowGranted={true}
onAdd={() => onAddPermission(objectMetadataId, permission.key)}
/>
);
})}
</SidePanelGroup>
);
};
@@ -1,7 +1,7 @@
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
import { type SettingsRolePermissionsSettingPermission } from '@/settings/roles/role-permissions/permission-flags/types/SettingsRolePermissionsSettingPermission';
import { type PermissionFlagType } from '~/generated-metadata/graphql';
import { WorkflowAiAgentPermissionsFlagRow } from './WorkflowAiAgentPermissionsFlagRow';
import { StyledLabel, StyledList } from './WorkflowAiAgentPermissionsStyles';
type WorkflowAiAgentPermissionsFlagListProps = {
title: string;
@@ -22,40 +22,27 @@ export const WorkflowAiAgentPermissionsFlagList = ({
onAddPermissionFlag,
onDeletePermissionFlag,
}: WorkflowAiAgentPermissionsFlagListProps) => {
const hasPermissions = permissions.length > 0;
if (!hasPermissions) {
if (permissions.length === 0) {
return null;
}
return (
<div>
<StyledLabel>{title}</StyledLabel>
<StyledList>
{permissions.map((permission) => {
const isEnabled = enabledPermissionFlagKeys.includes(permission.key);
<SidePanelGroup heading={title}>
{permissions.map((permission) => {
const isEnabled = enabledPermissionFlagKeys.includes(permission.key);
return (
<WorkflowAiAgentPermissionsFlagRow
key={permission.key}
permission={permission}
isEnabled={isEnabled}
readonly={readonly}
showDeleteButton={showDeleteButton}
onAdd={
isEnabled
? undefined
: () => onAddPermissionFlag?.(permission.key)
}
onDelete={
showDeleteButton
? () => onDeletePermissionFlag?.(permission.key)
: undefined
}
/>
);
})}
</StyledList>
</div>
return (
<WorkflowAiAgentPermissionsFlagRow
key={permission.key}
permission={permission}
isEnabled={isEnabled}
readonly={readonly}
showDeleteButton={showDeleteButton}
onAdd={() => onAddPermissionFlag?.(permission.key)}
onDelete={() => onDeletePermissionFlag?.(permission.key)}
/>
);
})}
</SidePanelGroup>
);
};
@@ -1,15 +1,7 @@
import { type SettingsRolePermissionsSettingPermission } from '@/settings/roles/role-permissions/permission-flags/types/SettingsRolePermissionsSettingPermission';
import { IconTrash } from 'twenty-ui/display';
import { IconButton } from 'twenty-ui/input';
import {
StyledDeleteButton,
StyledIconContainer,
StyledRow,
StyledRowLeftContent,
StyledText,
} from './WorkflowAiAgentPermissionsStyles';
import { ThemeContext } from 'twenty-ui/theme-constants';
import { useContext } from 'react';
import { MenuItem } from 'twenty-ui/navigation';
type WorkflowAiAgentPermissionsFlagRowProps = {
permission: SettingsRolePermissionsSettingPermission;
isEnabled: boolean;
@@ -27,34 +19,30 @@ export const WorkflowAiAgentPermissionsFlagRow = ({
onAdd,
onDelete,
}: WorkflowAiAgentPermissionsFlagRowProps) => {
const { theme } = useContext(ThemeContext);
const isClickable = !readonly && !isEnabled && Boolean(onAdd);
const isDisabled = isEnabled && !showDeleteButton;
const showTrashButton = isEnabled && showDeleteButton;
const iconButtons = showTrashButton
? [
{
Icon: IconTrash,
onClick: (event: React.MouseEvent) => {
event.stopPropagation();
onDelete?.();
},
},
]
: undefined;
return (
<StyledRow
<MenuItem
LeftIcon={permission.Icon}
withIconContainer
text={permission.name}
onClick={isClickable ? onAdd : undefined}
isDisabled={isDisabled}
>
<StyledRowLeftContent>
<StyledIconContainer>
<permission.Icon size={theme.icon.size.sm} />
</StyledIconContainer>
<StyledText>{permission.name}</StyledText>
</StyledRowLeftContent>
{isEnabled && showDeleteButton && (
<StyledDeleteButton data-delete-button>
<IconButton
Icon={IconTrash}
variant="tertiary"
size="small"
onClick={(event) => {
event.stopPropagation();
onDelete?.();
}}
/>
</StyledDeleteButton>
)}
</StyledRow>
disabled={isDisabled}
iconButtons={iconButtons}
/>
);
};
@@ -1,13 +1,6 @@
import { useIcons } from 'twenty-ui/display';
import {
StyledIconChevronRight,
StyledIconContainer,
StyledRow,
StyledRowLeftContent,
StyledText,
} from './WorkflowAiAgentPermissionsStyles';
import { ThemeContext } from 'twenty-ui/theme-constants';
import { useContext } from 'react';
import { MenuItem } from 'twenty-ui/navigation';
type WorkflowAiAgentPermissionsObjectRowProps = {
objectMetadata: {
id: string;
@@ -23,22 +16,16 @@ export const WorkflowAiAgentPermissionsObjectRow = ({
onClick,
readonly,
}: WorkflowAiAgentPermissionsObjectRowProps) => {
const { theme } = useContext(ThemeContext);
const { getIcon } = useIcons();
const IconComponent = getIcon(objectMetadata.icon);
return (
<StyledRow
key={objectMetadata.id}
<MenuItem
LeftIcon={IconComponent}
withIconContainer
text={objectMetadata.labelPlural}
hasSubMenu={!readonly}
onClick={!readonly ? onClick : undefined}
>
<StyledRowLeftContent>
<StyledIconContainer>
<IconComponent size={theme.icon.size.sm} />
</StyledIconContainer>
<StyledText>{objectMetadata.labelPlural}</StyledText>
</StyledRowLeftContent>
<StyledIconChevronRight size={theme.icon.size.sm} />
</StyledRow>
/>
);
};
@@ -1,6 +1,6 @@
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
import { t } from '@lingui/core/macro';
import { WorkflowAiAgentPermissionsObjectRow } from './WorkflowAiAgentPermissionsObjectRow';
import { StyledLabel, StyledList } from './WorkflowAiAgentPermissionsStyles';
type WorkflowAiAgentPermissionsObjectsListProps = {
objects: Array<{
@@ -18,18 +18,15 @@ export const WorkflowAiAgentPermissionsObjectsList = ({
readonly,
}: WorkflowAiAgentPermissionsObjectsListProps) => {
return (
<div>
<StyledLabel>{t`Objects`}</StyledLabel>
<StyledList>
{objects.map((objectMetadata) => (
<WorkflowAiAgentPermissionsObjectRow
key={objectMetadata.id}
objectMetadata={objectMetadata}
onClick={() => onObjectClick(objectMetadata.id)}
readonly={readonly}
/>
))}
</StyledList>
</div>
<SidePanelGroup heading={t`Objects`}>
{objects.map((objectMetadata) => (
<WorkflowAiAgentPermissionsObjectRow
key={objectMetadata.id}
objectMetadata={objectMetadata}
onClick={() => onObjectClick(objectMetadata.id)}
readonly={readonly}
/>
))}
</SidePanelGroup>
);
};
@@ -1,14 +1,7 @@
import { PermissionIcon } from '@/settings/roles/role-permissions/objects-permissions/components/PermissionIcon';
import { type SettingsRoleObjectPermissionKey } from '@/settings/roles/role-permissions/objects-permissions/constants/SettingsRoleObjectPermissionIconConfig';
import { IconTrash } from 'twenty-ui/display';
import { IconButton } from 'twenty-ui/input';
import {
StyledDeleteButton,
StyledIconContainer,
StyledRow,
StyledRowLeftContent,
StyledText,
} from './WorkflowAiAgentPermissionsStyles';
import { MenuItem } from 'twenty-ui/navigation';
type WorkflowAiAgentPermissionsPermissionRowProps = {
permission: {
@@ -34,34 +27,32 @@ export const WorkflowAiAgentPermissionsPermissionRow = ({
}: WorkflowAiAgentPermissionsPermissionRowProps) => {
const isClickable = !readonly && !isEnabled;
const isDisabled = isEnabled && !showDeleteButton;
const showTrashButton = isEnabled && showDeleteButton;
const iconButtons = showTrashButton
? [
{
Icon: IconTrash,
onClick: (event: React.MouseEvent) => {
event.stopPropagation();
onDelete?.();
},
},
]
: undefined;
return (
<StyledRow
<MenuItem
LeftComponent={
<PermissionIcon
permission={permission.key}
state={alwaysShowGranted || isEnabled ? 'granted' : 'revoked'}
/>
}
text={permission.label}
onClick={isClickable ? onAdd : undefined}
isDisabled={isDisabled}
>
<StyledRowLeftContent>
<StyledIconContainer>
<PermissionIcon
permission={permission.key}
state={alwaysShowGranted || isEnabled ? 'granted' : 'revoked'}
/>
</StyledIconContainer>
<StyledText>{permission.label}</StyledText>
</StyledRowLeftContent>
{isEnabled && showDeleteButton && (
<StyledDeleteButton data-delete-button>
<IconButton
Icon={IconTrash}
variant="tertiary"
size="small"
onClick={(e) => {
e.stopPropagation();
onDelete?.();
}}
/>
</StyledDeleteButton>
)}
</StyledRow>
disabled={isDisabled}
iconButtons={iconButtons}
/>
);
};
@@ -1,85 +0,0 @@
import { styled } from '@linaria/react';
import React from 'react';
import { IconChevronRight, Label } from 'twenty-ui/display';
import { themeCssVariables } from 'twenty-ui/theme-constants';
export const StyledText = styled.div`
color: ${themeCssVariables.font.color.secondary};
`;
const StyledLabelWrapper = styled.div`
margin: ${themeCssVariables.spacing[3]} ${themeCssVariables.spacing[3]}
${themeCssVariables.spacing[0]};
`;
export const StyledLabel = ({ children }: { children: React.ReactNode }) => (
<StyledLabelWrapper>
<Label>{children}</Label>
</StyledLabelWrapper>
);
export const StyledRow = styled.div<{ isDisabled?: boolean }>`
align-items: center;
border-radius: ${themeCssVariables.spacing[1]};
box-sizing: border-box;
cursor: ${({ isDisabled }) => (isDisabled ? 'not-allowed' : 'pointer')};
display: flex;
justify-content: space-between;
opacity: ${({ isDisabled }) => (isDisabled ? 0.5 : 1)};
padding: ${themeCssVariables.spacing[1]};
pointer-events: ${({ isDisabled }) => (isDisabled ? 'none' : 'auto')};
width: 100%;
:hover {
background-color: ${({ isDisabled }) =>
isDisabled ? 'inherit' : themeCssVariables.background.transparent.light};
}
:hover [data-delete-button] {
opacity: 1;
}
`;
export const StyledDeleteButton = styled.div`
opacity: 0;
transition: opacity ${themeCssVariables.animation.duration.fast}ms;
`;
export const StyledRowLeftContent = styled.div`
align-items: center;
display: flex;
gap: ${themeCssVariables.spacing[1]};
`;
export const StyledList = styled.div`
display: flex;
flex-direction: column;
gap: ${themeCssVariables.spacing[0.5]};
padding: ${themeCssVariables.spacing[2]};
`;
export const StyledIconContainer = styled.div`
align-items: center;
background-color: ${themeCssVariables.background.tertiary};
border-radius: ${themeCssVariables.spacing[1]};
color: ${themeCssVariables.font.color.tertiary};
display: flex;
justify-content: center;
padding: ${themeCssVariables.spacing[1]};
`;
const StyledIconChevronRightWrapper = styled.div`
align-items: center;
color: ${themeCssVariables.font.color.tertiary};
display: inline-flex;
`;
export const StyledIconChevronRight = ({
size,
color,
stroke,
}: React.ComponentProps<typeof IconChevronRight>) => (
<StyledIconChevronRightWrapper>
<IconChevronRight size={size} color={color} stroke={stroke} />
</StyledIconChevronRightWrapper>
);
@@ -1,20 +1,19 @@
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
import { useActionRolePermissionFlagConfig } from '@/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig';
import { SidePanelSubPageNavigationHeader } from '@/side-panel/pages/common/components/SidePanelSubPageNavigationHeader';
import { TextInput } from '@/ui/input/components/TextInput';
import { type WorkflowAiAgentAction } from '@/workflow/types/Workflow';
import { useWorkflowAiAgentPermissionActions } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/hooks/useWorkflowAiAgentPermissionActions';
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { type WorkflowAiAgentAction } from '@/workflow/types/Workflow';
import { useWorkflowAiAgentPermissionActions } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/hooks/useWorkflowAiAgentPermissionActions';
import { workflowAiAgentActionAgentState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentState';
import { workflowAiAgentPermissionsIsAddingPermissionState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsIsAddingPermissionState';
import { workflowAiAgentPermissionsSelectedObjectIdState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsSelectedObjectIdState';
import { useQuery } from '@apollo/client/react';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { useState } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { IconChevronLeft } from 'twenty-ui/display';
import { IconButton } from 'twenty-ui/input';
import { useQuery } from '@apollo/client/react';
import { type Agent, GetRolesDocument } from '~/generated-metadata/graphql';
import { SidePanelSkeletonLoader } from '~/loading/components/SidePanelSkeletonLoader';
import { filterBySearchQuery } from '~/utils/filterBySearchQuery';
@@ -22,16 +21,22 @@ import { filterBySearchQuery } from '~/utils/filterBySearchQuery';
import { isNonTextWritingKey } from '@/ui/utilities/hotkey/utils/isNonTextWritingKey';
import { WorkflowAiAgentPermissionList } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPermissionList';
import { CRUD_PERMISSIONS } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/constants/WorkflowAiAgentCrudPermissions';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { WorkflowAiAgentPermissionsCrudList } from './WorkflowAiAgentPermissionsCrudList';
import { WorkflowAiAgentPermissionsFlagList } from './WorkflowAiAgentPermissionsFlagList';
import { WorkflowAiAgentPermissionsObjectsList } from './WorkflowAiAgentPermissionsObjectsList';
import { getFilteredPermissions } from './workflowAiAgentPermissions.utils';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledSearchInputContainer = styled.div`
background-color: ${themeCssVariables.background.transparent.lighter};
border-block: 1px solid ${themeCssVariables.border.color.medium};
box-sizing: border-box;
height: 40px;
padding-inline: ${themeCssVariables.spacing[2]};
width: 100%;
& input {
background-color: transparent;
border: none;
border-radius: 0;
height: 40px;
@@ -40,24 +45,9 @@ const StyledSearchInputContainer = styled.div`
}
`;
const StyledBackButtonText = styled.span`
color: ${themeCssVariables.font.color.secondary};
`;
const StyledBackButton = styled.button`
align-items: center;
background: none;
border: none;
color: ${themeCssVariables.font.color.secondary};
cursor: pointer;
display: flex;
gap: ${themeCssVariables.spacing[1]};
padding: ${themeCssVariables.spacing[3]};
text-align: left;
width: 100%;
&:hover {
color: ${themeCssVariables.font.color.primary};
const StyledBackButtonContainer = styled.div`
& > div {
border-bottom: none;
}
`;
@@ -65,6 +55,10 @@ const StyledContainer = styled.div`
width: 100%;
`;
const StyledGroupsContainer = styled.div`
padding: ${themeCssVariables.spacing[2]};
`;
type WorkflowAiAgentPermissionsTabProps = {
action: WorkflowAiAgentAction;
readonly: boolean;
@@ -193,14 +187,17 @@ export const WorkflowAiAgentPermissionsTab = ({
return (
<StyledContainer>
{shouldShowBackButton && (
<StyledBackButton onClick={handleBack}>
<IconButton Icon={IconChevronLeft} variant="tertiary" size="small" />
<StyledBackButtonText>{t`Add permission`}</StyledBackButtonText>
</StyledBackButton>
<StyledBackButtonContainer>
<SidePanelSubPageNavigationHeader
title={t`Add permission`}
onBackClick={handleBack}
/>
</StyledBackButtonContainer>
)}
<StyledSearchInputContainer>
<TextInput
fullWidth
value={searchQuery}
onChange={(value: string) => setSearchQuery(value)}
placeholder={t`Type anything...`}
@@ -212,58 +209,60 @@ export const WorkflowAiAgentPermissionsTab = ({
/>
</StyledSearchInputContainer>
{shouldShowCrudList && (
<WorkflowAiAgentPermissionsCrudList
permissions={filterBySearchQuery({
items: CRUD_PERMISSIONS.map((p) => ({
key: p.key,
label: p.label(selectedObject.labelPlural),
})),
searchQuery,
getSearchableValues: (permission) => [permission.label],
})}
objectPermissions={objectPermissionForSelected}
readonly={readonly}
onAddPermission={handleAddPermission}
objectMetadataId={selectedObject.id}
/>
)}
<StyledGroupsContainer>
{shouldShowCrudList && (
<WorkflowAiAgentPermissionsCrudList
permissions={filterBySearchQuery({
items: CRUD_PERMISSIONS.map((p) => ({
key: p.key,
label: p.label(selectedObject.labelPlural),
})),
searchQuery,
getSearchableValues: (permission) => [permission.label],
})}
objectPermissions={objectPermissionForSelected}
readonly={readonly}
onAddPermission={handleAddPermission}
objectMetadataId={selectedObject.id}
/>
)}
{shouldShowSelectionLists && (
<>
<WorkflowAiAgentPermissionsObjectsList
objects={filteredObjects}
onObjectClick={handleObjectClick}
readonly={readonly}
/>
<WorkflowAiAgentPermissionsFlagList
title={t`Actions`}
permissions={filteredActionPermissions}
enabledPermissionFlagKeys={permissionFlagKeys}
readonly={readonly}
onAddPermissionFlag={handleAddPermissionFlag}
/>
</>
)}
{shouldShowSelectionLists && (
<>
<WorkflowAiAgentPermissionsObjectsList
objects={filteredObjects}
onObjectClick={handleObjectClick}
readonly={readonly}
/>
<WorkflowAiAgentPermissionsFlagList
title={t`Actions`}
permissions={filteredActionPermissions}
enabledPermissionFlagKeys={permissionFlagKeys}
readonly={readonly}
onAddPermissionFlag={handleAddPermissionFlag}
/>
</>
)}
{shouldShowExistingPermissions && (
<>
<WorkflowAiAgentPermissionList
readonly={readonly}
objectPermissions={objectPermissions}
onDeletePermission={handleDeletePermission}
searchQuery={searchQuery}
/>
<WorkflowAiAgentPermissionsFlagList
title={t`Actions`}
permissions={filteredEnabledActionPermissions}
enabledPermissionFlagKeys={permissionFlagKeys}
readonly={readonly}
showDeleteButton={!readonly}
onDeletePermissionFlag={handleDeletePermissionFlag}
/>
</>
)}
{shouldShowExistingPermissions && (
<>
<WorkflowAiAgentPermissionList
readonly={readonly}
objectPermissions={objectPermissions}
onDeletePermission={handleDeletePermission}
searchQuery={searchQuery}
/>
<WorkflowAiAgentPermissionsFlagList
title={t`Actions`}
permissions={filteredEnabledActionPermissions}
enabledPermissionFlagKeys={permissionFlagKeys}
readonly={readonly}
showDeleteButton={!readonly}
onDeletePermissionFlag={handleDeletePermissionFlag}
/>
</>
)}
</StyledGroupsContainer>
</StyledContainer>
);
};