diff --git a/awx/ui_next/src/api/models/Users.js b/awx/ui_next/src/api/models/Users.js index a76c4e49b7..e15908270b 100644 --- a/awx/ui_next/src/api/models/Users.js +++ b/awx/ui_next/src/api/models/Users.js @@ -7,7 +7,9 @@ class Users extends Base { } associateRole(userId, roleId) { - return this.http.post(`${this.baseUrl}${userId}/roles/`, { id: roleId }); + return this.http.post(`${this.baseUrl}${userId}/roles/`, { + id: roleId, + }); } disassociateRole(userId, roleId) { @@ -16,6 +18,12 @@ class Users extends Base { disassociate: true, }); } + + readOrganizations(userId, params) { + return this.http.get(`${this.baseUrl}${userId}/organizations/`, { + params, + }); + } } export default Users; diff --git a/awx/ui_next/src/screens/User/User.jsx b/awx/ui_next/src/screens/User/User.jsx index 5eb0e633a4..e7bc917729 100644 --- a/awx/ui_next/src/screens/User/User.jsx +++ b/awx/ui_next/src/screens/User/User.jsx @@ -9,7 +9,7 @@ import RoutedTabs from '@components/RoutedTabs'; import ContentError from '@components/ContentError'; import UserDetail from './UserDetail'; import UserEdit from './UserEdit'; -import UserOrganizations from './UserOrganizations'; +import UserOrganizationList from './UserOrganizationList'; import UserTeams from './UserTeams'; import UserTokens from './UserTokens'; import { UsersAPI } from '@api'; @@ -130,10 +130,9 @@ class User extends Component { render={() => } /> )} - } - /> + + + } diff --git a/awx/ui_next/src/screens/User/UserOrganizationList/UserOrganizationList.jsx b/awx/ui_next/src/screens/User/UserOrganizationList/UserOrganizationList.jsx new file mode 100644 index 0000000000..042d90a32a --- /dev/null +++ b/awx/ui_next/src/screens/User/UserOrganizationList/UserOrganizationList.jsx @@ -0,0 +1,71 @@ +import React, { useCallback, useEffect } from 'react'; +import { withI18n } from '@lingui/react'; +import { useLocation, useParams } from 'react-router-dom'; +import { t } from '@lingui/macro'; + +import PaginatedDataList from '@components/PaginatedDataList'; +import useRequest from '@util/useRequest'; +import { UsersAPI } from '@api'; +import { getQSConfig, parseQueryString } from '@util/qs'; +import UserOrganizationListItem from '../UserOrganizationListItem'; + +const QS_CONFIG = getQSConfig('organizations', { + page: 1, + page_size: 20, + order_by: 'name', + type: 'organization', +}); + +function UserOrganizationList({ i18n }) { + const location = useLocation(); + const { id: userId } = useParams(); + + const { + result: { organizations, count }, + error: contentError, + isLoading, + request: fetchOrgs, + } = useRequest( + useCallback(async () => { + const params = parseQueryString(QS_CONFIG, location.search); + const { + data: { results, count: orgCount }, + } = await UsersAPI.readOrganizations(userId, params); + return { + organizations: results, + count: orgCount, + }; + }, [userId, location.search]), + { + organizations: [], + count: 0, + } + ); + + useEffect(() => { + fetchOrgs(); + }, [fetchOrgs]); + + return ( + ( + {}} + isSelected={false} + /> + )} + /> + ); +} + +export default withI18n()(UserOrganizationList); diff --git a/awx/ui_next/src/screens/User/UserOrganizationList/index.js b/awx/ui_next/src/screens/User/UserOrganizationList/index.js new file mode 100644 index 0000000000..e02c2b87cc --- /dev/null +++ b/awx/ui_next/src/screens/User/UserOrganizationList/index.js @@ -0,0 +1 @@ +export { default } from './UserOrganizationList'; diff --git a/awx/ui_next/src/screens/User/UserOrganizationListItem/UserOrganizationListItem.jsx b/awx/ui_next/src/screens/User/UserOrganizationListItem/UserOrganizationListItem.jsx new file mode 100644 index 0000000000..a5a6e226af --- /dev/null +++ b/awx/ui_next/src/screens/User/UserOrganizationListItem/UserOrganizationListItem.jsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; +import { withI18n } from '@lingui/react'; +import { t } from '@lingui/macro'; +import { + DataList, + DataListItemCells, + DataListItemRow, + DataListItem, + DataListCell, +} from '@patternfly/react-core'; + +function UserOrganizationListItem({ organization, i18n }) { + return ( + + + + + + {organization.name} + + , + + {organization.description} + , + ]} + /> + + + + ); +} + +export default withI18n()(UserOrganizationListItem); diff --git a/awx/ui_next/src/screens/User/UserOrganizationListItem/index.js b/awx/ui_next/src/screens/User/UserOrganizationListItem/index.js new file mode 100644 index 0000000000..0c9f42e2a7 --- /dev/null +++ b/awx/ui_next/src/screens/User/UserOrganizationListItem/index.js @@ -0,0 +1 @@ +export { default } from './UserOrganizationListItem'; diff --git a/awx/ui_next/src/screens/User/UserOrganizations/UserOrganizations.jsx b/awx/ui_next/src/screens/User/UserOrganizations/UserOrganizations.jsx deleted file mode 100644 index aa97e30d80..0000000000 --- a/awx/ui_next/src/screens/User/UserOrganizations/UserOrganizations.jsx +++ /dev/null @@ -1,10 +0,0 @@ -import React, { Component } from 'react'; -import { CardBody } from '@components/Card'; - -class UserAdd extends Component { - render() { - return Coming soon :); - } -} - -export default UserAdd; diff --git a/awx/ui_next/src/screens/User/UserOrganizations/index.js b/awx/ui_next/src/screens/User/UserOrganizations/index.js deleted file mode 100644 index 7fa3e0744b..0000000000 --- a/awx/ui_next/src/screens/User/UserOrganizations/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './UserOrganizations';