Skip to content

Commit 6f0222c

Browse files
authored
Merge branch 'learningequality:unstable' into unstable
2 parents e6bbdd4 + 02442bd commit 6f0222c

File tree

35 files changed

+923
-228
lines changed

35 files changed

+923
-228
lines changed

contentcuration/contentcuration/frontend/channelEdit/components/AssessmentEditor/AssessmentEditor.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
:item="item"
4646
:errors="itemErrors(item)"
4747
:openDialog="openDialog"
48+
:nodeId="nodeId"
4849
data-test="editor"
4950
@update="onItemUpdate"
5051
@close="closeActiveItem"
@@ -207,7 +208,6 @@
207208
if (!this.items) {
208209
return [];
209210
}
210-
211211
return [...this.items].sort((item1, item2) => (item1.order > item2.order ? 1 : -1));
212212
},
213213
firstItem() {

contentcuration/contentcuration/frontend/channelEdit/components/AssessmentItemEditor/AssessmentItemEditor.vue

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
</VFlex>
6767
</VLayout>
6868

69-
<VLayout mt-4>
69+
<VLayout v-if="kind !== AssessmentItemTypes.FREE_RESPONSE" mt-4>
7070
<VFlex>
7171
<ErrorList
7272
:errors="answersErrorMessages"
@@ -112,7 +112,12 @@
112112
import translator from '../../translator';
113113
import { updateAnswersToQuestionType, assessmentItemKey } from '../../utils';
114114
import { AssessmentItemTypeLabels } from '../../constants';
115-
import { AssessmentItemTypes, ValidationErrors } from 'shared/constants';
115+
import {
116+
ContentModalities,
117+
AssessmentItemTypes,
118+
ValidationErrors,
119+
FeatureFlagKeys,
120+
} from 'shared/constants';
116121
import ErrorList from 'shared/views/ErrorList/ErrorList';
117122
import Uploader from 'shared/views/files/Uploader';
118123
import MarkdownEditor from 'shared/views/MarkdownEditor/MarkdownEditor/MarkdownEditor';
@@ -147,6 +152,10 @@
147152
* ...
148153
* }
149154
*/
155+
nodeId: {
156+
type: String,
157+
required: true,
158+
},
150159
item: {
151160
type: Object,
152161
default: null,
@@ -184,10 +193,13 @@
184193
openHintIdx: null,
185194
openAnswerIdx: null,
186195
kindSelectKey: 0,
196+
AssessmentItemTypes,
187197
};
188198
},
189199
computed: {
190200
...mapGetters('file', ['getFileUpload']),
201+
...mapGetters(['hasFeatureEnabled']),
202+
...mapGetters('contentNode', ['getContentNode']),
191203
question() {
192204
if (!this.item || !this.item.question) {
193205
return '';
@@ -198,6 +210,9 @@
198210
imagePreset() {
199211
return FormatPresetsNames.EXERCISE_IMAGE;
200212
},
213+
modality() {
214+
return this.getContentNode(this.nodeId)?.extra_fields?.options?.modality;
215+
},
201216
kind() {
202217
if (!this.item || !this.item.type) {
203218
return AssessmentItemTypes.SINGLE_SELECTION;
@@ -206,7 +221,7 @@
206221
return this.item.type;
207222
},
208223
kindSelectItems() {
209-
return [
224+
const items = [
210225
{
211226
value: AssessmentItemTypes.SINGLE_SELECTION,
212227
text: translator.$tr(AssessmentItemTypeLabels[AssessmentItemTypes.SINGLE_SELECTION]),
@@ -224,6 +239,18 @@
224239
text: translator.$tr(AssessmentItemTypeLabels[AssessmentItemTypes.TRUE_FALSE]),
225240
},
226241
];
242+
243+
if (
244+
this.hasFeatureEnabled(FeatureFlagKeys.survey) &&
245+
this.modality === ContentModalities.SURVEY
246+
) {
247+
items.push({
248+
value: AssessmentItemTypes.FREE_RESPONSE,
249+
text: translator.$tr(AssessmentItemTypeLabels[AssessmentItemTypes.FREE_RESPONSE]),
250+
});
251+
}
252+
253+
return items;
227254
},
228255
answers() {
229256
if (!this.item || !this.item.answers) {
@@ -244,8 +271,12 @@
244271
245272
if (this.errors && this.errors.includes(ValidationErrors.QUESTION_REQUIRED)) {
246273
errorMessages.push(translator.$tr(`errorQuestionRequired`));
274+
} else if (
275+
this.errors &&
276+
this.errors.includes(ValidationErrors.INVALID_COMPLETION_TYPE_FOR_FREE_RESPONSE_QUESTION)
277+
) {
278+
errorMessages.push(translator.$tr(`errorInvalidQuestionType`));
247279
}
248-
249280
return errorMessages;
250281
},
251282
answersErrorMessages() {
@@ -292,12 +323,10 @@
292323
...assessmentItemKey(this.item),
293324
...payload,
294325
};
295-
296326
this.$emit('update', payload);
297327
},
298328
changeKind(newKind) {
299329
const newAnswers = updateAnswersToQuestionType(newKind, this.answers);
300-
301330
this.closeAnswer();
302331
this.updateItem({
303332
type: newKind,
@@ -365,6 +394,21 @@
365394
366395
break;
367396
397+
case AssessmentItemTypes.FREE_RESPONSE:
398+
if (typeof this.openDialog === 'function' && this.answers.length > 0) {
399+
this.openDialog({
400+
title: this.$tr('dialogTitle'),
401+
message: this.$tr('dialogMessageChangeToFreeResponse'),
402+
submitLabel: this.$tr('dialogSubmitBtnLabel'),
403+
onSubmit: () => this.changeKind(newKind),
404+
onCancel: this.rerenderKindSelect,
405+
});
406+
} else {
407+
this.changeKind(newKind);
408+
}
409+
410+
break;
411+
368412
default:
369413
this.changeKind(newKind);
370414
break;
@@ -415,6 +459,8 @@
415459
"Switching to 'true or false' will remove all current answers. Continue?",
416460
dialogMessageChangeToInput:
417461
"Switching to 'numeric input' will set all answers as correct and remove all non-numeric answers. Continue?",
462+
dialogMessageChangeToFreeResponse:
463+
"Switching to 'free response' will remove all current answers. Continue?",
418464
},
419465
};
420466

contentcuration/contentcuration/frontend/channelEdit/components/AssessmentTab/AssessmentTab.vue

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,21 +91,26 @@
9191
return this.getAssessmentItems(this.nodeId);
9292
},
9393
areAssessmentItemsValid() {
94-
return this.getAssessmentItemsAreValid({ contentNodeId: this.nodeId, ignoreDelayed: true });
94+
return this.getAssessmentItemsAreValid({
95+
contentNodeId: this.nodeId,
96+
ignoreDelayed: true,
97+
});
9598
},
9699
assessmentItemsErrors() {
97-
return this.getAssessmentItemsErrors({ contentNodeId: this.nodeId, ignoreDelayed: true });
100+
const errorMap = this.getAssessmentItemsErrors({
101+
contentNodeId: this.nodeId,
102+
ignoreDelayed: true,
103+
});
104+
return errorMap;
98105
},
99106
invalidItemsErrorMessage() {
100107
const invalidItemsCount = this.getInvalidAssessmentItemsCount({
101108
contentNodeId: this.nodeId,
102109
ignoreDelayed: true,
103110
});
104-
105111
if (!invalidItemsCount) {
106112
return '';
107113
}
108-
109114
return this.$tr('incompleteItemsCountMessage', { invalidItemsCount });
110115
},
111116
},

contentcuration/contentcuration/frontend/channelEdit/components/edit/EditModal.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,4 +675,8 @@
675675
margin-top: -4px !important;
676676
}
677677
678+
::v-deep .v-dialog__content {
679+
z-index: 5 !important;
680+
}
681+
678682
</style>

contentcuration/contentcuration/frontend/channelEdit/components/edit/EditView.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,11 @@
7878
</li>
7979
</ul>
8080
</VAlert>
81-
<DetailsTabView :key="nodeIds.join('-')" ref="detailsTab" :nodeIds="nodeIds" />
81+
<DetailsTabView
82+
:key="nodeIds.join('-')"
83+
ref="detailsTab"
84+
:nodeIds="nodeIds"
85+
/>
8286
</VTabItem>
8387
<VTabItem :key="tabs.QUESTIONS" ref="questionwindow" :value="tabs.QUESTIONS" lazy>
8488
<AssessmentTab :nodeId="nodeIds[0]" />

contentcuration/contentcuration/frontend/channelEdit/constants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export const AssessmentItemTypeLabels = {
4848
[AssessmentItemTypes.TRUE_FALSE]: 'questionTypeTrueFalse',
4949
[AssessmentItemTypes.INPUT_QUESTION]: 'questionTypeInput',
5050
[AssessmentItemTypes.PERSEUS_QUESTION]: 'questionTypePerseus',
51+
[AssessmentItemTypes.FREE_RESPONSE]: 'questionTypeFreeResponse',
5152
};
5253

5354
export const TabNames = {

contentcuration/contentcuration/frontend/channelEdit/translator.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ const MESSAGES = {
1010
questionTypeTrueFalse: 'True/False',
1111
questionTypeInput: 'Numeric input',
1212
questionTypePerseus: 'Perseus',
13+
questionTypeFreeResponse: 'Free response',
1314
errorQuestionRequired: 'Question is required',
15+
errorInvalidQuestionType: 'Invalid question type',
1416
errorMissingAnswer: 'Choose a correct answer',
1517
errorChooseAtLeastOneCorrectAnswer: 'Choose at least one correct answer',
1618
errorProvideAtLeastOneCorrectAnswer: 'Provide at least one correct answer',

contentcuration/contentcuration/frontend/channelEdit/utils.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ export function updateAnswersToQuestionType(questionType, answers) {
9393
}
9494
}
9595

96+
if (questionType === AssessmentItemTypes.FREE_RESPONSE) {
97+
return [];
98+
}
99+
96100
const answersCopy = JSON.parse(JSON.stringify(answers));
97101

98102
switch (questionType) {

0 commit comments

Comments
 (0)