Change available pronouns from table to pills

Test plan:
-go to root account settings page /accounts/2/settings
-scroll down to the available pronouns section
-make sure the box is checked
-type in a pronoun and push enter
-click a pronoun to delete it

flag = none

closes VICE-543

Change-Id: I958270441ff318c528cfa8c54f262c53f99abde9
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/242925
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Davis Hyer <dhyer@instructure.com>
Product-Review: Laura Leavitt <lleavitt@instructure.com>
QA-Review: Davis Hyer <dhyer@instructure.com>
This commit is contained in:
Drake Harper 2020-07-17 12:08:10 -06:00
parent 7af32f9c1e
commit 7709fb1d19
4 changed files with 180 additions and 27 deletions

View File

@ -0,0 +1,103 @@
/*
* Copyright (C) 2020 - 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 {Tag} from '@instructure/ui-tag'
import {Text} from '@instructure/ui-text'
import {TextInput} from '@instructure/ui-text-input'
import {nanoid} from 'nanoid'
import {IconInfoLine} from '@instructure/ui-icons'
import I18n from 'i18n!PronounsInput'
export default class PronounsInput extends React.Component {
constructor(props) {
super(props)
const pronounList = ENV.PRONOUNS_LIST.filter(x => x !== null)
this.state = {
pronouns: pronounList,
input_id: `new_pronoun_input_${nanoid()}`
}
}
createNewTag = value => (
<>
<Tag
dismissible
key={`pronoun_${value}`}
text={value}
margin="0 small 0 0"
onClick={() => this.deletePronoun(value)}
/>
<input
key={`pronoun_input_holder_${value}`}
name="account[pronouns][]"
type="hidden"
value={value}
/>
</>
)
handleChange = (e, value) => {
this.setState({value})
}
deletePronoun = pronounToDelete => {
this.setState(prevState => ({
pronouns: prevState.pronouns.filter(pronoun => pronounToDelete !== pronoun)
}))
}
render() {
return (
<TextInput
id={`${this.state.input_id}`}
data-testid="test_pronoun_input"
onChange={this.handleChange}
onKeyDown={e => {
if (e.key === 'Enter') {
e.preventDefault()
this.setState(prevState => {
if (prevState.value && prevState.value !== '') {
prevState.pronouns.push(prevState.value)
return {pronouns: [...new Set(prevState.pronouns)]}
}
return prevState
})
document.querySelector(`#${this.state.input_id}`).value = ''
}
}}
label={
<>
<Text>{I18n.t('Available Pronouns')}</Text>
<span style={{margin: '0 10px 0 10px'}}>
<IconInfoLine />
</span>
</>
}
size="medium"
resize="vertical"
height="4 rem"
renderBeforeInput={this.state.pronouns.map(pronoun => {
return this.createNewTag(pronoun)
})}
/>
)
}
}

View File

@ -0,0 +1,49 @@
/*
* Copyright (C) 2020 - 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 PronounInput from '../PronounsInput'
import {render, fireEvent} from '@testing-library/react'
import React from 'react'
describe('render available pronouns input', () => {
beforeAll(() => {
ENV.PRONOUNS_LIST = ['She/Her', 'He/Him', 'They/Them']
})
it('with defaults in view', () => {
const {getByText} = render(<PronounInput />)
expect(getByText('She/Her')).toBeVisible()
expect(getByText('He/Him')).toBeVisible()
expect(getByText('They/Them')).toBeVisible()
})
it('removes pronoun "They/Them"', async () => {
const {findByText, queryByText} = render(<PronounInput />)
expect(await findByText('They/Them')).toBeVisible()
fireEvent.click(await findByText('They/Them'))
expect(await queryByText('They/Them')).toEqual(null)
})
it('adds pronoun "It/That"', async () => {
const {findByText, getByTestId} = render(<PronounInput />)
const input = getByTestId('test_pronoun_input')
fireEvent.change(input, {target: {value: 'It/That'}})
fireEvent.keyDown(input, {key: 'Enter', code: 13, charCode: 13})
expect(await findByText('It/That')).toBeVisible()
})
})

View File

@ -0,0 +1,26 @@
/*
* Copyright (C) 2020 - 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 $ from 'jquery'
import React from 'react'
import ReactDOM from 'react-dom'
import PronounsInput from '../account_settings/PronounsInput'
$(() => {
ReactDOM.render(<PronounsInput />, $('<div/>').appendTo('#personal_pronouns_options')[0])
})

View File

@ -380,33 +380,8 @@
<%= settings.check_box :can_add_pronouns, :checked => @account.settings[:can_add_pronouns], class: "element_toggler", "aria-controls": "personal_pronouns_options" %>
<%= settings.label :can_add_pronouns, en: "Enable Personal Pronouns" %>
<div id="personal_pronouns_options" <%= hidden(true) unless @account.settings[:can_add_pronouns] %>>
<table class="formtable">
<tbody>
<% ((@account.pronouns.presence || Pronouns.default_pronouns) + [nil]).each do |pronouns| %>
<tr class="pronouns_row <%= raw ' blank" style="display: none;' if pronouns.nil? %>">
<td> <input type="text" name="account[pronouns][]" value="<%= pronouns %>"/></td>
<td>
<button
type="button"
class="Button Button--icon-action"
title="<%= t("Remove Pronouns %{pronoun}", :pronoun => pronouns) %>"
onclick="$(this).closest('.pronouns_row').remove()"
>
<i class="icon-end standalone-icon"></i>
</button>
</td>
</tr>
<% end %>
</tbody>
</table>
<button
type="button"
class="Button"
onclick="$('.pronouns_row.blank').clone().removeClass('blank').show().insertBefore('.pronouns_row.blank').find('input').focus()"
>
<i class='icon-add'></i>
<%= t("Add pronouns option") %>
</button>
<% js_env(PRONOUNS_LIST: ((@account.pronouns.presence || Pronouns.default_pronouns)))
js_bundle :available_pronouns_list %>
</div>
<% end %>
</fieldset>