Skip to content

Commit d6fcaf5

Browse files
authored
Merge pull request learningequality#5921 from akolson/new-rte-autofocus
Autofocus RTE when answer/hint editor opens
2 parents 30559f2 + 526b18e commit d6fcaf5

5 files changed

Lines changed: 64 additions & 4 deletions

File tree

contentcuration/contentcuration/frontend/channelEdit/components/AnswersEditor/AnswersEditor.spec.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { shallowMount, mount } from '@vue/test-utils';
33
import { AssessmentItemToolbarActions } from '../../constants';
44
import AnswersEditor from './AnswersEditor';
55
import { AssessmentItemTypes } from 'shared/constants';
6+
import TipTapEditor from 'shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue';
67

78
jest.mock('shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue');
89

@@ -245,6 +246,31 @@ describe('AnswersEditor', () => {
245246
});
246247
});
247248

249+
describe('autofocus on the open answer editor', () => {
250+
beforeEach(() => {
251+
wrapper = mount(AnswersEditor, {
252+
propsData: {
253+
questionKind: AssessmentItemTypes.SINGLE_SELECTION,
254+
answers: [
255+
{ answer: 'Mayonnaise (I mean you can, but...)', correct: true, order: 1 },
256+
{ answer: 'Peanut butter', correct: false, order: 2 },
257+
],
258+
openAnswerIdx: 1,
259+
},
260+
});
261+
});
262+
263+
it('passes autofocus=true to the open answer editor', () => {
264+
const editors = wrapper.findAllComponents(TipTapEditor);
265+
expect(editors.at(1).props('autofocus')).toBe(true);
266+
});
267+
268+
it('passes autofocus=false to closed answer editors', () => {
269+
const editors = wrapper.findAllComponents(TipTapEditor);
270+
expect(editors.at(0).props('autofocus')).toBe(false);
271+
});
272+
});
273+
248274
describe('on an answer click', () => {
249275
beforeEach(async () => {
250276
wrapper = mount(AnswersEditor, {
@@ -314,7 +340,7 @@ describe('AnswersEditor', () => {
314340
},
315341
});
316342

317-
const editors = wrapper.findAllComponents({ name: 'RichTextEditor' });
343+
const editors = wrapper.findAllComponents(TipTapEditor);
318344
editors.at(1).vm.$emit('update', 'European butter');
319345

320346
await wrapper.vm.$nextTick();

contentcuration/contentcuration/frontend/channelEdit/components/AnswersEditor/AnswersEditor.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
v-model="answer.answer"
9595
class="editor"
9696
:mode="isAnswerOpen(answerIdx) ? 'edit' : 'view'"
97+
:autofocus="isAnswerOpen(answerIdx)"
9798
:imageProcessor="EditorImageProcessor"
9899
@update="updateAnswerText($event, answerIdx)"
99100
@minimize="emitClose"
@@ -164,6 +165,7 @@
164165
v-model="answer.answer"
165166
class="editor"
166167
:mode="isAnswerOpen(answerIdx) ? 'edit' : 'view'"
168+
:autofocus="isAnswerOpen(answerIdx)"
167169
:imageProcessor="EditorImageProcessor"
168170
@update="updateAnswerText($event, answerIdx)"
169171
@minimize="emitClose"

contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.spec.js

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { shallowMount, mount } from '@vue/test-utils';
33
import { AssessmentItemToolbarActions } from '../../constants';
44

55
import HintsEditor from './HintsEditor';
6+
import TipTapEditor from 'shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue';
67

78
jest.mock('shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue');
89

@@ -65,7 +66,7 @@ describe('HintsEditor', () => {
6566
});
6667

6768
// Find all instances of your new RichTextEditor component
68-
const editors = wrapper.findAllComponents({ name: 'RichTextEditor' });
69+
const editors = wrapper.findAllComponents(TipTapEditor);
6970
expect(editors.length).toBe(2);
7071

7172
// Instead of checking the raw HTML, we check the `value` prop passed to each editor.
@@ -85,7 +86,7 @@ describe('HintsEditor', () => {
8586
},
8687
});
8788

88-
const editors = wrapper.findAllComponents({ name: 'RichTextEditor' });
89+
const editors = wrapper.findAllComponents(TipTapEditor);
8990
editors.at(1).vm.$emit('update', 'Updated hint');
9091
});
9192

@@ -131,6 +132,30 @@ describe('HintsEditor', () => {
131132
});
132133
});
133134

135+
describe('autofocus on the open hint editor', () => {
136+
beforeEach(() => {
137+
wrapper = mount(HintsEditor, {
138+
propsData: {
139+
hints: [
140+
{ hint: 'First hint', order: 1 },
141+
{ hint: 'Second hint', order: 2 },
142+
],
143+
openHintIdx: 0,
144+
},
145+
});
146+
});
147+
148+
it('passes autofocus=true to the open hint editor', () => {
149+
const editors = wrapper.findAllComponents(TipTapEditor);
150+
expect(editors.at(0).props('autofocus')).toBe(true);
151+
});
152+
153+
it('passes autofocus=false to closed hint editors', () => {
154+
const editors = wrapper.findAllComponents(TipTapEditor);
155+
expect(editors.at(1).props('autofocus')).toBe(false);
156+
});
157+
});
158+
134159
describe('on hint click', () => {
135160
beforeEach(async () => {
136161
wrapper = mount(HintsEditor, {

contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
<TipTapEditor
5252
v-model="hint.hint"
5353
:mode="isHintOpen(hintIdx) ? 'edit' : 'view'"
54+
:autofocus="isHintOpen(hintIdx)"
5455
:image-processor="EditorImageProcessor"
5556
@update="updateHintText($event, hintIdx)"
5657
@minimize="emitClose"
@@ -79,10 +80,11 @@
7980
<TipTapEditor
8081
v-model="hint.hint"
8182
:mode="isHintOpen(hintIdx) ? 'edit' : 'view'"
83+
:autofocus="isHintOpen(hintIdx)"
8284
:image-processor="EditorImageProcessor"
8385
@update="updateHintText($event, hintIdx)"
8486
@minimize="emitClose"
85-
@open-editor="emitOpen(answerIdx)"
87+
@open-editor="emitOpen(hintIdx)"
8688
/>
8789
</keep-alive>
8890
</transition>

contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,11 @@
205205
if (editor.value && editor.value.isEditable !== (newMode === 'edit')) {
206206
editor.value.setEditable(newMode === 'edit');
207207
}
208+
if (newMode === 'edit' && editor.value && props.autofocus) {
209+
nextTick(() => {
210+
editor.value?.commands.focus('end');
211+
});
212+
}
208213
},
209214
);
210215

0 commit comments

Comments
 (0)