Create AnonymousPostSelector component

refs VICE-2367

flag=react_discussions_post
flag=discussion_anonymity

test plan:
  - Specs pass
  - Open storybook
  - Verify that AnonymousPostSelector matches design

qa risk: low

Change-Id: I8e1d5df6ab08b0d56747074e04f08d4c6c23126f
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/282438
Reviewed-by: Chawn Neal <chawn.neal@instructure.com>
QA-Review: Chawn Neal <chawn.neal@instructure.com>
Product-Review: Chawn Neal <chawn.neal@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
This commit is contained in:
Omar Gerardo Soto-Fortuño 2022-01-10 12:26:15 -05:00 committed by Omar Soto-Fortuño
parent 211af6ddb1
commit 0e2387ee77
3 changed files with 197 additions and 0 deletions

View File

@ -0,0 +1,109 @@
/*
* Copyright (C) 2021 - present Instructure, Inc.
*
* This file is part of Canvas.
*
* Canvas is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, version 3 of the License.
*
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import I18n from 'i18n!discussions_posts'
import React, {useState} from 'react'
import {Flex} from '@instructure/ui-flex'
import {Avatar} from '@instructure/ui-avatar'
import {AnonymousAvatar} from '../AnonymousAvatar/AnonymousAvatar'
import {CURRENT_USER} from '../../utils/constants'
import {Text} from '@instructure/ui-text'
import {Select} from '@instructure/ui-select'
export const AnonymousPostSelector = () => {
const [inputValue, setInputValue] = useState('Show to everyone')
const [selectedOptionId, setSelectedOptionId] = useState('show')
const [showOptions, setShowOptions] = useState(false)
const [highlightedOption, setHighlightedOption] = useState(null)
return (
<>
<Flex>
<Flex.Item align="start">
{selectedOptionId === 'show' && (
<Avatar
name={ENV.current_user.display_name}
src={ENV.current_user.avatar_image_url}
margin="0"
data-testid="current_user_avatar"
/>
)}
{selectedOptionId === 'hide' && <AnonymousAvatar seedString={CURRENT_USER} />}
</Flex.Item>
<Flex.Item direction="column" margin="0 0 0 small" padding="0 small 0 0" shouldShrink>
<Text weight="bold" size="medium" lineHeight="condensed">
{selectedOptionId === 'hide' ? I18n.t('Anonymous') : ENV.current_user.display_name}
</Text>
</Flex.Item>
</Flex>
<Flex margin="small 0 0 0">
<Select
inputValue={inputValue}
isShowingOptions={showOptions}
onRequestShowOptions={() => {
setShowOptions(true)
}}
onRequestHideOptions={() => {
setShowOptions(false)
}}
onRequestSelectOption={(event, {id}) => {
setShowOptions(false)
setSelectedOptionId(id)
if (id === 'hide') {
setInputValue(I18n.t('Hide from everyone'))
} else if (id === 'show') {
setInputValue(I18n.t('Show to everyone'))
}
}}
onBlur={() => {
setHighlightedOption(null)
}}
onRequestHighlightOption={(event, {id}) => {
setHighlightedOption(id)
}}
data-testid="anonymous_post_selector"
>
<Select.Option
id="show"
key="show"
isHighlighted={highlightedOption === 'show'}
isSelected={selectedOptionId === 'show'}
>
<Text>{I18n.t('Show to everyone')}</Text>
</Select.Option>
<Select.Option
id="hide"
key="hide"
isHighlighted={highlightedOption === 'hide'}
isSelected={selectedOptionId === 'hide'}
>
<Text>{I18n.t('Hide from everyone')}</Text>
</Select.Option>
</Select>
</Flex>
<Flex margin="x-small 0 0 0">
<Text weight="normal" size="small">
{selectedOptionId === 'show'
? I18n.t('Show name and profile picture')
: I18n.t('Hide name and profile picture')}
</Text>
</Flex>
</>
)
}

View File

@ -0,0 +1,33 @@
/*
* Copyright (C) 2021 - present Instructure, Inc.
*
* This file is part of Canvas.
*
* Canvas is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, version 3 of the License.
*
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React from 'react'
import {AnonymousPostSelector} from './AnonymousPostSelector'
ENV.current_user = {display_name: 'Ronald Weasley'}
export default {
title: 'Examples/Discussion Posts/Components/AnonymousPostSelector',
component: AnonymousPostSelector,
argTypes: {}
}
const Template = args => <AnonymousPostSelector {...args} />
export const Default = Template.bind({})
Default.args = {}

View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2021 - present Instructure, Inc.
*
* This file is part of Canvas.
*
* Canvas is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, version 3 of the License.
*
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React from 'react'
import {fireEvent, render} from '@testing-library/react'
import {AnonymousPostSelector} from '../AnonymousPostSelector'
const setup = () => {
return <AnonymousPostSelector />
}
describe('AnonymousPostSelector', () => {
beforeAll(() => {
window.ENV.current_user = {display_name: 'Ronald Weasley'}
})
it('should render', () => {
const container = render(setup())
expect(container).toBeTruthy()
})
it('should render current user by default', () => {
const container = render(setup())
expect(container.getByTestId('current_user_avatar')).toBeTruthy()
expect(container.getByText('Ronald Weasley')).toBeTruthy()
expect(container.getByText('Show name and profile picture')).toBeTruthy()
})
it('should allow to change to Hide from everyone', () => {
const container = render(setup())
fireEvent.click(container.getByTestId('anonymous_post_selector'))
fireEvent.click(container.getByText('Hide from everyone'))
expect(container.getByTestId('anonymous_avatar')).toBeTruthy()
expect(container.getByText('Anonymous')).toBeTruthy()
expect(container.getByText('Hide name and profile picture')).toBeTruthy()
})
})