diff --git a/assets/src/apps/authoring/components/PropertyEditor/PropertyEditor.tsx b/assets/src/apps/authoring/components/PropertyEditor/PropertyEditor.tsx index 82adf364bd..c2ddf6244a 100644 --- a/assets/src/apps/authoring/components/PropertyEditor/PropertyEditor.tsx +++ b/assets/src/apps/authoring/components/PropertyEditor/PropertyEditor.tsx @@ -100,6 +100,12 @@ const PropertyEditor: React.FC = ({ } }} onBlur={(key, changed) => { + //AdvancedFeedbackNumberRange widget does not call the onFocus hence we are using the onBlur and passing 'partPropertyElementFocus' as key + // to identify if this was called from onfocus event of the input + if (key === 'partPropertyElementFocus' && onfocusHandler) { + onfocusHandler(false); + return; + } // key will look like root_Position_x // changed will be the new value // formData will be the current state of the form diff --git a/assets/src/apps/authoring/components/PropertyEditor/custom/AdvancedFeedbackNumberRange.tsx b/assets/src/apps/authoring/components/PropertyEditor/custom/AdvancedFeedbackNumberRange.tsx index 4133500b55..26237bdcf4 100644 --- a/assets/src/apps/authoring/components/PropertyEditor/custom/AdvancedFeedbackNumberRange.tsx +++ b/assets/src/apps/authoring/components/PropertyEditor/custom/AdvancedFeedbackNumberRange.tsx @@ -59,6 +59,7 @@ export const AdvancedFeedbackNumberRange: React.FC = ({ id, value, onChan value={item} onRemoveRule={() => onChange(value.filter((v, i) => i !== index))} onChange={(newItem) => onChange(value.map((v, i) => (i === index ? newItem : v)))} + onfocusHandler={() => onBlur('partPropertyElementFocus', [])} /> ))} @@ -74,7 +75,8 @@ const FeedbackEditor: React.FC<{ onChange: (value: FeedbackItem) => void; onBlur: () => void; onRemoveRule: () => void; -}> = ({ value, onBlur, onChange, onRemoveRule }) => { + onfocusHandler: (changes: boolean) => void; +}> = ({ value, onBlur, onChange, onRemoveRule, onfocusHandler }) => { const onFeedbackChange = (e: React.ChangeEvent) => { onChange({ ...value, feedback: e.target.value }); }; @@ -154,6 +156,7 @@ const FeedbackEditor: React.FC<{ value={value.answer.correctMin} onChange={onCorrectMinChange} onBlur={onBlur} + onFocus={() => onfocusHandler(false)} />
@@ -163,6 +166,7 @@ const FeedbackEditor: React.FC<{ value={value.answer.correctMax} onChange={onCorrectMaxChange} onBlur={onBlur} + onFocus={() => onfocusHandler(false)} />
@@ -177,6 +181,7 @@ const FeedbackEditor: React.FC<{ value={value.answer.correctAnswer} onChange={onCorrectAnswerChange} onBlur={onBlur} + onFocus={() => onfocusHandler(false)} /> @@ -190,6 +195,7 @@ const FeedbackEditor: React.FC<{ value={value.feedback} onChange={onFeedbackChange} onBlur={onBlur} + onFocus={() => onfocusHandler(false)} /> diff --git a/assets/src/apps/authoring/components/PropertyEditor/custom/OptionsCustomErrorFeedbackAuthoring.tsx b/assets/src/apps/authoring/components/PropertyEditor/custom/OptionsCustomErrorFeedbackAuthoring.tsx index 44272461d0..23278cb5a5 100644 --- a/assets/src/apps/authoring/components/PropertyEditor/custom/OptionsCustomErrorFeedbackAuthoring.tsx +++ b/assets/src/apps/authoring/components/PropertyEditor/custom/OptionsCustomErrorFeedbackAuthoring.tsx @@ -1,7 +1,7 @@ import React, { useCallback } from 'react'; -import { useSelector } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; import { selectCurrentActivityTree } from '../../../../delivery/store/features/groups/selectors/deck'; -import { selectCurrentSelection } from '../../../store/parts/slice'; +import { selectCurrentSelection, setCurrentPartPropertyFocus } from '../../../store/parts/slice'; /* This component handles editing advanced feedback for a question type that has a fixed set of options. @@ -43,7 +43,7 @@ export const OptionsCustomErrorFeedbackAuthoring: React.FC = const currentPartSelection = useSelector(selectCurrentSelection); const activityTree = useSelector(selectCurrentActivityTree); const part = getPartDef(activityTree, currentPartSelection); - + const dispatch = useDispatch(); // TODO - make this widget more generic, right now it's very tied to dropdowns. const options: string[] = part?.custom?.optionLabels || ['Option 1', 'Option 2']; const correctIndex = (part?.custom?.correctAnswer || 0) - 1; // -1 because the correct answer is specified in a 1-based index @@ -76,12 +76,18 @@ export const OptionsCustomErrorFeedbackAuthoring: React.FC = } // No advanced feedback for the correct answer, that's just the "correct" feedback return ( onBlur(id, value)} + onBlur={() => { + onBlur(id, value); + dispatch(setCurrentPartPropertyFocus({ focus: true })); + }} key={index} index={index} option={option} feedback={value[index] || ''} onChange={OnOptionChanged(index)} + onFocusHandler={() => { + dispatch(setCurrentPartPropertyFocus({ focus: false })); + }} /> ); })} @@ -95,6 +101,7 @@ interface OptionFeedbackProps { index: number; onChange: (value: string) => void; onBlur: () => void; + onFocusHandler: () => void; } const OptionFeedback: React.FC = ({ option, @@ -102,6 +109,7 @@ const OptionFeedback: React.FC = ({ onBlur, feedback, onChange, + onFocusHandler, }) => { const labelOption = option || `Option ${index + 1}`; return ( @@ -112,6 +120,7 @@ const OptionFeedback: React.FC = ({ className="form-control" value={feedback} onChange={(e) => onChange(e.target.value)} + onFocus={onFocusHandler} /> ); diff --git a/assets/src/apps/authoring/components/RightMenu/RightMenu.tsx b/assets/src/apps/authoring/components/RightMenu/RightMenu.tsx index 2ab2d7bae2..059fea39ff 100644 --- a/assets/src/apps/authoring/components/RightMenu/RightMenu.tsx +++ b/assets/src/apps/authoring/components/RightMenu/RightMenu.tsx @@ -26,7 +26,7 @@ import { saveActivity } from '../../store/activities/actions/saveActivity'; import { updateSequenceItem } from '../../store/groups/layouts/deck/actions/updateSequenceItemFromActivity'; import { savePage } from '../../store/page/actions/savePage'; import { selectState as selectPageState } from '../../store/page/slice'; -import { selectCurrentSelection } from '../../store/parts/slice'; +import { selectCurrentSelection, setCurrentPartPropertyFocus } from '../../store/parts/slice'; import PropertyEditor from '../PropertyEditor/PropertyEditor'; import bankSchema, { bankUiSchema, @@ -231,6 +231,13 @@ const RightMenu: React.FC = () => { [currentLesson, dispatch], ); + const onfocusHandler = useCallback( + (partPropertyElementFocus: any) => { + dispatch(setCurrentPartPropertyFocus({ focus: partPropertyElementFocus })); + }, + [currentActivity, dispatch], + ); + return ( = () => { value={lessonData} triggerOnChange={['CustomLogic']} onChangeHandler={lessonPropertyChangeHandler} + onfocusHandler={onfocusHandler} /> @@ -258,6 +266,7 @@ const RightMenu: React.FC = () => { value={questionBankData} onChangeHandler={bankPropertyChangeHandler} triggerOnChange={true} + onfocusHandler={onfocusHandler} /> ) : null} @@ -269,6 +278,7 @@ const RightMenu: React.FC = () => { uiSchema={scrUiSchema as UiSchema} value={scrData} onChangeHandler={screenPropertyChangeHandler} + onfocusHandler={onfocusHandler} /> ) : null}