Skip to content

Commit

Permalink
feat: adding cancel and remind actions to the budget assignment table
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-sheehan-edx committed Oct 30, 2023
1 parent 8b12828 commit 6cf5b62
Show file tree
Hide file tree
Showing 2 changed files with 193 additions and 42 deletions.
170 changes: 128 additions & 42 deletions src/components/learner-credit-management/BudgetAssignmentsTable.jsx
Original file line number Diff line number Diff line change
@@ -1,58 +1,144 @@
import React from 'react';
import PropTypes from 'prop-types';
import { DataTable } from '@edx/paragon';

import {
Button,
DataTable,
Icon,
OverlayTrigger,
Tooltip,
} from '@edx/paragon';
import { Mail, DoNotDisturbOn } from '@edx/paragon/icons';
import TableTextFilter from './TableTextFilter';
import CustomDataTableEmptyState from './CustomDataTableEmptyState';
import AssignmentDetailsTableCell from './AssignmentDetailsTableCell';
import { DEFAULT_PAGE, PAGE_SIZE, formatPrice } from './data';

const FilterStatus = (rest) => <DataTable.FilterStatus showFilteredFields={false} {...rest} />;

const CancelAction = ({ selectedFlatRows, ...rest }) => (
// eslint-disable-next-line no-console
<Button variant="danger" onClick={() => console.log('Cancel', selectedFlatRows, rest)}>
{`Cancel (${selectedFlatRows.length})`}
</Button>
);

const RemindAction = ({ selectedFlatRows, ...rest }) => (
// eslint-disable-next-line no-console
<Button onClick={() => console.log('Remind', selectedFlatRows, rest)}>
{`Remind (${selectedFlatRows.length})`}
</Button>
);

const BudgetAssignmentsTable = ({
isLoading,
tableData,
fetchTableData,
}) => (
<DataTable
isSortable
manualSortBy
isPaginated
manualPagination
isFilterable
manualFilters
isLoading={isLoading}
defaultColumnValues={{ Filter: TableTextFilter }}
FilterStatusComponent={FilterStatus}
columns={[
{
Header: 'Assignment details',
accessor: 'assignmentDetails',
Cell: AssignmentDetailsTableCell,
disableSortBy: true,
},
{
Header: 'Amount',
Cell: ({ row }) => `-${formatPrice(row.original.contentQuantity / 100, { maximumFractionDigits: 0 })}`,
disableFilters: true,
},
]}
initialTableOptions={{
getRowId: row => row?.uuid?.toString(),
}}
initialState={{
pageSize: PAGE_SIZE,
pageIndex: DEFAULT_PAGE,
sortBy: [],
filters: [],
}}
fetchData={fetchTableData}
data={tableData.results}
itemCount={tableData.count}
pageCount={tableData.numPages}
EmptyTableComponent={CustomDataTableEmptyState}
/>
);
}) => {
const renderAdditionalColumns = (row) => (
<div className="d-flex">
{row.original.state === 'allocated' && (
<OverlayTrigger
key="Remind"
placement="top"
overlay={<Tooltip variant="light" id="tooltip-remind">Remind learner</Tooltip>}
>
<Icon
className="ml-auto mr-0"
src={Mail}
// eslint-disable-next-line no-console
onClick={() => console.log(`Reminding ${row.original.uuid}`)}
data-testid={`remind-assignment-${row.original.uuid}`}
/>
</OverlayTrigger>
)}
<div />
<OverlayTrigger
key="Cancel"
placement="top"
overlay={<Tooltip variant="light" id="tooltip-cancel">Cancel assignment</Tooltip>}
>
<Icon
className="ml-4.5 mr-2 text-danger-500"
src={DoNotDisturbOn}
// eslint-disable-next-line no-console
onClick={() => console.log(`Canceling ${row.original.uuid}`)}
data-testid={`cancel-assignment-${row.original.uuid}`}
/>
</OverlayTrigger>
</div>
);
return (
<DataTable
isSortable
isSelectable
manualSortBy
isPaginated
manualPagination
isFilterable
manualFilters
isLoading={isLoading}
defaultColumnValues={{ Filter: TableTextFilter }}
FilterStatusComponent={FilterStatus}
columns={[
{
Header: 'Assignment details',
accessor: 'assignmentDetails',
Cell: AssignmentDetailsTableCell,
disableSortBy: true,
},
{
Header: 'Amount',
Cell: ({ row }) => `-${formatPrice(row.original.contentQuantity / 100, { maximumFractionDigits: 0 })}`,
disableFilters: true,
},
]}
additionalColumns={[
{
id: 'action',
Header: '',
Cell: ({ row }) => (
renderAdditionalColumns(row)
),
},
]}
initialTableOptions={{
getRowId: row => row?.uuid?.toString(),
}}
initialState={{
pageSize: PAGE_SIZE,
pageIndex: DEFAULT_PAGE,
sortBy: [],
filters: [],
}}
fetchData={fetchTableData}
data={tableData.results}
itemCount={tableData.count}
pageCount={tableData.numPages}
EmptyTableComponent={CustomDataTableEmptyState}
bulkActions={[
<RemindAction />,
<CancelAction />,
]}
onSelectedRowsChanged={() => {}}
/>
);
};

CancelAction.propTypes = {
selectedFlatRows: PropTypes.arrayOf(PropTypes.shape()),
};

CancelAction.defaultProps = {
selectedFlatRows: [],
};

RemindAction.propTypes = {
selectedFlatRows: PropTypes.arrayOf(PropTypes.shape()),
};

RemindAction.defaultProps = {
selectedFlatRows: [],
};

BudgetAssignmentsTable.propTypes = {
isLoading: PropTypes.bool.isRequired,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,4 +343,69 @@ describe('<BudgetDetailPage />', () => {

expect(screen.getByText('loading budget details')).toBeInTheDocument();
});

it('displays bulk actions with remind when row selected and state allocated', () => {
useSubsidyAccessPolicy.mockReturnValue({
isInitialLoading: false,
data: {
uuid: 'a52e6548-649f-4576-b73f-c5c2bee25e9c',
policyType: 'AssignedLearnerCreditAccessPolicy',
isAssignable: true,
},
});
const mockLearnerEmail = '[email protected]';
const mockCourseKey = 'edX+DemoX';
useBudgetContentAssignments.mockReturnValue({
isLoading: false,
contentAssignments: {
count: 1,
results: [
{
uuid: 'test-uuid',
learnerEmail: mockLearnerEmail,
contentKey: mockCourseKey,
state: 'allocated',
},
],
numPages: 1,
currentPage: 1,
},
});
renderWithRouter(<BudgetDetailPageWrapper />);
const cancelRowAction = screen.getByTestId('cancel-assignment-test-uuid');
const remindRowAction = screen.getByTestId('remind-assignment-test-uuid');
expect(cancelRowAction).toBeInTheDocument();
expect(remindRowAction).toBeInTheDocument();
});

it('hides remind row action when state not allocated', () => {
useSubsidyAccessPolicy.mockReturnValue({
isInitialLoading: false,
data: {
uuid: 'a52e6548-649f-4576-b73f-c5c2bee25e9c',
policyType: 'AssignedLearnerCreditAccessPolicy',
isAssignable: true,
},
});
const mockLearnerEmail = '[email protected]';
const mockCourseKey = 'edX+DemoX';
useBudgetContentAssignments.mockReturnValue({
isLoading: false,
contentAssignments: {
count: 1,
results: [
{
uuid: 'test-uuid',
learnerEmail: mockLearnerEmail,
contentKey: mockCourseKey,
state: 'something else',
},
],
numPages: 1,
currentPage: 1,
},
});
renderWithRouter(<BudgetDetailPageWrapper />);
expect(screen.queryByTestId('remind-assignment-test-uuid')).not.toBeInTheDocument();
});
});

0 comments on commit 6cf5b62

Please sign in to comment.