diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py index 85ea0ba9681372a0c4aea3ec72ada2c0ba2da326..718d01be640280ee3f873375fb931f9945eb15fe 100644 --- a/addons/website_slides/controllers/main.py +++ b/addons/website_slides/controllers/main.py @@ -61,6 +61,9 @@ class WebsiteSlides(WebsiteProfile): return True def _set_completed_slide(self, slide, quiz_attempts_inc=False): + # quiz use their specific mechanism to be marked as done + if slide.slide_type == 'quiz' or slide.question_ids: + raise werkzeug.exceptions.Forbidden(_("Slide with questions must be marked as done when submitting all good answers ")) if slide.website_published and slide.channel_id.is_member: slide.action_set_completed(quiz_attempts_inc=quiz_attempts_inc) return True @@ -662,6 +665,7 @@ class WebsiteSlides(WebsiteProfile): rank_progress = {} if not user_bad_answers: slide._action_set_quiz_done() + slide.action_set_completed(quiz_attempts_inc=True) lower_bound = request.env.user.rank_id.karma_min upper_bound = request.env.user.next_rank_id.karma_min rank_progress = { @@ -674,11 +678,12 @@ class WebsiteSlides(WebsiteProfile): return { 'goodAnswers': user_good_answers.ids, 'badAnswers': user_bad_answers.ids, - 'completed': not user_bad_answers, + 'completed': slide.user_membership_id.sudo().completed, + 'channel_completion': slide.channel_id.completion, 'quizKarmaWon': quiz_info['quiz_karma_won'], 'quizKarmaGain': quiz_info['quiz_karma_gain'], 'quizAttemptsCount': quiz_info['quiz_attempts_count'], - 'rankProgress': rank_progress + 'rankProgress': rank_progress, } # -------------------------------------------------- diff --git a/addons/website_slides/static/src/js/slides_course_fullscreen_player.js b/addons/website_slides/static/src/js/slides_course_fullscreen_player.js index a83df8a01cd59855f299bde126cd73375dc82e42..30d23f20f2fadb90064708eeb417d62de1e6d4cc 100644 --- a/addons/website_slides/static/src/js/slides_course_fullscreen_player.js +++ b/addons/website_slides/static/src/js/slides_course_fullscreen_player.js @@ -102,7 +102,7 @@ odoo.define('website_slides.fullscreen', function (require) { if (totalTime && currentTime > totalTime - 30){ clearInterval(self.tid); if (!self.slide.hasQuestion && !self.slide.completed){ - self.trigger_up('slide_completed', self.slide); + self.trigger_up('slide_to_complete', self.slide); } } } @@ -289,8 +289,8 @@ odoo.define('website_slides.fullscreen', function (require) { }, custom_events: { 'change_slide': '_onChangeSlideRequest', + 'slide_to_complete': '_onSlideToComplete', 'slide_completed': '_onSlideCompleted', - 'quiz_completed': '_onSlideCompleted', 'slide_go_next': '_onSlideGoToNext', }, /** @@ -367,11 +367,17 @@ odoo.define('website_slides.fullscreen', function (require) { */ _fetchSlideContent: function (){ var slide = this.get('slide'); - if (slide.type === 'webpage') { + if (slide.type === 'webpage' && !slide.isQuiz) { return this._fetchHtmlContent(); } return $.when(); }, + _markAsCompleted: function (slideId, completion) { + var slide = findSlide(this.slides, {id: slideId}); + slide.completed = true; + this.sidebar.setSlideCompleted(slide.id); + this.sidebar.updateProgressbar(completion); + }, /** * Extend the slide data list to add informations about rendering method, and other * specific values according to their slide_type. @@ -459,9 +465,7 @@ odoo.define('website_slides.fullscreen', function (require) { slide_id: slide.id, } }).then(function (data){ - slide.completed = true; - self.sidebar.setSlideCompleted(slide.id); - self.sidebar.updateProgressbar(data.channel_completion); + self._markAsCompleted(slideId, data.channel_completion); }); } return $.when(); @@ -504,13 +508,23 @@ odoo.define('website_slides.fullscreen', function (require) { }); this.set('slide', newSlide); }, + /** + * Triggered when subwidget has mark the slide as done, and the UI need to be adapted. + * + * @private + */ + _onSlideCompleted: function (ev) { + var slide = ev.data.slide; + var completion = ev.data.completion; + this._markAsCompleted(slide.id, completion); + }, /** * Triggered when sub widget business is done and that slide * can now be marked as done. * * @private */ - _onSlideCompleted: function (ev) { + _onSlideToComplete: function (ev) { if (!session.is_website_user) { // no useless RPC call var slideId = ev.data.id; this._setCompleted(slideId); diff --git a/addons/website_slides/static/src/js/slides_course_quiz.js b/addons/website_slides/static/src/js/slides_course_quiz.js index c969e38623bd244cbd272a3c1cf7a6a47f804cc3..9e2b9b7ece50081cf4ea767fc9b9236abc96add2 100644 --- a/addons/website_slides/static/src/js/slides_course_quiz.js +++ b/addons/website_slides/static/src/js/slides_course_quiz.js @@ -177,15 +177,6 @@ odoo.define('website_slides.quiz', function (require) { QWeb.render('slide.slide.quiz.validation', {'widget': this}) ); }, - - /** - * Set the slide as completed and done. Trigger up the completion. - * - * @param {Integer} completion - */ - _setCompleted: function () { - this.trigger_up('quiz_completed', this.slide); - }, /* * Submit the given answer, and display the result * @@ -203,13 +194,12 @@ odoo.define('website_slides.quiz', function (require) { if (data.error) { self._alertShow(data.error); } else { - self.slide.completed = data.completed; self.quiz = _.extend(self.quiz, data); self._renderAnswersHighlighting(); self._renderValidationInfo(); - if (self.slide.completed) { + if (data.completed) { self._renderSuccessModal(data); - self._setCompleted(); + self.trigger_up('slide_completed', {slide: self.slide, completion: data.channel_completion}); } } }); @@ -266,10 +256,10 @@ odoo.define('website_slides.quiz', function (require) { }); sAnimations.registry.websiteSlidesQuizNoFullscreen = sAnimations.Class.extend({ - selector: '.o_wslides_js_lesson_quiz', + selector: '.o_wslides_lesson_main', // selector of complete page, as we need slide content and aside content table custom_events: { slide_go_next: '_onQuizNextSlide', - quiz_completed: '_onQuizCompleted', + slide_completed: '_onQuizCompleted', }, //---------------------------------------------------------------------- @@ -282,8 +272,9 @@ odoo.define('website_slides.quiz', function (require) { */ start: function () { var self = this; + this.quizWidgets = []; var defs = [this._super.apply(this, arguments)]; - $('.o_wslides_js_lesson_quiz').each(function () { + this.$('.o_wslides_js_lesson_quiz').each(function () { var slideData = $(this).data(); slideData.quizData = { questions: self._extractQuestionsAndAnswers(), @@ -300,13 +291,17 @@ odoo.define('website_slides.quiz', function (require) { //---------------------------------------------------------------------- // Handlers //--------------------------------------------------------------------- - - _onQuizCompleted: function (slideId) { - console.log('set completed', slideId); + _onQuizCompleted: function (ev) { + var self = this; + var slide = ev.data.slide; + var completion = ev.data.completion; + this.$('#o_wslides_lesson_aside_slide_check_' + slide.id).addClass('text-success fa-check-circle').removeClass('text-600 fa-circle-o'); + // need to use global selector as progress bar is ouside this animation widget scope + $('.o_wslides_lesson_header .progress-bar').css('width', completion + "%"); + $('.o_wslides_lesson_header .progress span').text(_.str.sprintf("%s %%", completion)); }, - _onQuizNextSlide: function () { - var url = this.$el.data('next-slide-url'); + var url = this.$('.o_wslides_js_lesson_quiz').data('next-slide-url'); window.location.replace(url); }, diff --git a/addons/website_slides_survey/controllers/slides.py b/addons/website_slides_survey/controllers/slides.py index 9396de502b8da4e7348e07575734c2f48f2efa0b..a7dad0b175d108ef828e4d33a1056cde48f54239 100644 --- a/addons/website_slides_survey/controllers/slides.py +++ b/addons/website_slides_survey/controllers/slides.py @@ -1,8 +1,10 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.addons.website_slides.controllers.main import WebsiteSlides +import werkzeug +from odoo.addons.website_slides.controllers.main import WebsiteSlides +from odoo import _ from odoo.http import request @@ -49,6 +51,13 @@ class WebsiteSlides(WebsiteSlides): return result + # Utils + # --------------------------------------------------- + def _set_completed_slide(self, slide, quiz_attempts_inc=False): + if slide.slide_type == 'certification': + raise werkzeug.exceptions.Forbidden(_("Certification slides are completed when the survey is succeeded.")) + return super(WebsiteSlides, self)._set_completed_slide(slide, quiz_attempts_inc=quiz_attempts_inc) + # Profile # --------------------------------------------------- def _prepare_user_slides_profile(self, user):