From 2ab0bd3236c178bdec60bb050bda87f3090fe4b6 Mon Sep 17 00:00:00 2001 From: mcm-odoo Date: Thu, 8 Aug 2019 09:09:48 +0000 Subject: [PATCH] [IMP] website_slides: add button to install Surveys application in Slide Upload modal PURPOSE Ease discovering of eLearning features by allowing to install surveys directly from frontend in order to allow certification. SPECIFICATIONS Add a button in Upload a document to install Surveys. This button only appears if surveys is not installed. When button is clicked, ask for confirmation before installing survey. LImitate this feature to group system: system people should see the button and use standard ACLS about module installation. LINK Task ID 2026846 --- addons/website_slides/controllers/main.py | 13 ++++ .../static/src/js/slides_upload.js | 67 ++++++++++++++++++- .../static/src/xml/website_slides_upload.xml | 20 +++++- .../views/website_slides_templates_course.xml | 4 ++ 4 files changed, 100 insertions(+), 4 deletions(-) diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py index a3cf6d99c78..592675e7729 100644 --- a/addons/website_slides/controllers/main.py +++ b/addons/website_slides/controllers/main.py @@ -418,6 +418,8 @@ class WebsiteSlides(WebsiteProfile): 'user': request.env.user, 'pager': pager, 'is_public_user': request.website.is_public_user(), + # display upload modal + 'enable_slide_upload': 'enable_slide_upload' in kw, } if not request.env.user._is_public(): last_message_values = request.env['mail.message'].search([ @@ -451,6 +453,17 @@ class WebsiteSlides(WebsiteProfile): offset=pager['offset']) values['channel_progress'] = self._get_channel_progress(channel, include_quiz=True) + # for sys admins: prepare data to install directly modules from eLearning when + # uploading slides. Currently supporting only survey, because why not. + if request.env.user.has_group('base.group_system'): + module = request.env.ref('base.module_survey') + if module.state != 'installed': + values['modules_to_install'] = [{ + 'id': module.id, + 'name': module.shortdesc, + 'motivational': _('Evaluate and certificate your students.'), + }] + values = self._prepare_additional_channel_values(values, **kw) return request.render('website_slides.course_main', values) diff --git a/addons/website_slides/static/src/js/slides_upload.js b/addons/website_slides/static/src/js/slides_upload.js index ec3958e8d0e..0377abedeb1 100644 --- a/addons/website_slides/static/src/js/slides_upload.js +++ b/addons/website_slides/static/src/js/slides_upload.js @@ -12,6 +12,7 @@ var _t = core._t; var SlideUploadDialog = Dialog.extend({ template: 'website.slide.upload.modal', events: _.extend({}, Dialog.prototype.events, { + 'click .o_wslides_js_upload_install_button': '_onClickInstallModule', 'click .o_wslides_select_type': '_onClickSlideTypeIcon', 'change input#upload': '_onChangeSlideUpload', 'change input#url': '_onChangeSlideUrl', @@ -21,6 +22,8 @@ var SlideUploadDialog = Dialog.extend({ * @override * @param {Object} parent * @param {Object} options holding channelId and optionally upload and publish control parameters + * @param {Object} options.modulesToInstall: list of additional modules to + * install {id: module ID, name: module short description} */ init: function (parent, options) { options = _.defaults(options || {}, { @@ -34,6 +37,8 @@ var SlideUploadDialog = Dialog.extend({ this.defaultCategoryID = parseInt(options.categoryId,10); this.canUpload = options.canUpload === 'True'; this.canPublish = options.canPublish === 'True'; + this.modulesToInstall = options.modulesToInstall ? JSON.parse(options.modulesToInstall.replace(/'/g, '"')) : null; + this.modulesToInstallStatus = null; this.set('state', '_select'); this.on('change:state', this, this._onChangeType); @@ -179,6 +184,11 @@ var SlideUploadDialog = Dialog.extend({ var state = this.get('state'); if (state === '_select') { btnList.push({text: _t("Cancel"), classes: 'o_w_slide_cancel', close: true}); + } else if (state === '_import') { + if (! this.modulesToInstallStatus.installing) { + btnList.push({text: this.modulesToInstallStatus.failed ? _t("Retry") : _t("Install"), classes: 'btn-primary', click: this._onClickInstallModuleConfirm.bind(this)}); + } + btnList.push({text: _t("Go Back"), classes: 'o_w_slide_go_back', click: this._onClickGoBack.bind(this)}); } else if (state !== '_upload') { // no button when uploading if (this.canUpload) { if (this.canPublish) { @@ -364,6 +374,8 @@ var SlideUploadDialog = Dialog.extend({ tmpl = 'website.slide.upload.modal.select'; } else if (currentType === '_upload') { tmpl = 'website.slide.upload.modal.uploading'; + } else if (currentType === '_import') { + tmpl = 'website.slide.upload.modal.import'; } else { tmpl = this.slide_type_data[currentType]['template']; } @@ -371,6 +383,12 @@ var SlideUploadDialog = Dialog.extend({ this.$('.o_w_slide_upload_modal_container').append(QWeb.render(tmpl, {widget: this})); this._resetModalButton(); + + if (currentType === '_import') { + this.set_title(_t("New Certification")); + } else { + this.set_title(_t("Upload a document")); + } }, _onChangeCanSubmitForm: function (ev) { if (this.get('can_submit_form')) { @@ -495,9 +513,53 @@ var SlideUploadDialog = Dialog.extend({ } }); }, - _onClickGoBack: function (ev) { + + _onClickInstallModule: function (ev) { + var $btn = $(ev.currentTarget); + var moduleId = $btn.data('moduleId'); + if (this.modulesToInstallStatus) { + this.set('state', '_import'); + if (this.modulesToInstallStatus.installing) { + this.$('#o_wslides_install_module_text') + .text(_.str.sprintf(_t('Already installing "%s".'), this.modulesToInstallStatus.name)); + } else if (this.modulesToInstallStatus.failed) { + this.$('#o_wslides_install_module_text') + .text(_.str.sprintf(_t('Failed to install "%s".'), this.modulesToInstallStatus.name)); + } + } else { + this.modulesToInstallStatus = _.extend({}, _.find(this.modulesToInstall, function (item) { return item.id == moduleId; })); + this.set('state', '_import'); + this.$('#o_wslides_install_module_text') + .text(_.str.sprintf(_t('Do you want to install the "%s" app?'), this.modulesToInstallStatus.name)); + } + }, + + _onClickInstallModuleConfirm: function () { + var self = this; + var $el = this.$('#o_wslides_install_module_text'); + $el.text(_.str.sprintf(_t('Installing "%s".'), this.modulesToInstallStatus.name)); + this.modulesToInstallStatus.installing = true; + this._resetModalButton(); + this._rpc({ + model: 'ir.module.module', + method: 'button_immediate_install', + args: [[this.modulesToInstallStatus.id]], + }).then(function () { + window.location.href = window.location.origin + window.location.pathname + '?enable_slide_upload'; + }, function () { + $el.text(_.str.sprintf(_t('Failed to install "%s".'), self.modulesToInstallStatus.name)); + self.modulesToInstallStatus.installing = false; + self.modulesToInstallStatus.failed = true; + self._resetModalButton(); + }); + }, + + _onClickGoBack: function () { this.set('state', '_select'); this.isValidUrl = true; + if (this.modulesToInstallStatus && !this.modulesToInstallStatus.installing) { + this.modulesToInstallStatus = null; + } }, _onClickFormSubmit: function (ev) { var self = this; @@ -540,7 +602,8 @@ publicWidget.registry.websiteSlidesUpload = publicWidget.Widget.extend({ */ start: function () { // Automatically open the upload dialog if requested from query string - if ($.deparam.querystring().enable_slide_upload !== undefined) { + if (this.$el.attr('data-open-modal')) { + this.$el.removeAttr('data-open-modal'); this._openDialog(this.$el); } return this._super.apply(this, arguments); diff --git a/addons/website_slides/static/src/xml/website_slides_upload.xml b/addons/website_slides/static/src/xml/website_slides_upload.xml index 877e8b9d967..d790242a96f 100644 --- a/addons/website_slides/static/src/xml/website_slides_upload.xml +++ b/addons/website_slides/static/src/xml/website_slides_upload.xml @@ -24,13 +24,22 @@ + + + + + + + -