Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Migrate deprecated Table to DataTable for CompletedLearnersTable #1303

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions src/components/Admin/CompletedLearnersTable.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React, { useMemo } from 'react';
import { useIntl } from '@edx/frontend-platform/i18n';
import { DataTable } from '@openedx/paragon';
import { useGenericTableData } from './data/hooks';
import EnterpriseDataApiService from '../../data/services/EnterpriseDataApiService';
import EmailCell from './EmailCell';

const CompletedLearnersTable = (enterpriseId) => {
const intl = useIntl();
const {
isLoading,
tableData,
fetchTableData,
} = useGenericTableData(
enterpriseId,
'completed-learners',
EnterpriseDataApiService.fetchCompletedLearners,
useMemo(() => ({
userEmail: { key: 'user_email' },
completedCourses: { key: 'completed_courses' },
}), []),
);

return (
<DataTable
isSortable
manualSortBy
isPaginated
manualPagination
isLoading={isLoading}
columns={[
{
Header: intl.formatMessage({
id: 'admin.portal.lpr.completed.learners.table.user_email.column.heading',
defaultMessage: 'Email',
description: 'Column heading for the user email column in the completed learners table',
}),
accessor: 'userEmail',
Cell: EmailCell,
},
{
Header: intl.formatMessage({
id: 'admin.portal.lpr.completed.learners.table.completed_courses.column.heading',
defaultMessage: 'Total Course Completed Count',
description: 'Column heading for the completed courses column in the completed learners table',
}),
accessor: 'completedCourses',
},
]}
initialState={{
pageIndex: 20,
pageSize: 0,
sortBy: [{ id: 'completedCourses', desc: true }],
selectedRowsOrdered: [],
}}
fetchData={fetchTableData}
data={tableData.results}
itemCount={tableData.itemCount}
pageCount={tableData.pageCount}
/>
);
};

export default CompletedLearnersTable;
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,20 @@ import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';

import CompletedLearnersTable from '.';
import CompletedLearnersTable from './CompletedLearnersTable';
import { useGenericTableData } from './data/hooks';

const mockStore = configureMockStore([thunk]);
const enterpriseId = 'test-enterprise';

jest.mock('./data/hooks/useGenericTableData', () => (
jest.fn().mockReturnValue({})
));

const store = mockStore({
portalConfiguration: {
enterpriseId,
},
table: {
'completed-learners': {
data: {
results: [],
current_page: 1,
num_pages: 1,
},
ordering: null,
loading: false,
error: null,
},
},
});

const CompletedLearnersWrapper = props => (
Expand All @@ -42,6 +36,15 @@ const CompletedLearnersWrapper = props => (

describe('CompletedLearnersTable', () => {
it('renders empty state correctly', () => {
useGenericTableData.mockReturnValue({
isLoading: false,
tableData: {
results: [],
itemCount: 0,
pageCount: 0,
},
fetchTableData: jest.fn(),
});
const tree = renderer
.create((
<CompletedLearnersWrapper />
Expand Down
16 changes: 16 additions & 0 deletions src/components/Admin/EmailCell.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import PropTypes from 'prop-types';

const EmailCell = ({ row }) => (
<span data-hj-suppress>{row.original.userEmail}</span>
);

EmailCell.propTypes = {
row: PropTypes.shape({
original: PropTypes.shape({
userEmail: PropTypes.string.isRequired,
}).isRequired,
}).isRequired,
};

export default EmailCell;
42 changes: 42 additions & 0 deletions src/components/Admin/EmailCell.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import EmailCell from './EmailCell';

describe('Email Component', () => {
it('should display the user email and suppress highlighting', () => {
const mockRow = {
original: {
userEmail: '[email protected]',
},
};

render(
<EmailCell row={mockRow} />,
);

// Assert that the email is rendered correctly
const emailElement = screen.getByText('[email protected]');
expect(emailElement).toBeInTheDocument();

// Assert that data-hj-suppress is present to suppress highlighting
expect(emailElement).toHaveAttribute('data-hj-suppress');
});

it('should throw a prop-type warning if the email is not provided', () => {
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {});

const invalidRow = {
original: {},
};

// Render with invalid props
render(<EmailCell row={invalidRow} />);

// Assert that a prop-types error has been logged
expect(consoleSpy).toHaveBeenCalled();

// Clean up the spy
consoleSpy.mockRestore();
});
});
Loading
Loading