diff --git a/src/components/GroupsTable/GroupsTable.js b/src/components/GroupsTable/GroupsTable.js index b5733dab4..1e03fde6c 100644 --- a/src/components/GroupsTable/GroupsTable.js +++ b/src/components/GroupsTable/GroupsTable.js @@ -26,7 +26,10 @@ import upperCase from 'lodash/upperCase'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { Link } from 'react-router-dom'; -import { TABLE_DEFAULT_PAGINATION } from '../../constants'; +import { + NO_MODIFY_GROUPS_TOOLTIP_MESSAGE, + TABLE_DEFAULT_PAGINATION, +} from '../../constants'; import { fetchGroups } from '../../store/inventory-actions'; import useFetchBatched from '../../Utilities/hooks/useFetchBatched'; import CreateGroupModal from '../InventoryGroups/Modals/CreateGroupModal'; @@ -426,8 +429,7 @@ const GroupsTable = () => { props: { isAriaDisabled: !canModify || selectedIds.length !== 1, ...(!canModify && { - tooltip: - 'You do not have the necessary permissions to modify groups. Contact your organization administrator.', + tooltip: NO_MODIFY_GROUPS_TOOLTIP_MESSAGE, }), }, }, @@ -437,8 +439,7 @@ const GroupsTable = () => { props: { isAriaDisabled: !canModify || selectedIds.length === 0, ...(!canModify && { - tooltip: - 'You do not have the necessary permissions to modify groups. Contact your organization administrator.', + tooltip: NO_MODIFY_GROUPS_TOOLTIP_MESSAGE, }), }, }, diff --git a/src/components/InventoryGroups/Modals/AddSelectedHostsToGroupModal.cy.js b/src/components/InventoryGroups/Modals/AddSelectedHostsToGroupModal.cy.js index 8dd7f4070..791c715f5 100644 --- a/src/components/InventoryGroups/Modals/AddSelectedHostsToGroupModal.cy.js +++ b/src/components/InventoryGroups/Modals/AddSelectedHostsToGroupModal.cy.js @@ -18,19 +18,50 @@ const mountModal = ( cy.mountWithContext(AddSelectedHostsToGroupModal, {}, props); }; -before(() => { - cy.mockWindowChrome(); -}); - describe('AddSelectedHostsToGroupModal', () => { - it('makes separate requests when searching groups', () => { - groupsInterceptors['successful with some items'](); - mountModal(); - - cy.wait('@getGroups'); // must make initial call - cy.get('input').type('abc'); - cy.wait('@getGroups').its('request.url').should('contain', '?name=abc'); - cy.get('input').type('d'); - cy.wait('@getGroups').its('request.url').should('contain', '?name=abcd'); + describe('without any permissions', () => { + before(() => { + cy.mockWindowChrome({ + userPermissions: [], + }); + }); + + beforeEach(() => { + groupsInterceptors['successful with some items'](); + mountModal(); + }); + + it('makes separate requests when searching groups', () => { + cy.wait('@getGroups'); // must make initial call + cy.get('input').type('abc'); + cy.wait('@getGroups').its('request.url').should('contain', '?name=abc'); + cy.get('input').type('d'); + cy.wait('@getGroups').its('request.url').should('contain', '?name=abcd'); + }); + + it('create group button is disabled', () => { + cy.get('button') + .contains('Create a new group') + .should('have.attr', 'aria-disabled', 'true'); + }); + }); + + describe('with groups write permission', () => { + before(() => { + cy.mockWindowChrome({ + userPermissions: ['inventory:groups:write'], + }); + }); + + beforeEach(() => { + groupsInterceptors['successful with some items'](); + mountModal(); + }); + + it('create group button is enabled', () => { + cy.get('button') + .contains('Create a new group') + .not('have.attr', 'aria-disabled', 'true'); + }); }); }); diff --git a/src/components/InventoryGroups/SmallComponents/CreateGroupButton.js b/src/components/InventoryGroups/SmallComponents/CreateGroupButton.js index dee264c9d..c5cf86ee1 100644 --- a/src/components/InventoryGroups/SmallComponents/CreateGroupButton.js +++ b/src/components/InventoryGroups/SmallComponents/CreateGroupButton.js @@ -1,15 +1,31 @@ import React from 'react'; -import { Button, Text } from '@patternfly/react-core'; +import { Button, Text, Tooltip } from '@patternfly/react-core'; import PropTypes from 'prop-types'; +import { usePermissionsWithContext } from '@redhat-cloud-services/frontend-components-utilities/RBACHook'; +import { NO_MODIFY_GROUPS_TOOLTIP_MESSAGE } from '../../../constants'; -export const CreateGroupButton = ({ closeModal }) => ( - <> - Or - - -); +export const CreateGroupButton = ({ closeModal }) => { + const { hasAccess: canModifyGroups } = usePermissionsWithContext([ + 'inventory:groups:write', + ]); + + return ( + <> + Or + {canModifyGroups ? ( + + ) : ( + + + + )} + + ); +}; CreateGroupButton.propTypes = { closeModal: PropTypes.func, diff --git a/src/constants.js b/src/constants.js index c6f0f760e..2686053a0 100644 --- a/src/constants.js +++ b/src/constants.js @@ -171,6 +171,9 @@ export const getSearchParams = () => { export const TABLE_DEFAULT_PAGINATION = 50; // from UX table audit +export const NO_MODIFY_GROUPS_TOOLTIP_MESSAGE = + 'You do not have the necessary permissions to modify groups. Contact your organization administrator.'; + export const REQUIRED_PERMISSIONS_TO_READ_GROUP = (groupId) => [ { permission: 'inventory:groups:read',