Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -208,12 +208,6 @@ filterwarnings = [
# fail on RemovedInDjango50Warning exception
"error::django.utils.deprecation.RemovedInDjango50Warning",

# ignore warnings raised from within coreapi 2.3.3
"ignore:pkg_resources is deprecated as an API:DeprecationWarning",

# ignore warning from rest_framework about coreapi
"ignore:CoreAPI compatibility is deprecated and will be removed in DRF 3.17:rest_framework.RemovedInDRF317Warning",

# ignore warnings raised by widget_tweaks.py
"ignore:'maxsplit' is passed as positional argument",

Expand Down
2 changes: 1 addition & 1 deletion rdmo/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "2.3.2"
__version__ = "2.4.0"
4 changes: 2 additions & 2 deletions rdmo/core/static/core/css/base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -500,8 +500,8 @@ li.has-warning > a.control-label > i {
}

// adjust background "hover" color in select2 to $link-color
.select2-results__option--highlighted{
background-color: $link-color !important,
.select2-results__option--highlighted {
background-color: $link-color !important
}

.cc-myself {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
import React from 'react'
import React, { useRef } from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
import { useDebouncedCallback } from 'use-debounce'
import { isEmpty, isNil } from 'lodash'

import useAdditionalInputs from '../../../hooks/useAdditionalInputs'
import useAdjustLabel from '../../../hooks/useAdjustLabel'
import useIdle from '../../../hooks/useIdle'

import AdditionalTextInput from './common/AdditionalTextInput'
import AdditionalTextareaInput from './common/AdditionalTextareaInput'
import OptionHelp from './common/OptionHelp'
import OptionText from './common/OptionText'

const CheckboxInput = ({ question, value, option, optionIndex, disabled, onCreate, onUpdate, onDelete }) => {

const ref = useRef(null)
const [getAdditionalInput, setAdditionalInput] = useAdditionalInputs(value, [option])
const [idle, setIdle] = useIdle([value])

useAdjustLabel(ref)

const checked = !isNil(value)

const classnames = classNames('checkbox', {
Expand All @@ -34,14 +44,20 @@ const CheckboxInput = ({ question, value, option, optionIndex, disabled, onCreat
}

const handleChange = () => {
if (checked) {
onDelete(value)
} else {
handleCreate(option, optionIndex)
if (idle) {
setIdle(false)
handleAdditionalInputChange.cancel()

if (checked) {
onDelete(value)
setAdditionalInput(option, '')
} else {
handleCreate(option, optionIndex, getAdditionalInput(option))
}
}
}

const handleAdditionalValueChange = useDebouncedCallback((value, option, additionalInput) => {
const handleAdditionalInputChange = useDebouncedCallback((value, option, additionalInput) => {
if (checked) {
if (option.has_provider) {
onUpdate(value, {
Expand All @@ -64,7 +80,7 @@ const CheckboxInput = ({ question, value, option, optionIndex, disabled, onCreat
}, 500)

return (
<div className={classnames}>
<div ref={ref} className={classnames}>
<label>
<input
type="checkbox"
Expand All @@ -83,7 +99,15 @@ const CheckboxInput = ({ question, value, option, optionIndex, disabled, onCreat
option.additional_input == 'text' && (
<>
<span>:</span>
<AdditionalTextInput className="ml-10" value={value} option={option} disabled={disabled} onChange={handleAdditionalValueChange} />
<AdditionalTextInput
className="ml-10"
inputValue={getAdditionalInput(option)}
disabled={disabled}
onChange={(additionalInput) => {
setAdditionalInput(option, additionalInput)
handleAdditionalInputChange(value, option, additionalInput)
}}
/>
<OptionHelp className="ml-10" option={option} />
</>
)
Expand All @@ -92,7 +116,14 @@ const CheckboxInput = ({ question, value, option, optionIndex, disabled, onCreat
option.additional_input == 'textarea' && (
<>
<span>:</span>
<AdditionalTextareaInput value={value} option={option} disabled={disabled} onChange={handleAdditionalValueChange} />
<AdditionalTextareaInput
inputValue={getAdditionalInput(option)}
disabled={disabled}
onChange={(additionalInput) => {
setAdditionalInput(option, additionalInput)
handleAdditionalInputChange(value, option, additionalInput)
}}
/>
<div>
<OptionHelp option={option} />
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react'
import PropTypes from 'prop-types'


import { getQuestionTextId, getQuestionHelpId } from '../../../utils/question'
import { gatherOptions } from '../../../utils/options'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React, { useRef } from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
import { useDebouncedCallback } from 'use-debounce'
Expand All @@ -7,13 +7,24 @@ import { isEmpty } from 'lodash'
import { getQuestionTextId, getQuestionHelpId } from '../../../utils/question'
import { isDefaultValue } from '../../../utils/value'

import useAdditionalInputs from '../../../hooks/useAdditionalInputs'
import useAdjustLabel from '../../../hooks/useAdjustLabel'

import AdditionalTextInput from './common/AdditionalTextInput'
import AdditionalTextareaInput from './common/AdditionalTextareaInput'
import OptionHelp from './common/OptionHelp'
import OptionText from './common/OptionText'

const RadioInput = ({ question, value, options, disabled, updateValue, buttons }) => {

const ref = useRef(null)
const [getAdditionalInput, setAdditionalInput] = useAdditionalInputs(value, options)

useAdjustLabel(ref)

const handleChange = (option) => {
handleAdditionalInputChange.cancel()

if (option.has_provider) {
updateValue(value, {
text: option.text,
Expand All @@ -23,15 +34,15 @@ const RadioInput = ({ question, value, options, disabled, updateValue, buttons }
})
} else {
updateValue(value, {
text: option.default_text || '',
text: getAdditionalInput(option) || option.default_text || '',
option: option.id,
unit: question.unit,
value_type: question.value_type
})
}
}

const handleAdditionalValueChange = useDebouncedCallback((value, option, additionalInput) => {
const handleAdditionalInputChange = useDebouncedCallback((value, option, additionalInput) => {
updateValue(value, {
option: option.id,
text: additionalInput,
Expand All @@ -46,7 +57,7 @@ const RadioInput = ({ question, value, options, disabled, updateValue, buttons }
})

return (
<div className="interview-input radio-input">
<div ref={ref} className="interview-input radio-input">
<div className="buttons-wrapper">
{buttons}
<fieldset className={classnames}
Expand Down Expand Up @@ -78,10 +89,12 @@ const RadioInput = ({ question, value, options, disabled, updateValue, buttons }
<span>:</span>
<AdditionalTextInput
className="ml-10"
value={value}
option={option}
inputValue={getAdditionalInput(option)}
disabled={disabled}
onChange={handleAdditionalValueChange}
onChange={(additionalInput) => {
setAdditionalInput(option, additionalInput)
handleAdditionalInputChange(value, option, additionalInput)
}}
/>
<OptionHelp className="ml-10" option={option} />
</>
Expand All @@ -92,10 +105,12 @@ const RadioInput = ({ question, value, options, disabled, updateValue, buttons }
<>
<span>:</span>
<AdditionalTextareaInput
value={value}
option={option}
inputValue={getAdditionalInput(option)}
disabled={disabled}
onChange={handleAdditionalValueChange}
onChange={(additionalInput) => {
setAdditionalInput(option, additionalInput)
handleAdditionalInputChange(value, option, additionalInput)
}}
/>
<div>
<OptionHelp option={option} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import PropTypes from 'prop-types'
import classNames from 'classnames'
import { isEmpty, isNil } from 'lodash'
import { useDebouncedCallback } from 'use-debounce'
// import { convert } from 'html-to-text'

import ProjectApi from '../../../api/ProjectApi'
import { projectId } from '../../../utils/meta'
Expand All @@ -19,6 +18,7 @@ import { getValueOption } from '../../../utils/options'
import OptionHelp from './common/OptionHelp'
import OptionText from './common/OptionText'

import SelectValueContainer from './SelectValueContainer'

const SelectInput = ({ question, value, options, disabled, creatable, updateValue, buttons }) => {

Expand Down Expand Up @@ -104,7 +104,8 @@ const SelectInput = ({ question, value, options, disabled, creatable, updateValu
<OptionText option={option} />
<OptionHelp className="ml-10" option={option} />
</span>
)
),
components: { ValueContainer: SelectValueContainer }
}

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, { useRef, useEffect } from 'react'
import PropTypes from 'prop-types'
import { components } from 'react-select'

const SelectValueContainer = (props) => {
const ref = useRef(null)

useEffect(() => {
if (!ref.current) return

const links = ref.current.querySelectorAll('a')
const handlers = []

links.forEach((link) => {
const handler = (e) => e.stopPropagation()

link.addEventListener('mousedown', handler)
link.setAttribute('target', '_blank')
link.setAttribute('rel', 'noopener noreferrer')

handlers.push({ link, handler })
})

return () => {
handlers.forEach(({ link, handler }) => {
link.removeEventListener('mousedown', handler)
})
}
}, [])

return (
<components.ValueContainer {...props}>
<span ref={ref} style={{ display: 'inline-flex', alignItems: 'center' }}>
{props.children}
</span>
</components.ValueContainer>
)
}

SelectValueContainer.propTypes = {
children: PropTypes.node
}

export default SelectValueContainer
Original file line number Diff line number Diff line change
@@ -1,39 +1,23 @@
import React, { useState, useEffect } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { get, isNil } from 'lodash'

const AdditionalTextInput = ({ className, value, option, disabled, onChange }) => {
const [inputValue, setInputValue] = useState('')

useEffect(() => {
if (isNil(value)) {
setInputValue('')
} else {
setInputValue(value.option == option.id ? value.text : '')
}
}, [get(value, 'id'), get(value, 'text'), get(value, 'option'), get(value, 'external_id')])
import classNames from 'classnames'

const AdditionalTextInput = ({ className, inputValue, disabled, onChange }) => {
return (
<span className={className}>
<input
type="text"
className="form-control input-sm"
disabled={disabled}
aria-label={gettext('Additional input')}
value={inputValue}
onChange={(event) => {
setInputValue(event.target.value)
onChange(value, option, event.target.value)
}}
/>
</span>
<input
type="text"
className={classNames('form-control input-sm', className)}
disabled={disabled}
aria-label={gettext('Additional input')}
value={inputValue}
onChange={(event) => onChange(event.target.value)}
/>
)
}

AdditionalTextInput.propTypes = {
className: PropTypes.string,
value: PropTypes.object,
option: PropTypes.object.isRequired,
inputValue: PropTypes.string,
disabled: PropTypes.bool,
onChange: PropTypes.func.isRequired
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,23 @@
import React, { useState, useEffect } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { get, isNil } from 'lodash'

const AdditionalTextareaInput = ({ value, option, disabled, onChange }) => {
const [inputValue, setInputValue] = useState('')

useEffect(() => {
if (isNil(value)) {
setInputValue('')
} else {
setInputValue(value.option == option.id ? value.text : '')
}
}, [get(value, 'id'), get(value, 'text'), get(value, 'option'), get(value, 'external_id')])
import classNames from 'classnames'

const AdditionalTextareaInput = ({ className, inputValue, disabled, onChange }) => {
return (
<textarea
rows={4}
className="form-control input-sm"
className={classNames('form-control input-sm', className)}
disabled={disabled}
aria-label={gettext('Additional input')}
value={inputValue}
onChange={(event) => {
setInputValue(event.target.value)
onChange(value, option, event.target.value)
}}
onChange={(event) => onChange(event.target.value)}
/>
)
}

AdditionalTextareaInput.propTypes = {
value: PropTypes.object,
option: PropTypes.object.isRequired,
className: PropTypes.string,
inputValue: PropTypes.string,
disabled: PropTypes.bool,
onChange: PropTypes.func.isRequired
}
Expand Down
Loading