-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
28 changed files
with
817 additions
and
158 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import PropTypes from 'prop-types'; | ||
|
||
import { | ||
Avatar, Card, Col, Row, | ||
} from '@openedx/paragon'; | ||
|
||
const OrgMemberCard = ({ original }) => { | ||
const { enterpriseCustomerUser, enrollments } = original; | ||
const { name, joinedOrg, email } = enterpriseCustomerUser; | ||
|
||
return ( | ||
<Card orientation="horizontal"> | ||
<Card.Body> | ||
<Card.Section className="pb-1"> | ||
<Row className="d-flex flex-row"> | ||
<Col xs={2}> | ||
<Avatar size="lg" /> | ||
</Col> | ||
<Col> | ||
<Row> | ||
<h3 className="pt-2">{name}</h3> | ||
</Row> | ||
<Row> | ||
<p>{email}</p> | ||
</Row> | ||
</Col> | ||
<Col> | ||
<h5 className="pt-2 text-uppercase">Joined org</h5> | ||
{joinedOrg} | ||
</Col> | ||
<Col> | ||
<h5 className="pt-2 text-uppercase">Enrollments</h5> | ||
{enrollments} | ||
</Col> | ||
</Row> | ||
</Card.Section> | ||
</Card.Body> | ||
</Card> | ||
); | ||
}; | ||
|
||
OrgMemberCard.propTypes = { | ||
original: PropTypes.shape({ | ||
enterpriseCustomerUser: PropTypes.shape({ | ||
email: PropTypes.string.isRequired, | ||
name: PropTypes.string.isRequired, | ||
joinedOrg: PropTypes.string.isRequired, | ||
}), | ||
enrollments: PropTypes.number.isRequired, | ||
}), | ||
}; | ||
|
||
export default OrgMemberCard; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import React from 'react'; | ||
import { CardView, DataTable } from '@openedx/paragon'; | ||
import { connect } from 'react-redux'; | ||
import PropTypes from 'prop-types'; | ||
|
||
import TableTextFilter from '../learner-credit-management/TableTextFilter'; | ||
import CustomDataTableEmptyState from '../learner-credit-management/CustomDataTableEmptyState'; | ||
import OrgMemberCard from './OrgMemberCard'; | ||
import useEnterpriseMembersTableData from './data/hooks/useEnterpriseMembersTableData'; | ||
|
||
const FilterStatus = (rest) => <DataTable.FilterStatus showFilteredFields={false} {...rest} />; | ||
|
||
const PeopleManagementTable = ({ enterpriseId }) => { | ||
const { | ||
isLoading: isTableLoading, | ||
enterpriseMembersTableData, | ||
fetchEnterpriseMembersTableData, | ||
} = useEnterpriseMembersTableData({ enterpriseId }); | ||
|
||
const tableColumns = [{ Header: 'Name', accessor: 'name' }]; | ||
|
||
return ( | ||
<DataTable | ||
isSortable | ||
manualSortBy | ||
isPaginated | ||
manualPagination | ||
isFilterable | ||
manualFilters | ||
isLoading={isTableLoading} | ||
defaultColumnValues={{ Filter: TableTextFilter }} | ||
FilterStatusComponent={FilterStatus} | ||
numBreakoutFilters={2} | ||
columns={tableColumns} | ||
initialState={{ | ||
pageSize: 10, | ||
pageIndex: 0, | ||
sortBy: [ | ||
{ id: 'enterpriseCustomerUser.name', desc: true }, | ||
], | ||
filters: [], | ||
}} | ||
fetchData={fetchEnterpriseMembersTableData} | ||
data={enterpriseMembersTableData.results} | ||
itemCount={enterpriseMembersTableData.itemCount} | ||
pageCount={enterpriseMembersTableData.pageCount} | ||
EmptyTableComponent={CustomDataTableEmptyState} | ||
> | ||
<DataTable.TableControlBar /> | ||
<CardView | ||
className="d-block" | ||
CardComponent={OrgMemberCard} | ||
columnSizes={{ xs: 12 }} | ||
/> | ||
<DataTable.TableFooter /> | ||
</DataTable> | ||
); | ||
}; | ||
|
||
PeopleManagementTable.propTypes = { | ||
enterpriseId: PropTypes.string.isRequired, | ||
}; | ||
|
||
const mapStateToProps = state => ({ | ||
enterpriseId: state.portalConfiguration.enterpriseId, | ||
}); | ||
|
||
export default connect(mapStateToProps)(PeopleManagementTable); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
export { default as useEnterpriseGroupUuid } from './useEnterpriseGroupUuid'; | ||
export { default as useEnterpriseGroupLearnersTableData } from './useEnterpriseGroupLearnersTableData'; | ||
export { default as useEnterpriseMembersTableData } from './useEnterpriseMembersTableData'; | ||
export { default as useAllEnterpriseGroupLearners } from './useAllEnterpriseGroupLearners'; |
2 changes: 1 addition & 1 deletion
2
...ment/data/hooks/useEnterpriseGroupUuid.js → ...ment/data/hooks/useEnterpriseGroupUuid.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
src/components/PeopleManagement/data/hooks/useEnterpriseMembersTableData.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { | ||
useCallback, useMemo, useState, | ||
} from 'react'; | ||
import { camelCaseObject } from '@edx/frontend-platform/utils'; | ||
import { logError } from '@edx/frontend-platform/logging'; | ||
import debounce from 'lodash.debounce'; | ||
|
||
import LmsApiService from '../../../../data/services/LmsApiService'; | ||
|
||
const useEnterpriseMembersTableData = ({ enterpriseId }) => { | ||
const [isLoading, setIsLoading] = useState(true); | ||
const [enterpriseMembersTableData, setEnterpriseMembersTableData] = useState({ | ||
itemCount: 0, | ||
pageCount: 0, | ||
results: [], | ||
}); | ||
const fetchEnterpriseMembersData = useCallback((args) => { | ||
const fetch = async () => { | ||
try { | ||
setIsLoading(true); | ||
const options = {}; | ||
args.filters.forEach((filter) => { | ||
const { id, value } = filter; | ||
if (id === 'name') { | ||
options.user_query = value; | ||
} | ||
}); | ||
|
||
options.page = args.pageIndex + 1; | ||
const response = await LmsApiService.fetchEnterpriseCustomerMembers(enterpriseId, options); | ||
const data = camelCaseObject(response.data); | ||
setEnterpriseMembersTableData({ | ||
itemCount: data.count, | ||
pageCount: data.numPages ?? Math.floor(data.count / options.pageSize), | ||
results: data.results, | ||
}); | ||
} catch (error) { | ||
logError(error); | ||
} finally { | ||
setIsLoading(false); | ||
} | ||
}; | ||
if (args.filters.length && args.filters[0].value.length > 2) { | ||
fetch(); | ||
} else if (!args.filters.length) { | ||
fetch(); | ||
} | ||
}, [enterpriseId]); | ||
|
||
const debouncedFetchEnterpriseMembersData = useMemo( | ||
() => debounce(fetchEnterpriseMembersData, 300), | ||
[fetchEnterpriseMembersData], | ||
); | ||
|
||
return { | ||
isLoading, | ||
enterpriseMembersTableData, | ||
fetchEnterpriseMembersTableData: debouncedFetchEnterpriseMembersData, | ||
}; | ||
}; | ||
|
||
export default useEnterpriseMembersTableData; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
...EnterpriseGroupLearnersTableData.test.jsx → ...EnterpriseGroupLearnersTableData.test.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
src/components/PeopleManagement/tests/useEnterpriseMembersTableData.test.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { renderHook } from '@testing-library/react-hooks'; | ||
import { camelCaseObject } from '@edx/frontend-platform/utils'; | ||
import LmsApiService from '../../../data/services/LmsApiService'; | ||
|
||
import useEnterpriseMembersTableData from '../data/hooks/useEnterpriseMembersTableData'; | ||
|
||
describe('useEnterpriseMembersTableData', () => { | ||
it('should fetch and return members of an enterprise', async () => { | ||
const mockEnterpriseUUID = 'uuid-bb'; | ||
const mockData = { | ||
count: 1, | ||
current_page: 1, | ||
next: null, | ||
num_pages: 1, | ||
previous: null, | ||
results: [{ | ||
enterprise_customer_user: { | ||
email: '[email protected]', | ||
joinedOrg: 'Sep 15, 2021', | ||
name: 'Jeez Louise', | ||
}, | ||
enrollments: 11, | ||
}], | ||
}; | ||
const mockEnterpriseMembers = jest.spyOn(LmsApiService, 'fetchEnterpriseCustomerMembers'); | ||
mockEnterpriseMembers.mockResolvedValue({ data: mockData }); | ||
|
||
const { result, waitForNextUpdate } = renderHook( | ||
() => useEnterpriseMembersTableData({ enterpriseId: mockEnterpriseUUID }), | ||
); | ||
result.current.fetchEnterpriseMembersTableData({ | ||
pageIndex: 0, | ||
pageSize: 10, | ||
filters: [], | ||
sortBy: [], | ||
}); | ||
await waitForNextUpdate(); | ||
expect(LmsApiService.fetchEnterpriseCustomerMembers).toHaveBeenCalledWith(mockEnterpriseUUID, { page: 1 }); | ||
expect(result.current.isLoading).toEqual(false); | ||
expect(result.current.enterpriseMembersTableData.results).toEqual(camelCaseObject(mockData.results)); | ||
}); | ||
}); |
Oops, something went wrong.