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 5d2a736 commit 9d7fd32
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React from 'react';
import PropTypes from 'prop-types';
import {
Icon,
IconButton,
OverlayTrigger,
Stack,
Tooltip,
} from '@edx/paragon';
import { Mail, DoNotDisturbOn } from '@edx/paragon/icons';

const AssignmentRowActionTableCell = ({ row }) => {
const cancelButtonMarginLeft = row.original.state === 'allocated' ? 'ml-2.5' : 'ml-auto';
return (
<div className="d-flex">
{row.original.state === 'allocated' && (
<>
<OverlayTrigger
key="Remind"
placement="top"
overlay={<Tooltip variant="light" id="tooltip-remind">Remind learner</Tooltip>}
>
<IconButton
className="ml-auto mr-0"
src={Mail}
iconAs={Icon}
// eslint-disable-next-line no-console
onClick={() => console.log(`Reminding ${row.original.uuid}`)}
data-testid={`remind-assignment-${row.original.uuid}`}
/>
</OverlayTrigger>
<Stack direction="horizontal" gap={1} />
</>
)}
<OverlayTrigger
key="Cancel"
placement="top"
overlay={<Tooltip variant="light" id="tooltip-cancel">Cancel assignment</Tooltip>}
>
<IconButton
className={`${cancelButtonMarginLeft} mr-1 text-danger-500`}
src={DoNotDisturbOn}
iconAs={Icon}
// eslint-disable-next-line no-console
onClick={() => console.log(`Canceling ${row.original.uuid}`)}
data-testid={`cancel-assignment-${row.original.uuid}`}
/>
</OverlayTrigger>
</div>
);
};

AssignmentRowActionTableCell.propTypes = {
row: PropTypes.shape({
original: PropTypes.shape({
uuid: PropTypes.string.isRequired,
state: PropTypes.string.isRequired,
}).isRequired,
}).isRequired,
};

export default AssignmentRowActionTableCell;
21 changes: 21 additions & 0 deletions src/components/learner-credit-management/AssignmentTableCancel.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Button } from '@edx/paragon';
import { DoNotDisturbOn } from '@edx/paragon/icons';

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

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

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

export default AssignmentTableCancelAction;
29 changes: 29 additions & 0 deletions src/components/learner-credit-management/AssignmentTableRemind.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Button } from '@edx/paragon';
import { Mail } from '@edx/paragon/icons';

const AssignmentTableRemindAction = ({ selectedFlatRows, ...rest }) => {
const hideRemindAction = selectedFlatRows.some(
row => row.original.state !== 'allocated',
);
if (hideRemindAction) {
return null;
}
return (
// eslint-disable-next-line no-console
<Button iconBefore={Mail} onClick={() => console.log('Remind', selectedFlatRows, rest)}>
{`Remind (${selectedFlatRows.length})`}
</Button>
);
};

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

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

export default AssignmentTableRemindAction;
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React from 'react';
import PropTypes from 'prop-types';
import { DataTable } from '@edx/paragon';

import TableTextFilter from './TableTextFilter';
import CustomDataTableEmptyState from './CustomDataTableEmptyState';
import AssignmentDetailsTableCell from './AssignmentDetailsTableCell';
import AssignmentStatusTableCell from './AssignmentStatusTableCell';
import AssignmentRowActionTableCell from './AssignmentRowActionTableCell';
import AssignmentTableRemindAction from './AssignmentTableRemind';
import AssignmentTableCancelAction from './AssignmentTableCancel';
import { DEFAULT_PAGE, PAGE_SIZE, formatPrice } from './data';
import AssignmentRecentActionTableCell from './AssignmentRecentActionTableCell';

Expand All @@ -18,6 +20,7 @@ const BudgetAssignmentsTable = ({
}) => (
<DataTable
isSortable
isSelectable
manualSortBy
isPaginated
manualPagination
Expand Down Expand Up @@ -49,6 +52,13 @@ const BudgetAssignmentsTable = ({
disableFilters: true,
},
]}
additionalColumns={[
{
Header: '',
Cell: AssignmentRowActionTableCell,
id: 'action',
},
]}
initialTableOptions={{
getRowId: row => row?.uuid?.toString(),
}}
Expand All @@ -63,6 +73,10 @@ const BudgetAssignmentsTable = ({
itemCount={tableData?.count || 0}
pageCount={tableData?.numPages || 1}
EmptyTableComponent={CustomDataTableEmptyState}
bulkActions={[
<AssignmentTableRemindAction />,
<AssignmentTableCancelAction />,
]}
/>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -701,4 +701,57 @@ describe('<BudgetDetailPage />', () => {

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

it('displays bulk actions with remind when row selected and state allocated', () => {
useSubsidyAccessPolicy.mockReturnValue({
isInitialLoading: false,
data: mockAssignableSubsidyAccessPolicy,
});
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: mockAssignableSubsidyAccessPolicy,
});
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 9d7fd32

Please sign in to comment.