Skip to content

Commit

Permalink
Fix use optionIndex as collection_index for checkboxes
Browse files Browse the repository at this point in the history
  • Loading branch information
jochenklar committed Feb 4, 2025
1 parent 009022a commit a532e8b
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 26 deletions.
14 changes: 8 additions & 6 deletions rdmo/projects/assets/js/interview/actions/interviewActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,19 +275,21 @@ export function storeValue(value) {
return {type: NOOP}
} else {
return (dispatch, getState) => {
const valueIndex = getState().interview.values.findIndex((v) => compareValues(v, value))
const page = getState().interview.page
const sets = getState().interview.sets
const question = page.questions.find((question) => question.attribute === value.attribute)
const refresh = question && question.optionsets.some((optionset) => optionset.has_refresh)
const widget_type = question && question.widget_type

const valueIndex = getState().interview.values.findIndex((v) => compareValues(v, value, widget_type))
const valueFile = value.file
const valueSuccess = value.success

dispatch(addToPending(pendingId))
dispatch(storeValueInit(valueIndex))

return ValueApi.storeValue(projectId, value)
return ValueApi.storeValue(projectId, { ...value, widget_type })
.then((value) => {
const page = getState().interview.page
const sets = getState().interview.sets
const question = page.questions.find((question) => question.attribute === value.attribute)
const refresh = question && question.optionsets.some((optionset) => optionset.has_refresh)

dispatch(fetchNavigation(page))
dispatch(updateProgress())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,22 @@ import AdditionalTextareaInput from './common/AdditionalTextareaInput'
import OptionHelp from './common/OptionHelp'
import OptionText from './common/OptionText'

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

const checked = !isNil(value)

const handleCreate = (option, additionalInput) => {
const handleCreate = (option, optionIndex, additionalInput) => {
if (option.has_provider) {
onCreate([{
external_id: option.id,
text: option.text
text: option.text,
collection_index: optionIndex
}])
} else {
onCreate([{
option: option.id,
text: additionalInput
text: additionalInput,
collection_index: optionIndex
}])
}
}
Expand All @@ -30,7 +32,7 @@ const CheckboxInput = ({ question, value, option, disabled, onCreate, onUpdate,
if (checked) {
onDelete(value)
} else {
handleCreate(option)
handleCreate(option, optionIndex)
}
}

Expand All @@ -52,7 +54,7 @@ const CheckboxInput = ({ question, value, option, disabled, onCreate, onUpdate,
})
}
} else {
handleCreate(option, additionalInput)
handleCreate(option, optionIndex, additionalInput)
}
}, 500)

Expand Down Expand Up @@ -100,6 +102,7 @@ CheckboxInput.propTypes = {
question: PropTypes.object,
value: PropTypes.object,
option: PropTypes.object,
optionIndex: PropTypes.object,
disabled: PropTypes.bool,
onCreate: PropTypes.func.isRequired,
onUpdate: PropTypes.func.isRequired,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react'
import PropTypes from 'prop-types'
import { maxBy } from 'lodash'

import { gatherOptions } from '../../../utils/options'

Expand All @@ -16,21 +15,16 @@ const CheckboxWidget = ({ page, question, sets, values, siblings, currentSet, di
createValue, updateValue, deleteValue, copyValue }) => {

const handleCreateValue = (attrsList) => {
const lastValue = maxBy(values, (v) => v.collection_index)

let collectionIndex = lastValue ? lastValue.collection_index + 1 : 0
attrsList.forEach(attrs => {
createValue({
attribute: question.attribute,
set_prefix: currentSet.set_prefix,
set_index: currentSet.set_index,
collection_index: collectionIndex,
set_collection: question.set_collection,
unit: question.unit,
value_type: question.value_type,
...attrs
}, true)
collectionIndex += 1
})
}

Expand All @@ -54,6 +48,7 @@ const CheckboxWidget = ({ page, question, sets, values, siblings, currentSet, di
question={question}
value={value}
option={option}
optionIndex={optionIndex}
disabled={disabled}
onCreate={handleCreateValue}
onUpdate={updateValue}
Expand Down
17 changes: 12 additions & 5 deletions rdmo/projects/assets/js/interview/utils/value.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,19 @@ const activateFirstValue = (page, values) => {
}
}

const compareValues = (a, b) => {
const compareValues = (a, b, widget_type = null) => {
if (isNil(a.id) || isNil(b.id)) {
return (a.attribute == b.attribute) &&
(a.set_prefix == b.set_prefix) &&
(a.set_index == b.set_index) &&
(a.collection_index == b.collection_index)
if (widget_type === 'checkbox') {
return (a.attribute == b.attribute) &&
(a.set_prefix == b.set_prefix) &&
(a.set_index == b.set_index) &&
(a.option == b.option)
} else {
return (a.attribute == b.attribute) &&
(a.set_prefix == b.set_prefix) &&
(a.set_index == b.set_index) &&
(a.collection_index == b.collection_index)
}
} else {
return a.id == b.id
}
Expand Down
9 changes: 6 additions & 3 deletions rdmo/projects/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,17 @@ def __call__(self, data, serializer):
get_kwargs = {
'attribute': data.get('attribute'),
'set_prefix': data.get('set_prefix'),
'set_index': data.get('set_index'),
'collection_index': data.get('collection_index')
'set_index': data.get('set_index')
}

# for checkboxes, check only values with the same option. the widget_type is provided with the post request
# check the widget type, which is provided with the post request
widget_type = serializer.context['view'].request.data.get('widget_type')
if widget_type == 'checkbox':
# for checkboxes, fail if a value with the same option exist
get_kwargs['option'] = data.get('option')
else:
# for all other widget_types, fail if a value with the same collection_index exist
get_kwargs['collection_index'] = data.get('collection_index')

try:
serializer.context['view'].project.values.filter(snapshot=None).get(**get_kwargs)
Expand Down

0 comments on commit a532e8b

Please sign in to comment.