Skip to content

Commit 2c3f9de

Browse files
committed
simplify inserting questions
Signed-off-by: Christian Hartmann <chris-hartmann@gmx.de>
1 parent 11d81e5 commit 2c3f9de

2 files changed

Lines changed: 30 additions & 41 deletions

File tree

src/components/AddQuestionMenu.vue

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
:disabled="isLoadingQuestions"
2525
:isMenu="hasSubtypes(answer)"
2626
class="question-menu__question"
27-
@click="onPrimaryClick(answer, type)">
27+
@click="onPrimaryClick(answer, type, position)">
2828
<template #icon>
2929
<NcIconSvgWrapper :svg="answer.icon" />
3030
</template>
@@ -51,7 +51,7 @@
5151
closeAfterClick
5252
:disabled="isLoadingQuestions"
5353
class="question-menu__question"
54-
@click="onSubtypeClick(activeQuestionType, type)">
54+
@click="onSubtypeClick(activeQuestionType, type, position)">
5555
<template #icon>
5656
<NcIconSvgWrapper :svg="answer.icon" />
5757
</template>
@@ -88,12 +88,13 @@ export default {
8888
ariaLabel: { type: String, default: null },
8989
variant: { type: String, default: null },
9090
primary: { type: Boolean, default: false },
91+
position: { type: Number, default: null },
9192
isLoadingQuestions: { type: Boolean, default: false },
9293
answerTypesFilter: { type: Object, required: true },
9394
hasSubtypes: { type: Function, required: true },
9495
},
9596
96-
emits: ['update:open', 'add-question', 'addQuestion'],
97+
emits: ['update:open', 'addQuestion'],
9798
9899
setup() {
99100
return {
@@ -121,17 +122,17 @@ export default {
121122
},
122123
123124
methods: {
124-
onPrimaryClick(answer, type) {
125+
onPrimaryClick(answer, type, position) {
125126
if (this.hasSubtypes(answer)) {
126127
this.activeQuestionType = type
127128
return
128129
}
129-
this.$emit('addQuestion', type, null)
130+
this.$emit('addQuestion', type, null, position)
130131
this.openLocal = false
131132
},
132133
133-
onSubtypeClick(type, subtype) {
134-
this.$emit('addQuestion', type, subtype)
134+
onSubtypeClick(type, subtype, position) {
135+
this.$emit('addQuestion', type, subtype, position)
135136
this.openLocal = false
136137
},
137138
},

src/views/Create.vue

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@
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)">
@@ -169,8 +169,7 @@
169169
:class="[
170170
{
171171
'is-open':
172-
insertMenuOpened
173-
&& pendingInsertIndex === index + 1,
172+
insertMenuOpenedIndex === index,
174173
},
175174
{
176175
'is-mobile': isMobile,
@@ -186,11 +185,15 @@
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

Comments
 (0)