diff --git a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/index.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/index.vue
index 46e090adba..4e4051666b 100644
--- a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/index.vue
+++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/index.vue
@@ -26,6 +26,7 @@
:setTitle="setTitle"
:setGoBack="setGoBack"
:topic="topic"
+ :disabled="isSaving"
:channelsFetch="channelsFetch"
:bookmarksFetch="bookmarksFetch"
:treeFetch="treeFetch"
@@ -51,12 +52,25 @@
+
+
+ {{ $tr('closeConfirmationMessage') }}
+
@@ -101,8 +115,12 @@
function notifyResourcesAdded(count) {
createSnackbar(resourcesAddedWithCount$({ count }));
}
+ const { saveLessonError$ } = coachStrings;
+ function notifySaveLessonError() {
+ createSnackbar(saveLessonError$());
+ }
- const { saveAndFinishAction$ } = coreStrings;
+ const { saveAndFinishAction$, continueAction$, cancelAction$ } = coreStrings;
return {
loading,
@@ -116,6 +134,9 @@
deselectResources,
setSelectedResources,
notifyResourcesAdded,
+ notifySaveLessonError,
+ cancelAction$,
+ continueAction$,
saveAndFinishAction$,
};
},
@@ -123,6 +144,8 @@
return {
title: '',
goBack: null,
+ isSaving: false,
+ isCloseConfirmationOpen: false,
PageNames,
};
},
@@ -151,14 +174,8 @@
...mapMutations('lessonSummary', {
setWorkingResources: 'SET_WORKING_RESOURCES',
}),
- async saveAndClose() {
- if (this.selectedResources.length > 0) {
- await this.save();
- }
- this.closeSidePanel();
- },
- async save() {
- const newResources = uniqBy(
+ getNewResources() {
+ return uniqBy(
[
...this.workingResources,
...this.selectedResources.map(resource => ({
@@ -169,15 +186,29 @@
],
'contentnode_id',
);
+ },
+ async save() {
+ if (!this.selectedResources.length) {
+ this.closeSidePanel(false);
+ return;
+ }
+ this.isSaving = true;
+ const newResources = this.getNewResources();
// As we are just adding resources, we can rely on the difference in length
// to determine if there are new resources to save.
const countNewResources = newResources.length - this.workingResources.length;
if (countNewResources > 0) {
- await this.saveLessonResources({
- lessonId: this.currentLesson.id,
- resources: newResources,
- });
+ try {
+ await this.saveLessonResources({
+ lessonId: this.currentLesson.id,
+ resources: newResources,
+ });
+ } catch (error) {
+ this.notifySaveLessonError();
+ this.isSaving = false;
+ throw error;
+ }
for (const resource of this.selectedResources) {
this.addToResourceCache({ node: resource });
}
@@ -187,11 +218,18 @@
this.$emit('workingResourcesUpdated');
this.notifyResourcesAdded(countNewResources);
}
+ this.closeSidePanel(false);
},
- closeSidePanel() {
- this.$router.push({
- name: PageNames.LESSON_SUMMARY_BETTER,
- });
+ closeSidePanel(verifyHasNewResources = true) {
+ const newResources = this.getNewResources();
+ const hasNewResources = newResources.length > this.workingResources.length;
+ if (hasNewResources && verifyHasNewResources) {
+ this.isCloseConfirmationOpen = true;
+ } else {
+ this.$router.push({
+ name: PageNames.LESSON_SUMMARY_BETTER,
+ });
+ }
},
setTitle(title) {
this.title = title;
@@ -200,6 +238,18 @@
this.goBack = goBack;
},
},
+ $trs: {
+ closeConfirmationTitle: {
+ message: 'Are you sure you want to leave this page?',
+ context:
+ 'The title of a confirmation modal informing the user that they will lose their work if they leave the page',
+ },
+ closeConfirmationMessage: {
+ message: 'You will lose any unsaved edits to your work',
+ context:
+ 'Warning message for the user that they will lose their work if they leave the page without saving.',
+ },
+ },
};