diff options
| author | Florent Lejoly <fle@odoo.com> | 2019-11-27 12:51:28 +0000 |
|---|---|---|
| committer | Thibault Delavallée <tde@odoo.com> | 2020-04-16 10:26:32 +0000 |
| commit | 24033e4aaf65a52fedaa13fc0846eb745238f09d (patch) | |
| tree | c15a062d15ba6d1776ad2a4fee237735d6951d51 | |
| parent | dd53c515c8c4d63ec714c765db911f2407bae175 (diff) | |
[IMP] website_slides,_survey: allow certification creation at frontend
Purpose
=======
Before this commit, in the front end, you had to create a certification before
adding it to a course. This commit allows creation of certification in
front-end with pre-filled settings.
Functional Spec
===============
1. On a course, add content, type certification, you can choose an existing one
(normal flow) or create a new one in the dropdown by typing a new survey
name (new flow).
3. When submitting (Publish or save as draft), a certification survey, with
pre-filled settings is created and linked to the slide.
Pre-filled settings:
* One page per question
* Attempts limit : 1
* Time limit : no limit
* Scoring without answers
* Passing score : 70%
* Is Certification : True
* Email Template : Certification: Send by email
* Give Badge : False
4. After submit, the user stays on the Course Content.
5. A toaster is displayed in the top right saying:
Toaster's Title: Certification created
Content: Follow this link to add questions to your certification.
<a>Edit certification</a>
A website editor can select a certification (if available) for the creation of
a slide.
Task id: 1981399
PR #43577
Co-Authored-By: Florent Lejoly <fle@odoo.com>
Co-Authored-By: David Beguin <dbe@odoo.com>
6 files changed, 167 insertions, 27 deletions
diff --git a/addons/website_slides_survey/controllers/main.py b/addons/website_slides_survey/controllers/main.py index cda54c29322..a0b4cf9b53c 100644 --- a/addons/website_slides_survey/controllers/main.py +++ b/addons/website_slides_survey/controllers/main.py @@ -1,13 +1,67 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import http +from odoo import http, _ from odoo.http import request +from odoo.exceptions import AccessError +from odoo.addons.website_slides.controllers.main import WebsiteSlides + + +class WebsiteSlidesSurvey(WebsiteSlides): -class WebsiteSlidesSurvey(http.Controller): @http.route(['/slides_survey/certification/search_read'], type='json', auth='user', methods=['POST'], website=True) def slides_certification_search_read(self, fields): + can_create = request.env['survey.survey'].check_access_rights('create', raise_exception=False) return { 'read_results': request.env['survey.survey'].search_read([('certification', '=', True)], fields), + 'can_create': can_create, } + + # ------------------------------------------------------------ + # Overrides + # ------------------------------------------------------------ + + @http.route(['/slides/add_slide'], type='json', auth='user', methods=['POST'], website=True) + def create_slide(self, *args, **post): + create_new_survey = post['slide_type'] == "certification" and post.get('survey') and not post['survey']['id'] + linked_survey_id = int(post.get('survey', {}).get('id') or 0) + + if create_new_survey: + # If user cannot create a new survey, no need to create the slide either. + if not request.env['survey.survey'].check_access_rights('create', raise_exception=False): + return {'error': _('You are not allowed to create a survey.')} + + # Create survey first as certification slide needs a survey_id (constraint) + post['survey_id'] = request.env['survey.survey'].create({ + 'title': post['survey']['title'], + 'background_image': post['image_1920'], + 'questions_layout': 'page_per_question', + 'is_attempts_limited': True, + 'attempts_limit': 1, + 'is_time_limited': False, + 'scoring_type': 'scoring_without_answers', + 'certification': True, + 'scoring_success_min': 70.0, + 'certification_mail_template_id': request.env.ref('survey.mail_template_certification').id, + }).id + elif linked_survey_id: + try: + request.env['survey.survey'].browse([linked_survey_id]).read(['title']) + except AccessError: + return {'error': _('You are not allowed to link a certification.')} + + post['survey_id'] = post['survey']['id'] + + # Then create the slide + result = super(WebsiteSlidesSurvey, self).create_slide(*args, **post) + + if create_new_survey: + # Set the redirect_url used in toaster + action_id = request.env.ref('survey.action_survey_form').id + result.update({ + 'redirect_url': '/web#id=%s&action=%s&model=survey.survey&view_type=form' % (post['survey_id'], action_id), + 'redirect_to_certification': True + }) + + return result diff --git a/addons/website_slides_survey/static/src/js/slides_certification_upload_toast.js b/addons/website_slides_survey/static/src/js/slides_certification_upload_toast.js new file mode 100644 index 00000000000..e258201bc79 --- /dev/null +++ b/addons/website_slides_survey/static/src/js/slides_certification_upload_toast.js @@ -0,0 +1,39 @@ +odoo.define('website_slides_survey.certification_upload_toast', function (require) { +'use strict'; + +var publicWidget = require('web.public.widget'); + +var sessionStorage = window.sessionStorage; +var core = require('web.core'); +var _t = core._t; + + +publicWidget.registry.CertificationUploadToast = publicWidget.Widget.extend({ + selector: '.o_wslides_survey_certification_upload_toast', + + /** + * @override + */ + start: function () { + var self = this; + this._super.apply(this, arguments).then(function () { + var url = sessionStorage.getItem("survey_certification_url"); + if (url) { + self.displayNotification({ + type: 'info', + title: _t('Certification created'), + message: _.str.sprintf( + _t('Follow this link to add questions to your certification. <a href="%s">Edit certification</a>'), + url + ), + sticky: true, + }); + sessionStorage.removeItem("survey_certification_url"); + } + }); + }, +}); + +return publicWidget.registry.CertificationUploadToast; + +}); diff --git a/addons/website_slides_survey/static/src/js/slides_upload.js b/addons/website_slides_survey/static/src/js/slides_upload.js index 817f80004c0..54dc18da723 100644 --- a/addons/website_slides_survey/static/src/js/slides_upload.js +++ b/addons/website_slides_survey/static/src/js/slides_upload.js @@ -3,12 +3,34 @@ odoo.define('website_slides_survey.upload_modal', function (require) { var core = require('web.core'); var _t = core._t; +var sessionStorage = window.sessionStorage; var SlidesUpload = require('website_slides.upload_modal'); /** * Management of the new 'certification' slide_type */ SlidesUpload.SlideUploadDialog.include({ + events: _.extend({}, SlidesUpload.SlideUploadDialog.prototype.events || {}, { + 'change input#certification_id': '_onChangeCertification' + }), + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * Will automatically set the title of the slide to the title of the chosen certification + */ + _onChangeCertification: function (ev) { + if (ev.added && ev.added.text) { + this.$("input#name").val(ev.added.text); + } + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + /** * Overridden to add the "certification" slide type * @@ -56,7 +78,7 @@ SlidesUpload.SlideUploadDialog.include({ var result = this._super.apply(this, arguments); var $certificationInput = this.$('#certification_id'); - if ($certificationInput.length !== 0){ + if ($certificationInput.length !== 0) { var $select2Container = $certificationInput .closest('.form-group') .find('.select2-container'); @@ -76,15 +98,38 @@ SlidesUpload.SlideUploadDialog.include({ * @override * @private */ - _getSelect2DropdownValues: function (){ + _getSelect2DropdownValues: function () { var result = this._super.apply(this, arguments); var certificateValue = this.$('#certification_id').select2('data'); + var survey = {}; if (certificateValue) { - result['survey_id'] = certificateValue.id; + if (certificateValue.create) { + survey.id = false; + survey.title = certificateValue.text; + } else { + survey.id = certificateValue.id; + } } + result['survey'] = survey; return result; - } + }, + + /** + * Overridde to handle certification created on-the-fly: toaster will hold + * survey edit url, need to put it in session to use it in CertificationUploadToast + * + * @override + * @private + */ + _onFormSubmitDone: function (data) { + if (!data.error && data.redirect_to_certification) { + sessionStorage.setItem("survey_certification_url", data.redirect_url); + window.location.reload(); + } else { + this._super.apply(this, arguments); + } + }, }); SlidesUpload.websiteSlidesUpload.include({ diff --git a/addons/website_slides_survey/static/src/xml/website_slide_upload.xml b/addons/website_slides_survey/static/src/xml/website_slide_upload.xml index 0b273a15b21..073a16277c3 100644 --- a/addons/website_slides_survey/static/src/xml/website_slide_upload.xml +++ b/addons/website_slides_survey/static/src/xml/website_slide_upload.xml @@ -3,33 +3,28 @@ <t t-name="website.slide.upload.modal.certification"> <div> <form class="clearfix"> - <div class="form-group row"> - <label for="certification_id" class="col-form-label col-md-3">Certification</label> - <div class="controls col-md-9"> - <input class="form-control" id="certification_id" required="required"/> + <div class="row"> + <div class="col" id="o_wslides_js_slide_upload_left_column"> + <div class="form-group"> + <label for="certification_id" class="col-form-label col-md-3">Certification</label> + <input class="form-control" id="certification_id" required="required"/> + </div> + <div class="form-group"> + <label for="upload" class="col-form-label">Choose an Image</label> + <input id="upload" class="form-control" data-prevent-onchange='true' name="file" accept="image/*" type="file" required="required"/> + </div> + <t t-call="website.slide.upload.modal.common"/> + <canvas id="data_canvas" class="d-none"></canvas> </div> - </div> - <t t-call="website.slide.upload.modal.common"/> - <div class="form-group row"> - <div class="col-md-4"> + + <div id="o_wslides_js_slide_upload_preview_column" class="col-md-6 d-none"> <div class="img-thumbnail"> <div class="o_slide_preview"> <img src="/website_slides/static/src/img/document.png" id="slide-image" title="Content Preview" alt="Content Preview" class="img-fluid"/> </div> </div> - </div> - <div class="col-md-8"> - <ul class="list-group"> - <li class="list-group-item"> - <h5 class="list-group-item-heading"> - <label for="upload" class="col-form-label">Cover Image File</label> - </h5> - <input id="upload" name="file" class="form-control" accept="image/*" type="file" required="required" data-prevent-onchange="1"/> - </li> - </ul> - </div> - </div> - <canvas id="data_canvas" class="d-none"></canvas> + </div> + </div> </form> </div> </t> diff --git a/addons/website_slides_survey/views/assets.xml b/addons/website_slides_survey/views/assets.xml index 40eae653970..5b8fd3a0530 100644 --- a/addons/website_slides_survey/views/assets.xml +++ b/addons/website_slides_survey/views/assets.xml @@ -8,6 +8,7 @@ <xpath expr="//script[last()]" position="after"> <script type="text/javascript" src="/website_slides_survey/static/src/js/slides_upload.js"/> <script type="text/javascript" src="/website_slides_survey/static/src/js/slides_course_fullscreen_player.js"/> + <script type="text/javascript" src="/website_slides_survey/static/src/js/slides_certification_upload_toast.js"/> </xpath> </template> </data> diff --git a/addons/website_slides_survey/views/website_slides_templates_course.xml b/addons/website_slides_survey/views/website_slides_templates_course.xml index 7dcd3d79586..1e6521836c1 100644 --- a/addons/website_slides_survey/views/website_slides_templates_course.xml +++ b/addons/website_slides_survey/views/website_slides_templates_course.xml @@ -32,5 +32,11 @@ <attribute name="t-if">channel.can_upload and not slide.question_ids and slide.slide_type != 'certification'</attribute> </xpath> </template> + + <template id="course_slides_list_inherit_survey" inherit_id="website_slides.course_slides_list"> + <xpath expr="//div[hasclass('o_wslides_content_actions')]" position="inside"> + <div class="o_wslides_survey_certification_upload_toast"/> + </xpath> + </template> </data> </odoo> |
