157157 @update:options ="
158158 (val) => (form.questions[index].options = val)
159159 "
160- @clone =" cloneHere(index, question )"
160+ @clone =" cloneQuestion(question, index )"
161161 @delete =" deleteQuestion(question.id)"
162162 @moveDown =" onMoveDown(index)"
163163 @moveUp =" onMoveUp(index)" >
169169 :class =" [
170170 {
171171 'is-open':
172- insertMenuOpened
173- && pendingInsertIndex === index + 1,
172+ insertMenuOpenedIndex === index,
174173 },
175174 {
176175 'is-mobile': isMobile,
186185 )
187186 "
188187 variant="tertiary"
188+ :position =" index "
189189 :isLoadingQuestions =" isLoadingQuestions "
190190 :answerTypesFilter =" answerTypesFilter "
191191 :hasSubtypes =" hasSubtypes "
192192 @update :open ="
193- onInsertMenuUpdate ($event , index )
193+ (v ) =>
194+ (insertMenuOpenedIndex = v
195+ ? index
196+ : null )
194197 "
195198 @addQuestion =" addQuestion " />
196199 </div >
@@ -288,7 +291,7 @@ export default {
288291 questionRefsMap: {},
289292
290293 // when set to a number, the next created question will be inserted at this index
291- pendingInsertIndex : null ,
294+ insertMenuOpenedIndex : null ,
292295 // controls per-question insert menu visibility
293296 insertMenuOpened: false ,
294297 }
@@ -484,18 +487,18 @@ export default {
484487 *
485488 * @param {string} type the question type, see AnswerTypes
486489 * @param {string|null} subtype the question subtype, see AnswerTypes.subtypes
490+ * @param {number|null} position where the new question should be added
487491 */
488- async addQuestion (type , subtype = null ) {
492+ async addQuestion (type , subtype = null , position = null ) {
489493 this .activeQuestionType = null
490494 const text = ' '
491495 this .isLoadingQuestions = true
492496
493497 try {
494- // include optional position (1-based order) when inserting between questions
495498 const body = { type, text, subtype }
496- if (this . pendingInsertIndex !== null ) {
497- // backend expects 1-based position; pendingInsertIndex is array index to insert at
498- body .position = this . pendingInsertIndex + 1
499+ if (position !== null ) {
500+ // position: current question position + 2 (0-based index: +1, next position: +1)
501+ body .position = position + 2
499502 }
500503
501504 const response = await axios .post (
@@ -507,15 +510,14 @@ export default {
507510 const question = OcsResponse2Data (response)
508511
509512 // Delegate insertion & focus handling to helper
510- this .insertQuestion (question, { text, type, answers: [] })
513+ this .insertQuestion (question, { text, type, answers: [] }, position )
511514 } catch (error) {
512515 logger .error (' Error while adding new question' , { error })
513516 showError (
514517 t (' forms' , ' There was an error while adding the new question' ),
515518 )
516519 } finally {
517520 this .isLoadingQuestions = false
518- this .pendingInsertIndex = null
519521 }
520522 },
521523
@@ -554,7 +556,7 @@ export default {
554556 }
555557 },
556558
557- insertQuestion (questionData , defaultFields = {}) {
559+ insertQuestion (questionData , defaultFields = {}, position = null ) {
558560 const newQuestionObj = {
559561 ... defaultFields,
560562 ... questionData,
@@ -567,8 +569,8 @@ export default {
567569 && questionData .order !== null
568570 ) {
569571 insertAt = Number (questionData .order ) - 1
570- } else if (this . pendingInsertIndex !== null ) {
571- insertAt = this . pendingInsertIndex
572+ } else if (position !== null ) {
573+ insertAt = position
572574 }
573575
574576 if (insertAt !== null && insertAt <= this .form .questions .length ) {
@@ -577,7 +579,6 @@ export default {
577579 // Prefer ref by id when available, fallback to positional refs
578580 this .questionRefsMap [newQuestionObj .id ]? .focus ()
579581 })
580- this .pendingInsertIndex = null
581582 } else {
582583 this .form .questions .push (newQuestionObj)
583584 this .$nextTick (() => {
@@ -588,27 +589,13 @@ export default {
588589 emit (' forms:last-updated:set' , this .form .id )
589590 },
590591
591- onInsertMenuUpdate (val , index ) {
592- if (val) {
593- this .pendingInsertIndex = index + 1
594- } else {
595- this .pendingInsertIndex = null
596- }
597- this .insertMenuOpened = val
598- },
599-
600- cloneHere (index , question ) {
601- this .pendingInsertIndex = index + 1
602- this .cloneQuestion (question)
603- this .insertMenuOpened = false
604- },
605-
606592 /**
607593 * Clone a question
608594 *
609595 * @param {number} id the question id to clone in the current form
596+ * @param {number} position where the cloned question should be added
610597 */
611- async cloneQuestion ({ id }) {
598+ async cloneQuestion ({ id }, position ) {
612599 this .isLoadingQuestions = true
613600
614601 try {
@@ -621,8 +608,9 @@ export default {
621608 )
622609
623610 const body = {}
624- if (this .pendingInsertIndex !== null ) {
625- body .position = this .pendingInsertIndex + 1
611+ if (position !== null ) {
612+ // position: current question position + 2 (0-based index: +1, next position: +1)
613+ body .position = position + 2
626614 }
627615
628616 const response = await axios .post (url, body)
0 commit comments