Skip to content

Commit

Permalink
Add read/unread buttons to threading menu fixes VICE-1291
Browse files Browse the repository at this point in the history
Test Plan
1. Open Storybook `yarn storybook`
2. Navigate to threading menu
3. Should now see mark as read/unread options
4. Toggle of `isUnread` in Controls should change the menu between
the Read/Unread options

Change-Id: Ibeeced26d61c553806a0d5100f7e0df8336b9562
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/262528
Tested-by: Service Cloud Jenkins <[email protected]>
Tested-by: Omar Soto-Fortuño <[email protected]>
Reviewed-by: Omar Soto-Fortuño <[email protected]>
QA-Review: Omar Soto-Fortuño <[email protected]>
Product-Review: Omar Soto-Fortuño <[email protected]>
  • Loading branch information
jeffredodd committed Apr 9, 2021
1 parent 93fb36e commit 77cfa18
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import {
IconDiscussionLine,
IconEditLine,
IconTrashLine,
IconMarkAsReadLine,
IconMarkAsReadSolid,
IconSpeedGraderLine
} from '@instructure/ui-icons'

Expand Down Expand Up @@ -64,12 +66,27 @@ export class ThreadActions extends React.Component {
const getMenuConfigs = props => {
const options = [
{
key: 'markAsUnread',
key: 'markAllAsRead',
icon: <IconNextUnreadLine />,
label: I18n.t('Mark All as Read'),
selectionCallback: props.markAsUnread
selectionCallback: props.onMarkAllAsUnread
}
]
if (props.isUnread) {
options.push({
key: 'markAsRead',
icon: <IconMarkAsReadLine />,
label: I18n.t('Mark as Read'),
selectionCallback: props.onToggleUnread
})
} else {
options.push({
key: 'markAsUnread',
icon: <IconMarkAsReadSolid />,
label: I18n.t('Mark as Unread'),
selectionCallback: props.onToggleUnread
})
}
if (props.goToTopic) {
options.push({
key: 'toTopic',
Expand Down Expand Up @@ -114,7 +131,13 @@ const getMenuConfigs = props => {
}

const renderMenuItem = ({selectionCallback, icon, label, key}, id) => (
<Menu.Item key={`${key}-${id}`} onSelect={selectionCallback} data-testid={key}>
<Menu.Item
key={`${key}-${id}`}
onSelect={() => {
selectionCallback(key)
}}
data-testid={key}
>
<Flex>
<Flex.Item>{icon}</Flex.Item>
<Flex.Item padding="0 0 0 xx-small">
Expand All @@ -126,12 +149,18 @@ const renderMenuItem = ({selectionCallback, icon, label, key}, id) => (

ThreadActions.propTypes = {
id: PropTypes.string.isRequired,
markAsUnread: PropTypes.func.isRequired,
onMarkAllAsUnread: PropTypes.func.isRequired,
onToggleUnread: PropTypes.func.isRequired,
isUnread: PropTypes.bool,
goToTopic: PropTypes.func,
goToParent: PropTypes.func,
onEdit: PropTypes.func,
onDelete: PropTypes.func,
openInSpeedGrader: PropTypes.func
}

ThreadActions.defaultProps = {
isUnread: false
}

export default ThreadActions
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ export default {
title: 'Examples/Discussion Posts/ThreadActions',
component: ThreadActions,
argTypes: {
markAsUnread: {action: 'markAsUnread'},
goToTopic: {action: 'goToTopic'},
goToParent: {action: 'goToParent'},
onEdit: {action: 'onEdit'},
onDelete: {action: 'onDelete'},
onMarkAllAsUnread: {action: 'onMarkAsUnread'},
onToggleUnread: {action: 'onToggleUnread'},
openInSpeedGrader: {action: 'openInSpeedGrader'}
}
}
Expand All @@ -52,3 +53,13 @@ OtherStudentView.args = {
onEdit: null,
openInSpeedGrader: null
}

export const UnreadThread = Template.bind({})
UnreadThread.args = {
isUnread: true
}

export const ReadThread = Template.bind({})
ReadThread.args = {
isUnread: false
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ import {ThreadActions} from '../ThreadActions'
const createProps = overrides => {
return {
goToParent: jest.fn(),
markAsUnread: jest.fn(),
onMarkAllAsUnread: jest.fn(),
goToTopic: jest.fn(),
onEdit: jest.fn(),
onDelete: jest.fn(),
openInSpeedGrader: jest.fn(),
onToggleUnread: jest.fn(),
...overrides
}
}
Expand All @@ -41,6 +42,7 @@ describe('ThreadActions', () => {
expect(menu).toBeInTheDocument()
fireEvent.click(menu)

expect(getByTestId('markAllAsRead')).toBeInTheDocument()
expect(getByTestId('markAsUnread')).toBeInTheDocument()
expect(getByTestId('toTopic')).toBeInTheDocument()
expect(getByTestId('edit')).toBeInTheDocument()
Expand All @@ -55,7 +57,7 @@ describe('ThreadActions', () => {
})

it('does not display if callback is not provided', () => {
const props = {markAsUnread: jest.fn()}
const props = {onMarkAllAsUnread: jest.fn()}
const {getByTestId, queryByText} = render(<ThreadActions {...props} />)
const menu = getByTestId('thread-actions-menu')

Expand All @@ -76,15 +78,53 @@ describe('ThreadActions', () => {
const {getByTestId, getByText} = render(<ThreadActions {...props} />)

fireEvent.click(getByTestId('thread-actions-menu'))
expect(props.markAsUnread.mock.calls.length).toBe(0)
expect(props.onMarkAllAsUnread.mock.calls.length).toBe(0)
fireEvent.click(getByText('Mark All as Read'))
expect(props.markAsUnread.mock.calls.length).toBe(1)
expect(props.onMarkAllAsUnread.mock.calls.length).toBe(1)
})
})

describe('mark as read/unread', () => {
it('should render Mark as Unread button when read', () => {
const props = createProps()
const {getByTestId} = render(<ThreadActions {...props} />)

const menu = getByTestId('thread-actions-menu')
expect(menu).toBeInTheDocument()
fireEvent.click(menu)

const markAsUnread = getByTestId('markAsUnread')

expect(markAsUnread).toBeInTheDocument()

fireEvent.click(markAsUnread)

expect(props.onToggleUnread.mock.calls.length).toBe(1)
expect(props.onToggleUnread.mock.calls[0][0]).toBe('markAsUnread')
})

it('should render Mark as Read button when unread', () => {
const props = createProps()
const {getByTestId} = render(<ThreadActions isUnread {...props} />)

const menu = getByTestId('thread-actions-menu')
expect(menu).toBeInTheDocument()
fireEvent.click(menu)

const markAsRead = getByTestId('markAsRead')

expect(markAsRead).toBeInTheDocument()

fireEvent.click(markAsRead)

expect(props.onToggleUnread.mock.calls.length).toBe(1)
expect(props.onToggleUnread.mock.calls[0][0]).toBe('markAsRead')
})
})

describe('edit', () => {
it('does not render if the callback is not provided', () => {
const props = {markAsUnread: jest.fn()}
const props = {onMarkAllAsUnread: jest.fn()}
const {getByTestId, queryByText} = render(<ThreadActions {...props} />)

fireEvent.click(getByTestId('thread-actions-menu'))
Expand All @@ -104,7 +144,7 @@ describe('ThreadActions', () => {

describe('delete', () => {
it('does not render if the callback is not provided', () => {
const props = {markAsUnread: jest.fn()}
const props = {onMarkAllAsUnread: jest.fn()}
const {getByTestId, queryByText} = render(<ThreadActions {...props} />)

fireEvent.click(getByTestId('thread-actions-menu'))
Expand All @@ -124,7 +164,7 @@ describe('ThreadActions', () => {

describe('SpeedGrader', () => {
it('does not render if the callback is not provided', () => {
const props = {markAsUnread: jest.fn()}
const props = {onMarkAllAsUnread: jest.fn()}
const {getByTestId, queryByText} = render(<ThreadActions {...props} />)

fireEvent.click(getByTestId('thread-actions-menu'))
Expand All @@ -144,7 +184,7 @@ describe('ThreadActions', () => {

describe('Go to topic', () => {
it('does not render if the callback is not provided', () => {
const props = {markAsUnread: jest.fn()}
const props = {onMarkAllAsUnread: jest.fn()}
const {getByTestId, queryByText} = render(<ThreadActions {...props} />)

fireEvent.click(getByTestId('thread-actions-menu'))
Expand All @@ -164,7 +204,7 @@ describe('ThreadActions', () => {

describe('Go to Parent', () => {
it('does not render if the callback is not provided', () => {
const props = {markAsUnread: jest.fn()}
const props = {onMarkAllAsUnread: jest.fn()}
const {getByTestId, queryByText} = render(<ThreadActions {...props} />)

fireEvent.click(getByTestId('thread-actions-menu'))
Expand Down

0 comments on commit 77cfa18

Please sign in to comment.