From 8d4610a5951196eb719b4ea2627b8fbf7c816ac8 Mon Sep 17 00:00:00 2001 From: Grzegorz Zdunek Date: Thu, 21 Nov 2024 12:10:46 +0100 Subject: [PATCH] Remove resource lists --- .../NewRequest/ResourceList/Apps.tsx | 294 ------------------ .../NewRequest/ResourceList/Databases.tsx | 76 ----- .../NewRequest/ResourceList/Desktops.tsx | 70 ----- .../NewRequest/ResourceList/Kubes.tsx | 66 ---- .../NewRequest/ResourceList/Nodes.tsx | 86 ----- .../ResourceList/ResourceList.story.tsx | 231 -------------- .../NewRequest/ResourceList/ResourceList.tsx | 141 --------- .../NewRequest/ResourceList/UserGroups.tsx | 77 ----- 8 files changed, 1041 deletions(-) delete mode 100644 web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Apps.tsx delete mode 100644 web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Databases.tsx delete mode 100644 web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Desktops.tsx delete mode 100644 web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Kubes.tsx delete mode 100644 web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Nodes.tsx delete mode 100644 web/packages/shared/components/AccessRequests/NewRequest/ResourceList/ResourceList.story.tsx delete mode 100644 web/packages/shared/components/AccessRequests/NewRequest/ResourceList/ResourceList.tsx delete mode 100644 web/packages/shared/components/AccessRequests/NewRequest/ResourceList/UserGroups.tsx diff --git a/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Apps.tsx b/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Apps.tsx deleted file mode 100644 index 5488ceeedaefd..0000000000000 --- a/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Apps.tsx +++ /dev/null @@ -1,294 +0,0 @@ -/** - * Teleport - * Copyright (C) 2024 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import React, { useState, useEffect } from 'react'; -import styled from 'styled-components'; -import { components } from 'react-select'; -import { Flex, Text, ButtonBorder, ButtonPrimary } from 'design'; -import { ClickableLabelCell, Cell } from 'design/DataTable'; - -import { App } from 'teleport/services/apps'; - -import Select, { - Option as BaseOption, - CustomSelectComponentProps, -} from 'shared/components/Select'; -import { ToolTipInfo } from 'shared/components/ToolTip'; - -import { ResourceMap, RequestableResourceKind } from '../resource'; - -import { ListProps, StyledTable } from './ResourceList'; - -type Option = BaseOption & { - isSelected?: boolean; -}; - -export function Apps(props: ListProps & { apps: App[] }) { - const { - apps = [], - addedResources, - customSort, - onLabelClick, - addOrRemoveResource, - } = props; - return ( - ( - - ), - }, - { - altKey: 'action-btn', - render: agent => ( - - ), - }, - ]} - emptyText="No Results Found" - customSort={customSort} - disableFilter - /> - ); -} - -const OptionComponent = ( - props: CustomSelectComponentProps< - { toggleUserGroup(groupId: string, groupDescription: string): void }, - Option - > -) => { - const { toggleUserGroup } = props.selectProps.customProps; - return ( - - toggleUserGroup(props.value, props.label)} - py="8px" - px="12px" - > - {' '} - {props.label} - - - ); -}; - -function ActionCell({ - agent, - addedResources, - addOrRemoveResource, -}: { - agent: App; - addedResources: ResourceMap; - addOrRemoveResource: ( - kind: RequestableResourceKind, - resourceId: string, - resourceName?: string - ) => void; -}) { - const [userGroupOptions] = useState(() => { - return agent.userGroups.map(ug => { - return { label: ug.description, value: ug.name }; - }); - }); - const [selectedGroups, setSelectedGroups] = useState([]); - - useEffect(() => { - if (userGroupOptions.length === 0) { - return; - } - - // Applications can refer to the same user group id. - // When user selects an option from one row, we need - // to update selected groups for all other rows. - const updatedSelectedGroups = userGroupOptions.flatMap(o => { - if (addedResources.user_group[o.value]) { - return { ...o, isSelected: true }; - } - return []; // skip this option - }); - setSelectedGroups(updatedSelectedGroups); - - // A user can only select an app OR user groups. - // If a user selected a user group from one row, - // that is also applicable to this row, - // remove app from selection. - if (addedResources.app[agent.name] && updatedSelectedGroups.length > 0) { - addOrRemoveResource('app', agent.name); - } - }, [addedResources]); - - function handleSelectedGroups(o: Option[]) { - // Deselect the app if a user is selecting from a list of groups - // for the first time. - if (selectedGroups.length === 0 && addedResources.app[agent.name]) { - addOrRemoveResource('app', agent.name); // remove app from selection. - } - - setSelectedGroups(o); - } - - function toggleUserGroup(id: string, description = '') { - addOrRemoveResource('user_group', id, description); - } - - function toggleApp() { - addOrRemoveResource('app', agent.name, agent.friendlyName); - } - - const isAppAdded = Boolean(addedResources.app[agent.name]); - const hasSelectedGroups = selectedGroups.length > 0; - - if (!isAppAdded && !hasSelectedGroups) { - return ( - - - + Add to request - - - ); - } - - if (isAppAdded && agent.userGroups.length === 0) { - return ( - - - Remove - - - ); - } - - // Remove button is only shown when user has not added user - // groups yet, but has the option to do so - const showRemoveButton = isAppAdded && !hasSelectedGroups; - - return ( - - {showRemoveButton && ( - - Remove - - )} - - - This application {agent.name} can be alternatively requested by - members of user groups. You can alternatively select user groups - instead to access this application. - - - - - ); -} - -const StyledSelect = styled(Select)` - margin-left: 8px; - - input[type='checkbox'] { - cursor: pointer; - } - - .react-select__control { - width: 260px; - } - - .react-select__option { - padding: 0; - } - - .react-select__value-container { - position: static; - } - - &.hasSelectedGroups { - .react-select__control { - background: ${p => p.theme.colors.interactive.solid.primary.default}; - border: transparent; - } - - .react-select__placeholder, - .react-select__dropdown-indicator { - color: ${p => p.theme.colors.text.primaryInverse}; - } - } -`; diff --git a/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Databases.tsx b/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Databases.tsx deleted file mode 100644 index 3f6f1e69da38c..0000000000000 --- a/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Databases.tsx +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Teleport - * Copyright (C) 2024 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import React from 'react'; -import { ClickableLabelCell } from 'design/DataTable'; -import { Database } from 'teleport/services/databases'; - -import { ListProps, StyledTable, renderActionCell } from './ResourceList'; - -export function Databases(props: ListProps & { databases: Database[] }) { - const { - databases = [], - onLabelClick, - addedResources, - addOrRemoveResource, - requestStarted, - customSort, - } = props; - - return ( - ( - - ), - }, - { - altKey: 'action-btn', - render: agent => - renderActionCell( - Boolean(addedResources.db[agent.name]), - requestStarted, - () => addOrRemoveResource('db', agent.name) - ), - }, - ]} - emptyText="No Results Found" - customSort={customSort} - disableFilter - /> - ); -} diff --git a/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Desktops.tsx b/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Desktops.tsx deleted file mode 100644 index 7dcde05b2b33d..0000000000000 --- a/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Desktops.tsx +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Teleport - * Copyright (C) 2024 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import React from 'react'; -import { ClickableLabelCell } from 'design/DataTable'; -import { Desktop } from 'teleport/services/desktops'; - -import { ListProps, StyledTable, renderActionCell } from './ResourceList'; - -export function Desktops(props: ListProps & { desktops: Desktop[] }) { - const { - desktops = [], - addedResources, - customSort, - onLabelClick, - requestStarted, - addOrRemoveResource, - } = props; - - return ( - ( - - ), - }, - { - altKey: 'action-btn', - render: agent => - renderActionCell( - Boolean(addedResources.windows_desktop[agent.name]), - requestStarted, - () => addOrRemoveResource('windows_desktop', agent.name) - ), - }, - ]} - emptyText="No Results Found" - customSort={customSort} - disableFilter - /> - ); -} diff --git a/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Kubes.tsx b/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Kubes.tsx deleted file mode 100644 index b6e79ed45329a..0000000000000 --- a/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Kubes.tsx +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Teleport - * Copyright (C) 2024 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import React from 'react'; -import { ClickableLabelCell } from 'design/DataTable'; -import { Kube } from 'teleport/services/kube'; - -import { ListProps, StyledTable, renderActionCell } from './ResourceList'; - -export function Kubes(props: ListProps & { kubes: Kube[] }) { - const { - kubes = [], - addedResources, - requestStarted, - customSort, - onLabelClick, - addOrRemoveResource, - } = props; - - return ( - ( - - ), - }, - { - altKey: 'action-btn', - render: agent => - renderActionCell( - Boolean(addedResources.kube_cluster[agent.name]), - requestStarted, - () => addOrRemoveResource('kube_cluster', agent.name) - ), - }, - ]} - emptyText="No Results Found" - customSort={customSort} - disableFilter - /> - ); -} diff --git a/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Nodes.tsx b/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Nodes.tsx deleted file mode 100644 index dfcb2021445ab..0000000000000 --- a/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/Nodes.tsx +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Teleport - * Copyright (C) 2024 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import React from 'react'; -import { Cell, ClickableLabelCell } from 'design/DataTable'; -import { Node } from 'teleport/services/nodes'; - -import { ListProps, StyledTable, renderActionCell } from './ResourceList'; - -export function Nodes(props: ListProps & { nodes: Node[] }) { - const { - nodes = [], - addedResources, - customSort, - onLabelClick, - requestStarted, - addOrRemoveResource, - } = props; - - return ( - ( - - ), - }, - { - altKey: 'action-btn', - render: agent => - renderActionCell( - Boolean(addedResources.node[agent.id]), - requestStarted, - () => addOrRemoveResource('node', agent.id, agent.hostname) - ), - }, - ]} - emptyText="No Results Found" - customSort={customSort} - disableFilter - /> - ); -} - -export const renderAddressCell = ({ addr, tunnel }: Node) => ( - {tunnel ? renderTunnel() : addr} -); - -function renderTunnel() { - return ( - - ← tunnel - - ); -} diff --git a/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/ResourceList.story.tsx b/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/ResourceList.story.tsx deleted file mode 100644 index 98c538c03ca27..0000000000000 --- a/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/ResourceList.story.tsx +++ /dev/null @@ -1,231 +0,0 @@ -/** - * Teleport - * Copyright (C) 2024 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import React from 'react'; - -import { Desktop } from 'teleport/services/desktops'; -import { Database } from 'teleport/services/databases'; -import { App } from 'teleport/services/apps'; -import { Kube } from 'teleport/services/kube'; -import { Node } from 'teleport/services/nodes'; -import { UserGroup } from 'teleport/services/userGroups'; - -import { getEmptyResourceState } from '../resource'; - -import { ResourceList, ResourceListProps } from './ResourceList'; - -export default { - title: 'Shared/AccessRequests/ResourceList', -}; - -export const Apps = () => ( - -); - -export const Databases = () => ( - -); - -export const Desktops = () => ( - -); - -export const Kubes = () => ( - -); - -export const Nodes = () => ( - -); - -export const Roles = () => ( - -); - -export const UserGroups = () => ( - -); - -export const SamlApps = () => ; - -const props: ResourceListProps = { - agents: [], - selectedResource: 'app', - customSort: { dir: 'ASC', fieldName: '', onSort: () => null }, - requestStarted: false, - onLabelClick: () => null, - addedResources: getEmptyResourceState(), - addOrRemoveResource: () => null, - requestableRoles: [], - disableRows: false, -}; - -const apps: App[] = [ - { - name: 'aws-console-1', - kind: 'app', - uri: 'https://console.aws.amazon.com/ec2/v2/home', - publicAddr: 'awsconsole-1.teleport-proxy.com', - addrWithProtocol: 'https://awsconsole-1.teleport-proxy.com', - labels: [ - { - name: 'aws_account_id', - value: 'A1234', - }, - ], - description: 'This is an AWS Console app', - awsConsole: true, - samlApp: false, - awsRoles: [], - clusterId: 'one', - fqdn: 'awsconsole-1.com', - id: 'one-aws-console-1-awsconsole-1.teleport-proxy.com', - launchUrl: '', - userGroups: [], - }, - { - name: 'aws-console-2', - kind: 'app', - uri: 'https://console.aws.amazon.com/ec2/v2/home', - publicAddr: 'awsconsole-2.teleport-proxy.com', - addrWithProtocol: 'https://awsconsole-2.teleport-proxy.com', - labels: [ - { - name: 'aws_account_id', - value: 'A1235', - }, - ], - description: 'This is another AWS Console app', - awsConsole: true, - samlApp: false, - awsRoles: [], - clusterId: 'one', - fqdn: 'awsconsole-2.com', - id: 'one-aws-console-2-awsconsole-2.teleport-proxy.com', - launchUrl: '', - userGroups: [ - { name: 'admins', description: 'Admins' }, - { name: 'users', description: 'Regular users' }, - ], - }, -]; - -const nodes: Node[] = [ - { - tunnel: false, - kind: 'node', - subKind: 'teleport', - sshLogins: ['dev', 'root'], - id: '104', - clusterId: 'one', - hostname: 'fujedu', - addr: '172.10.1.20:3022', - labels: [ - { - name: 'cluster', - value: 'one', - }, - ], - }, -]; - -const dbs: Database[] = [ - { - name: 'aurora', - kind: 'db', - description: 'PostgreSQL 11.6: AWS Aurora ', - hostname: 'aurora-hostname', - type: 'RDS PostgreSQL', - protocol: 'postgres', - labels: [{ name: 'cluster', value: 'root' }], - }, -]; - -const desktops: Desktop[] = [ - { - os: 'windows', - kind: 'windows_desktop', - name: 'bb8411a4-ba50-537c-89b3-226a00447bc6', - addr: 'host.com', - labels: [{ name: 'foo', value: 'bar' }], - logins: ['Administrator'], - }, -]; - -const kubes: Kube[] = [ - { - name: 'tele.logicoma.dev-prod', - kind: 'kube_cluster', - labels: [{ name: 'env', value: 'prod' }], - }, -]; - -const userGroups: UserGroup[] = [ - { - kind: 'user_group', - name: 'group id 1', - description: 'user group', - labels: [{ name: 'env', value: 'prod' }], - }, - { - kind: 'user_group', - name: 'group id 2', - description: 'admin group', - labels: [{ name: 'env', value: 'dev' }], - }, -]; - -const samlApp: App[] = [ - { - name: 'app_saml', - kind: 'app', - uri: 'https://example.com/saml', - publicAddr: 'example.com', - addrWithProtocol: 'https://example.com/saml', - labels: [ - { - name: 'env', - value: 'dev', - }, - ], - description: 'This is a SAML app', - awsConsole: false, - samlApp: true, - awsRoles: [], - clusterId: 'one', - fqdn: 'example.com', - id: 'example.com/saml', - launchUrl: '', - userGroups: [], - }, -]; diff --git a/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/ResourceList.tsx b/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/ResourceList.tsx deleted file mode 100644 index 2981f1175ebd3..0000000000000 --- a/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/ResourceList.tsx +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Teleport - * Copyright (C) 2024 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import React from 'react'; -import styled from 'styled-components'; -import { ButtonBorder, ButtonPrimary, Box } from 'design'; -import Table, { Cell } from 'design/DataTable'; -import { Desktop } from 'teleport/services/desktops'; -import { Database } from 'teleport/services/databases'; -import { App } from 'teleport/services/apps'; -import { Kube } from 'teleport/services/kube'; -import { Node } from 'teleport/services/nodes'; -import { UserGroup } from 'teleport/services/userGroups'; -import { CustomSort } from 'design/DataTable/types'; - -import { ResourceLabel, UnifiedResource } from 'teleport/services/agents'; - -import { ResourceMap, RequestableResourceKind } from '../resource'; - -import { Apps } from './Apps'; -import { Databases } from './Databases'; -import { Nodes } from './Nodes'; -import { Desktops } from './Desktops'; -import { Kubes } from './Kubes'; -import { Roles } from './Roles'; -import { UserGroups } from './UserGroups'; - -export function ResourceList(props: ResourceListProps) { - const { - agents, - disableRows, - selectedResource, - requestableRoles, - ...listProps - } = props; - - return ( - - {selectedResource === 'app' && ( - - )} - {selectedResource === 'db' && ( - - )} - {selectedResource === 'node' && ( - - )} - {selectedResource === 'windows_desktop' && ( - - )} - {selectedResource === 'kube_cluster' && ( - - )} - {selectedResource === 'role' && ( - - )} - {selectedResource === 'user_group' && ( - - )} - - ); -} - -export const StyledTable = styled(Table)` - & > tbody > tr > td { - vertical-align: middle; - } -` as typeof Table; - -const Wrapper = styled(Box)` - &.disabled { - pointer-events: none; - opacity: 0.5; - } -`; - -export function renderActionCell( - isAgentAdded: boolean, - requestStarted: boolean, - toggleAgent: () => void -) { - const text = requestStarted ? '+ Add to request' : '+ Request Access'; - return ( - - {isAgentAdded ? ( - - Remove - - ) : ( - - {text} - - )} - - ); -} - -export type ListProps = { - customSort: CustomSort; - requestStarted: boolean; - onLabelClick: (label: ResourceLabel) => void; - addedResources: ResourceMap; - addOrRemoveResource: ( - kind: RequestableResourceKind, - resourceId: string, - resourceName?: string - ) => void; - requestableRoles?: string[]; -}; - -export type ResourceListProps = { - agents: UnifiedResource[]; - selectedResource: RequestableResourceKind; - // disableRows disable clicking on any buttons (when fetching). - disableRows: boolean; -} & ListProps; diff --git a/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/UserGroups.tsx b/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/UserGroups.tsx deleted file mode 100644 index e96e396127543..0000000000000 --- a/web/packages/shared/components/AccessRequests/NewRequest/ResourceList/UserGroups.tsx +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Teleport - * Copyright (C) 2024 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import React from 'react'; -import { ClickableLabelCell } from 'design/DataTable'; -import { UserGroup } from 'teleport/services/userGroups'; - -import { ListProps, StyledTable, renderActionCell } from './ResourceList'; - -export function UserGroups(props: ListProps & { userGroups: UserGroup[] }) { - const { - userGroups = [], - addedResources, - customSort, - requestStarted, - onLabelClick, - addOrRemoveResource, - } = props; - - return ( - {friendlyName || name}, - }, - { - key: 'description', - headerText: 'Description', - isSortable: true, - }, - { - key: 'labels', - headerText: 'Labels', - render: ({ labels }) => ( - - ), - }, - { - altKey: 'action-btn', - render: agent => - renderActionCell( - Boolean(addedResources.user_group[agent.name]), - requestStarted, - () => - addOrRemoveResource( - 'user_group', - agent.name, - agent.friendlyName - ) - ), - }, - ]} - emptyText="No Results Found" - customSort={customSort} - disableFilter - /> - ); -}