Skip to content

Commit 3db474c

Browse files
committed
Adapt CourseUnitView when a test is active
1 parent 2c90478 commit 3db474c

File tree

3 files changed

+93
-9
lines changed

3 files changed

+93
-9
lines changed

kolibri/plugins/learn/frontend/views/CourseUnitView/UnitTreeAccordion/index.vue

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
:style="{
1212
backgroundColor: $themePalette.grey.v_100,
1313
}"
14+
:disabled="!activeTest || activeTest.testType !== TestType.PRE"
15+
:selected="activeTest && activeTest.testType === TestType.PRE"
1416
>
1517
<template #leading-actions>
1618
<KIcon
@@ -154,9 +156,12 @@
154156

155157
<TreeItem
156158
:title="postTestLabel$()"
159+
:description="postTestItemDescription"
160+
:disabled="!activeTest || activeTest.testType !== TestType.POST"
157161
:style="{
158162
backgroundColor: $themePalette.grey.v_100,
159163
}"
164+
:selected="activeTest && activeTest.testType === TestType.POST"
160165
>
161166
<template #leading-actions>
162167
<KIcon
@@ -168,7 +173,8 @@
168173
<template #trailing-actions>
169174
<KIcon
170175
class="item-icon"
171-
icon="notStarted"
176+
:icon="isPostTestCompleted ? 'mastered' : 'notStarted'"
177+
:color="isPostTestCompleted ? $themePalette.grey.v_400 : undefined"
172178
/>
173179
</template>
174180
</TreeItem>
@@ -188,9 +194,11 @@
188194
import { coreStrings } from 'kolibri/uiText/commonCoreStrings';
189195
import LearningActivityIcon from 'kolibri-common/components/ResourceDisplayAndSearch/LearningActivityIcon.vue';
190196
import TimeDuration from 'kolibri-common/components/TimeDuration.vue';
197+
import get from 'lodash/get';
191198
import { injectCourseContentProgress } from '../useCourseContentProgressTracking';
192199
import useContentNodeProgress from '../../../composables/useContentNodeProgress';
193200
import useBookmarks from '../../../composables/useBookmarks';
201+
import { TestType } from '../../../constants';
194202
import TreeItem from './TreeItem.vue';
195203
196204
export default {
@@ -221,6 +229,25 @@
221229
coursesStrings;
222230
const { completedLabel$, ratioLabel$, saveToBookmarks$, removeFromBookmarks$ } = coreStrings;
223231
232+
const isPostTestCompleted = computed(() => {
233+
if (props.isUnitComplete) {
234+
return true;
235+
}
236+
return props.activeTest?.testType === TestType.POST;
237+
});
238+
239+
const postTestItemDescription = computed(() => {
240+
if (isPostTestCompleted.value) {
241+
return completedLabel$();
242+
}
243+
const numQuestions = get(
244+
props.unitTree,
245+
'options.completion_criteria.threshold.pre_post_test.version_a_item_ids.length',
246+
0,
247+
);
248+
return ratioLabel$({ number: 0, total: numQuestions });
249+
});
250+
224251
const getLessonRatioLabel = lesson => {
225252
const lessonResources = lesson.children?.results || [];
226253
const totalResources = lessonResources.length || 0;
@@ -257,10 +284,13 @@
257284
};
258285
259286
return {
287+
TestType,
260288
lessons,
261289
contentNodeProgressMap,
262290
bookmarksMap,
291+
isPostTestCompleted,
263292
loadingBookmarksMap,
293+
postTestItemDescription,
264294
currentResourceProgressSessionReady,
265295
getResources,
266296
getLessonRatioLabel,
@@ -290,6 +320,18 @@
290320
type: String,
291321
default: null,
292322
},
323+
/**
324+
* Whether the current unit is already completed. i.e. we are seeing a
325+
* unit previous to the current unit in the unit tree.
326+
*/
327+
isUnitComplete: {
328+
type: Boolean,
329+
default: false,
330+
},
331+
activeTest: {
332+
type: Object,
333+
default: null,
334+
},
293335
/**
294336
* The maximum lft of the resource that can be seen in the unit tree
295337
*/

kolibri/plugins/learn/frontend/views/CourseUnitView/__mocks__/useCourseContentProgressTracking.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
* `useCourseContentProgressTracking` composable function mock.
33
*/
44

5+
import { computed } from 'vue';
6+
57
const MOCK_DEFAULTS = {
68
contentNodeProgressMap: {},
79
contentNodeProgressMetaDataMap: {},
@@ -18,15 +20,23 @@ export function useCourseContentProgressMock(overrides = {}) {
1820
}
1921

2022
const INJECT_DEFAULTS = {
21-
sessionReady: true,
22-
progress: 0,
23-
time_spent: 0,
24-
extra_fields: {},
23+
sessionReady: computed(() => true),
24+
progress: computed(() => 0),
25+
time_spent: computed(() => 0),
26+
extra_fields: computed(() => ({})),
27+
pastattempts: computed(() => []),
28+
complete: computed(() => false),
29+
context: computed(() => ({})),
30+
totalattempts: computed(() => 0),
31+
mastery_criterion: computed(() => null),
2532
startTrackingProgress: jest.fn(),
2633
stopTrackingProgress: jest.fn(),
34+
restartContentSession: jest.fn(),
2735
handleUpdateProgress: jest.fn(),
2836
handleAddProgress: jest.fn(),
37+
handleUpdateInteraction: jest.fn(),
2938
handleUpdateContentState: jest.fn(),
39+
updateContentSession: jest.fn(),
3040
onError: jest.fn(),
3141
};
3242

kolibri/plugins/learn/frontend/views/CourseUnitView/index.vue

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,10 @@
6363
v-if="unitTree"
6464
:maxResourceLft="maxResourceLft"
6565
:unitTree="unitTree"
66+
:activeTest="activeTest"
6667
:currentResourceId="currentResource && currentResource.id"
6768
:currentLessonId="currentLesson && currentLesson.id"
69+
:isUnitComplete="isUnitComplete"
6870
@finished="onResourceFinished"
6971
@navigateToResource="handleNavigateToResource"
7072
/>
@@ -203,8 +205,24 @@
203205
return courseUnits.value[currentUnitIndex.value + 1];
204206
});
205207
208+
const isUnitComplete = computed(() => {
209+
if (!resumeData.value || !resumeData.value.started) {
210+
// no data to make a decision
211+
return false;
212+
}
213+
// If current unit is different, it means that it is a previoius unit,
214+
if (resumeData.value.active_test) {
215+
return resumeData.value.active_test.unit_id !== props.unitId;
216+
}
217+
if (resumeData.value.resume_position) {
218+
return resumeData.value.resume_position.unit_id !== props.unitId;
219+
}
220+
// If no resume_position, it means the course is complete,
221+
return true;
222+
});
223+
206224
const canGoToNextUnit = computed(() => {
207-
if (!nextUnit.value) {
225+
if (!nextUnit.value || activeTest.value) {
208226
return false;
209227
}
210228
return props.unitId !== resumeData.value?.resume_position?.unit_id;
@@ -269,10 +287,19 @@
269287
return Number.MAX_SAFE_INTEGER;
270288
});
271289
272-
const prevEnabled = computed(() => currentResourceIndexInUnit.value > 0);
290+
const prevEnabled = computed(() => {
291+
if (activeTest.value) {
292+
return false;
293+
}
294+
return currentResourceIndexInUnit.value > 0;
295+
});
273296
274297
const nextEnabled = computed(() => {
275-
if (currentResourceIndexInUnit.value === null || maxResourceLft.value === null) {
298+
if (
299+
activeTest.value ||
300+
currentResourceIndexInUnit.value === null ||
301+
maxResourceLft.value === null
302+
) {
276303
return false;
277304
}
278305
if (currentResourceIndexInUnit.value >= unitResources.value.length - 1) {
@@ -307,7 +334,6 @@
307334
if (index >= 0) {
308335
return index;
309336
}
310-
// Shouldn't get here
311337
return null;
312338
});
313339
@@ -333,6 +359,10 @@
333359
};
334360
335361
const onResourceFinished = () => {
362+
if (activeTest.value) {
363+
// when active test, we do nothing when the learner finishes its pre/post test.
364+
return;
365+
}
336366
if (
337367
!resumeData.value?.resume_position ||
338368
// If finished resource is not the current resource in resume position
@@ -792,6 +822,8 @@
792822
previousAvailableResource,
793823
maxResourceLft,
794824
resourceLayoutRef,
825+
isUnitComplete,
826+
activeTest,
795827
handlePrev,
796828
handleNext,
797829
onResourceFinished,

0 commit comments

Comments
 (0)