diff --git a/awx/ui_next/src/screens/Organization/OrganizationTeams/OrganizationTeams.jsx b/awx/ui_next/src/screens/Organization/OrganizationTeams/OrganizationTeamList.jsx
similarity index 82%
rename from awx/ui_next/src/screens/Organization/OrganizationTeams/OrganizationTeams.jsx
rename to awx/ui_next/src/screens/Organization/OrganizationTeams/OrganizationTeamList.jsx
index 70965ad1da..76638e2bb6 100644
--- a/awx/ui_next/src/screens/Organization/OrganizationTeams/OrganizationTeams.jsx
+++ b/awx/ui_next/src/screens/Organization/OrganizationTeams/OrganizationTeamList.jsx
@@ -6,6 +6,7 @@ import { t } from '@lingui/macro';
import { OrganizationsAPI } from '../../../api';
import PaginatedDataList from '../../../components/PaginatedDataList';
import { getQSConfig, parseQueryString } from '../../../util/qs';
+import OrganizationTeamListItem from './OrganizationTeamListItem';
const QS_CONFIG = getQSConfig('team', {
page: 1,
@@ -13,7 +14,7 @@ const QS_CONFIG = getQSConfig('team', {
order_by: 'name',
});
-function OrganizationTeams({ id, i18n }) {
+function OrganizationTeamList({ id, i18n }) {
const location = useLocation();
const [contentError, setContentError] = useState(null);
const [hasContentLoading, setHasContentLoading] = useState(false);
@@ -70,13 +71,21 @@ function OrganizationTeams({ id, i18n }) {
key: 'name',
},
]}
+ renderItem={item => (
+
+ )}
/>
);
}
-OrganizationTeams.propTypes = {
+OrganizationTeamList.propTypes = {
id: PropTypes.number.isRequired,
};
-export { OrganizationTeams as _OrganizationTeams };
-export default withI18n()(OrganizationTeams);
+export { OrganizationTeamList as _OrganizationTeamList };
+export default withI18n()(OrganizationTeamList);
diff --git a/awx/ui_next/src/screens/Organization/OrganizationTeams/OrganizationTeams.test.jsx b/awx/ui_next/src/screens/Organization/OrganizationTeams/OrganizationTeamList.test.jsx
similarity index 62%
rename from awx/ui_next/src/screens/Organization/OrganizationTeams/OrganizationTeams.test.jsx
rename to awx/ui_next/src/screens/Organization/OrganizationTeams/OrganizationTeamList.test.jsx
index c21ec13622..f7c61d8ac4 100644
--- a/awx/ui_next/src/screens/Organization/OrganizationTeams/OrganizationTeams.test.jsx
+++ b/awx/ui_next/src/screens/Organization/OrganizationTeams/OrganizationTeamList.test.jsx
@@ -8,7 +8,7 @@ import {
} from '../../../../testUtils/enzymeHelpers';
import { sleep } from '../../../../testUtils/testUtils';
-import OrganizationTeams from './OrganizationTeams';
+import OrganizationTeamList from './OrganizationTeamList';
jest.mock('../../../api');
@@ -16,16 +16,41 @@ const listData = {
data: {
count: 7,
results: [
- { id: 1, name: 'one', url: '/org/team/1' },
- { id: 2, name: 'two', url: '/org/team/2' },
- { id: 3, name: 'three', url: '/org/team/3' },
- { id: 4, name: 'four', url: '/org/team/4' },
- { id: 5, name: 'five', url: '/org/team/5' },
+ {
+ id: 1,
+ name: 'one',
+ url: '/org/team/1',
+ summary_fields: { user_capabilities: { edit: true, delete: true } },
+ },
+ {
+ id: 2,
+ name: 'two',
+ url: '/org/team/2',
+ summary_fields: { user_capabilities: { edit: true, delete: true } },
+ },
+ {
+ id: 3,
+ name: 'three',
+ url: '/org/team/3',
+ summary_fields: { user_capabilities: { edit: true, delete: true } },
+ },
+ {
+ id: 4,
+ name: 'four',
+ url: '/org/team/4',
+ summary_fields: { user_capabilities: { edit: true, delete: true } },
+ },
+ {
+ id: 5,
+ name: 'five',
+ url: '/org/team/5',
+ summary_fields: { user_capabilities: { edit: true, delete: true } },
+ },
],
},
};
-describe('', () => {
+describe('', () => {
beforeEach(() => {
OrganizationsAPI.readTeams.mockResolvedValue(listData);
});
@@ -37,7 +62,7 @@ describe('', () => {
test('renders succesfully', async () => {
await act(async () => {
mountWithContexts(
- ', () => {
test('should load teams on mount', async () => {
await act(async () => {
- mountWithContexts().find(
- 'OrganizationTeams'
+ mountWithContexts().find(
+ 'OrganizationTeamList'
);
});
expect(OrganizationsAPI.readTeams).toHaveBeenCalledWith(1, {
@@ -62,7 +87,9 @@ describe('', () => {
test('should pass fetched teams to PaginatedDatalist', async () => {
let wrapper;
await act(async () => {
- wrapper = mountWithContexts();
+ wrapper = mountWithContexts(
+
+ );
});
await sleep(0);
wrapper.update();
@@ -90,7 +117,7 @@ describe('', () => {
);
let wrapper;
await act(async () => {
- wrapper = mountWithContexts();
+ wrapper = mountWithContexts();
});
await waitForElement(wrapper, 'ContentError', el => el.length === 1);
});
diff --git a/awx/ui_next/src/screens/Organization/OrganizationTeams/OrganizationTeamListItem.jsx b/awx/ui_next/src/screens/Organization/OrganizationTeams/OrganizationTeamListItem.jsx
new file mode 100644
index 0000000000..b352e3dda9
--- /dev/null
+++ b/awx/ui_next/src/screens/Organization/OrganizationTeams/OrganizationTeamListItem.jsx
@@ -0,0 +1,64 @@
+import React from 'react';
+import { Link } from 'react-router-dom';
+import PropTypes from 'prop-types';
+import {
+ Button,
+ DataListAction,
+ DataListItem,
+ DataListItemRow,
+ DataListItemCells,
+ Tooltip,
+} from '@patternfly/react-core';
+import { t } from '@lingui/macro';
+import { withI18n } from '@lingui/react';
+import { PencilAltIcon } from '@patternfly/react-icons';
+import DataListCell from '../../../components/DataListCell';
+
+function OrganizationTeamListItem({ i18n, team, detailUrl }) {
+ const labelId = `check-action-${team.id}`;
+
+ return (
+
+
+
+
+
+ {team.name}
+
+
+ ,
+ ]}
+ />
+
+ {team.summary_fields.user_capabilities.edit && (
+
+
+
+ )}
+
+
+
+ );
+}
+
+OrganizationTeamListItem.propTypes = {
+ team: PropTypes.shape({ id: PropTypes.number, name: PropTypes.string })
+ .isRequired,
+ detailUrl: PropTypes.string.isRequired,
+};
+
+export default withI18n()(OrganizationTeamListItem);
diff --git a/awx/ui_next/src/screens/Organization/OrganizationTeams/OrgnizationTeamListItem.test.jsx b/awx/ui_next/src/screens/Organization/OrganizationTeams/OrgnizationTeamListItem.test.jsx
new file mode 100644
index 0000000000..8758ebf946
--- /dev/null
+++ b/awx/ui_next/src/screens/Organization/OrganizationTeams/OrgnizationTeamListItem.test.jsx
@@ -0,0 +1,45 @@
+import React from 'react';
+import { act } from 'react-dom/test-utils';
+
+import { mountWithContexts } from '../../../../testUtils/enzymeHelpers';
+
+import OrganizationTeamListItem from './OrganizationTeamListItem';
+
+const team = {
+ id: 1,
+ name: 'one',
+ url: '/org/team/1',
+ summary_fields: { user_capabilities: { edit: true, delete: true } },
+};
+
+describe('', () => {
+ let wrapper;
+ test('should mount properly', async () => {
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ );
+ });
+ expect(wrapper.find('OrganizationTeamListItem').length).toBe(1);
+ });
+
+ test('should render proper data', async () => {
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ );
+ });
+ expect(wrapper.find(`b[aria-label="team name"]`).text()).toBe('one');
+ expect(wrapper.find('PencilAltIcon').length).toBe(1);
+ });
+
+ test('should not render edit button', async () => {
+ team.summary_fields.user_capabilities.edit = false;
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ );
+ });
+ expect(wrapper.find('PencilAltIcon').length).toBe(0);
+ });
+});
diff --git a/awx/ui_next/src/screens/Organization/OrganizationTeams/index.js b/awx/ui_next/src/screens/Organization/OrganizationTeams/index.js
index eb8b71f016..de8b47e407 100644
--- a/awx/ui_next/src/screens/Organization/OrganizationTeams/index.js
+++ b/awx/ui_next/src/screens/Organization/OrganizationTeams/index.js
@@ -1 +1 @@
-export { default } from './OrganizationTeams';
+export { default } from './OrganizationTeamList';