[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
This commit is contained in:
mcm-odoo
2019-08-12 15:40:36 +00:00
committed by Thibault Delavallée
parent 9554e9d3f8
commit 2ab0bd3236
4 changed files with 100 additions and 4 deletions
+13
View File
@@ -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)
@@ -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);
@@ -24,13 +24,22 @@
</a>
</div>
</div>
<t t-if="widget.modulesToInstall">
<t t-foreach="widget.modulesToInstall" t-as="module_info">
<a class="o_wslides_js_upload_install_button w-100 text-center mb-4 btn rounded border text-600 p-3"
href="#" t-att-title="module_info['name']"
t-att-data-module-id="module_info['id']">
<i class="fa fa-trophy"></i> <t t-esc="module_info['motivational']"/>
</a>
</t>
</t>
</t>
<!--
Uploading template
-->
<t t-name="website.slide.upload.modal.uploading">
<div class="oe_slides_upload_loading text-center" aria-hidden="true" role="status">
<div class="text-center" aria-hidden="true" role="status">
<div class="fa-3x">
<i class="fas fa-spinner fa-pulse"></i>
</div>
@@ -38,6 +47,13 @@
</div>
</t>
<!--
Import module template
-->
<t t-name="website.slide.upload.modal.import">
<p id="o_wslides_install_module_text"/>
</t>
<!--
Slide Type common form part template
-->
@@ -172,7 +188,7 @@
<h3 class="modal-title">Upload Image</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
</header>
<div class="oe_slides_upload_loading text-center" style="display:none" aria-hidden="true" role="status">
<div class="text-center" style="display:none" aria-hidden="true" role="status">
<h4><i class='fa fa-spinner fa-spin'></i> Uploading Image... </h4>
</div>
<main class="modal-body">
@@ -329,6 +329,7 @@
<div t-if="channel.can_upload" class="justify-content-center mt-1">
<a role="button" class="btn btn-link btn-block o_wslides_js_slide_upload" title="Upload Presentation"
aria-label="Upload Presentation" href="#"
t-att-data-modules-to-install="modules_to_install"
t-att-data-channel-id="channel.id"
t-att-data-can-upload="channel.can_upload"
t-att-data-can-publish="channel.can_publish">
@@ -363,6 +364,7 @@
role="button"
aria-label="Upload Presentation"
href="#"
t-att-data-modules-to-install="modules_to_install"
t-att-data-channel-id="channel.id"
t-att-data-category-id="category_id"
t-att-data-can-upload="channel.can_upload"
@@ -388,6 +390,8 @@
role="button"
aria-label="Upload Presentation"
href="#"
t-att-data-open-modal="enable_slide_upload"
t-att-data-modules-to-install="modules_to_install"
t-att-data-channel-id="channel.id"
t-att-data-can-upload="channel.can_upload"
t-att-data-can-publish="channel.can_publish"><i class="fa fa-plus mr-1 align-middle"/><span>Add Content</span></a>