diff --git a/addons/website_slides/static/src/js/slides.js b/addons/website_slides/static/src/js/slides.js
index 0377394c452..bea4146bfe6 100644
--- a/addons/website_slides/static/src/js/slides.js
+++ b/addons/website_slides/static/src/js/slides.js
@@ -2,34 +2,56 @@
odoo.define('website_slides.slides', function (require) {
"use strict";
- var time = require('web.time');
- require('root.widget');
+var time = require('web.time');
+require('root.widget');
+var sAnimations = require('website.content.snippets.animation');
- (function () {
- $("timeago.timeago").each(function (index, el) {
- var datetime = $(el).attr('datetime'),
- datetime_obj = time.str_to_datetime(datetime),
- // if presentation 7 days, 24 hours, 60 min, 60 second, 1000 millis old(one week)
- // then return fix formate string else timeago
- display_str = "";
- if (datetime_obj && new Date().getTime() - datetime_obj.getTime() > 7 * 24 * 60 * 60 * 1000) {
- display_str = moment(datetime_obj).format('ll');
- } else {
- display_str = moment(datetime_obj).fromNow();
- }
- $(el).text(display_str);
- });
+var page_widgets = {};
- // To prevent showing channel settings alert box once user closed it.
- $('.o_slides_hide_channel_settings').on('click', function(ev) {
- var channel_id = $(this).data("channelId");
- ev.preventDefault();
- document.cookie = "slides_channel_" + channel_id + " = closed";
- return true;
- });
- })();
+sAnimations.registry.websiteSlides = sAnimations.Class.extend({
+ selector: 'main',
+ read_events: {
+ 'each timeago.timeago': '_onTimeAgo',
+ 'click .o_slides_hide_channel_settings': '_onHideChannelSettings',
+ },
- return {
- page_widgets: {},
- }
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ * @param {Object} index
+ * @param {Object} el
+ */
+ _onTimeAgo: function (index, el) {
+ var datetime = $(el).attr('datetime'),
+ datetime_obj = time.str_to_datetime(datetime),
+ // if presentation 7 days, 24 hours, 60 min, 60 second, 1000 millis old(one week)
+ // then return fix formate string else timeago
+ display_str = "";
+ if (datetime_obj && new Date().getTime() - datetime_obj.getTime() > 7 * 24 * 60 * 60 * 1000) {
+ display_str = moment(datetime_obj).format('ll');
+ } else {
+ display_str = moment(datetime_obj).fromNow();
+ }
+ $(el).text(display_str);
+ },
+ /**
+ * To prevent showing channel settings alert box once user closed it.
+ *
+ * @override
+ * @param {Object} ev
+ */
+ _onHideChannelSettings: function (ev) {
+ var channel_id = $(this).data("channelId");
+ ev.preventDefault();
+ document.cookie = "slides_channel_" + channel_id + " = closed";
+ return true;
+ },
+});
+
+return {
+ page_widgets: page_widgets,
+};
});
diff --git a/addons/website_slides/static/src/js/slides_embed.js b/addons/website_slides/static/src/js/slides_embed.js
index 2ba46a1990d..dcb72d7765c 100644
--- a/addons/website_slides/static/src/js/slides_embed.js
+++ b/addons/website_slides/static/src/js/slides_embed.js
@@ -1,50 +1,77 @@
/*global $, _, PDFSlidesViewer*/
odoo.define('website_slides.slides_embed', function (require) {
- "use strict";
-
- var time = require('web.time');
- var Widget = require('web.Widget');
- require('website_slides.slides');
-
- (function () {
- /*
- * Embedded Code Widget
- */
- var SlideSocialEmbed = Widget.extend({
- events: {
- 'change input' : 'change_page',
- },
- init: function(parent, max_page){
- this._super(parent);
- this.max_page = max_page || false;
- },
- change_page: function(ev){
- ev.preventDefault();
- var input = this.$('input');
- var page = parseInt(input.val());
- if (this.max_page && !(page > 0 && page <= this.max_page)) {
- page = 1;
- }
- this.update_embedded_code(page);
- },
- update_embedded_code: function(page){
- var embed_input = this.$('.slide_embed_code');
- var new_code = embed_input.val().replace(/(page=).*?([^\d]+)/, '$1' + page + '$2');
- embed_input.val(new_code);
- },
- });
+"use strict";
- $('iframe.o_wslides_iframe_viewer').ready(function() {
- // TODO : make it work. For now, once the iframe is loaded, the value of #page_count is
- // still now set (the pdf is still loading)
- var $iframe = $(this);
- var max_page = $iframe.contents().find('#page_count').val();
- slides.page_widgets['social_embed'] = new SlideSocialEmbed($iframe, max_page).setElement($('.oe_slide_js_embed_code_widget'));
- });
-
- })();
-
+var Widget = require('web.Widget');
+require('website_slides.slides');
+var sAnimations = require('website.content.snippets.animation');
+
+// Embedded Code Widget
+var SlideSocialEmbed = Widget.extend({
+ events: {
+ 'change input' : '_changePage',
+ },
+ /**
+ * @override
+ * @param {Object} parent
+ * @param {Number} max_page
+ */
+ init: function (parent, max_page){
+ this._super(parent);
+ this.max_page = max_page || false;
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * @param {Object} ev
+ */
+ _changePage: function (ev){
+ ev.preventDefault();
+ var input = this.$('input');
+ var page = parseInt(input.val());
+ if (this.max_page && !(page > 0 && page <= this.max_page)) {
+ page = 1;
+ }
+ this._updateEmbeddedCode(page);
+ },
+ /**
+ * @private
+ * @param {Number} page
+ */
+ _updateEmbeddedCode: function (page){
+ var embed_input = this.$('.slide_embed_code');
+ var new_code = embed_input.val().replace(/(page=).*?([^\d]+)/, '$1' + page + '$2');
+ embed_input.val(new_code);
+ },
});
+
+sAnimations.registry.websiteSlidesEmbed = sAnimations.Class.extend({
+ selector: 'main',
+ read_events: {
+ 'ready iframe.o_wslides_iframe_viewer': '_onIframeViewer',
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ _onIframeViewer: function () {
+ // TODO : make it work. For now, once the iframe is loaded, the value of #page_count is
+ // still now set (the pdf is still loading)
+ var $iframe = $(this);
+ var max_page = $iframe.contents().find('#page_count').val();
+ new SlideSocialEmbed($iframe, max_page).setElement($('.oe_slide_js_embed_code_widget'));
+ },
+});
+});
+
/**
This file is a minimal version of the PDFViewer widget.
It is NOT use in the website_slides module, but it is
@@ -250,5 +277,3 @@ $(document).ready(function () {
});
}
});
-
-
diff --git a/addons/website_slides/static/src/js/slides_like.js b/addons/website_slides/static/src/js/slides_like.js
index d9c0da2afa2..3f3033c6098 100644
--- a/addons/website_slides/static/src/js/slides_like.js
+++ b/addons/website_slides/static/src/js/slides_like.js
@@ -1,63 +1,85 @@
/*global $, _, PDFJS */
odoo.define('website_slides.slides_like', function (require) {
- "use strict";
-
- var ajax = require('web.ajax');
- var core = require('web.core');
- var Widget = require('web.Widget');
- var local_storage = require('web.local_storage');
- var slides = require('website_slides.slides');
-
- var _t = core._t;
-
- (function () {
+"use strict";
+
+var ajax = require('web.ajax');
+var core = require('web.core');
+var Widget = require('web.Widget');
+var local_storage = require('web.local_storage');
+var sAnimations = require('website.content.snippets.animation');
+var slides = require('website_slides.slides');
+
+var _t = core._t;
+
+// Like/Dislike Buttons Widget
+var LikeButton = Widget.extend({
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * @param {Object} $el
+ */
+ setElement: function ($el){
+ this._super.apply(this, arguments);
+ this.$el.on('click', this, _.bind(this._applyAction, this));
+ },
+ /**
+ * @private
+ * @param {Object} ev
+ */
+ _applyAction: function (ev){
+ var button = $(ev.currentTarget);
+ var slide_id = button.data('slide-id');
+ var user_id = button.data('user-id');
+ var is_public = button.data('public-user');
+ var href = button.data('href');
+ if (is_public){
+ this._popoverAlert(button, _.str.sprintf(_t('Please login to vote this slide'), (document.URL)));
+ } else {
+ var target = button.find('.fa');
+ if (local_storage.getItem('slide_vote_' + slide_id) !== user_id.toString()) {
+ ajax.jsonRpc(href, 'call', {slide_id: slide_id}).then(function (data) {
+ target.text(data);
+ local_storage.setItem('slide_vote_' + slide_id, user_id);
+ });
+ } else {
+ this._popoverAlert(button, _t('You have already voted for this slide'));
+ }
+ }
+ },
+ /**
+ * @private
+ * @param {Object} $el
+ * @param {String} message
+ */
+ _popoverAlert: function ($el, message){
+ $el.popover({
+ trigger: 'focus',
+ placement: 'bottom',
+ container: 'body',
+ html: true,
+ content: function () {
+ return message;
+ }
+ }).popover('show');
+ },
+});
+
+sAnimations.registry.websiteSlidesLike = sAnimations.Class.extend({
+ selector: 'main',
+
+ /**
+ * @override
+ * @param {Object} parent
+ */
+ start: function (parent) {
var widget_parent = $('body');
-
- /*
- * Like/Dislike Buttons Widget
- */
- var LikeButton = Widget.extend({
- setElement: function($el){
- this._super.apply(this, arguments);
- this.$el.on('click', this, _.bind(this.apply_action, this));
- },
- apply_action: function(ev){
- var button = $(ev.currentTarget);
- var slide_id = button.data('slide-id');
- var user_id = button.data('user-id');
- var is_public = button.data('public-user');
- var href = button.data('href');
- if(is_public){
- this.popover_alert(button, _.str.sprintf(_t('Please login to vote this slide'), (document.URL)));
- }else{
- var target = button.find('.fa');
- if (local_storage.getItem('slide_vote_' + slide_id) !== user_id.toString()) {
- ajax.jsonRpc(href, 'call', {slide_id: slide_id}).then(function (data) {
- target.text(data);
- local_storage.setItem('slide_vote_' + slide_id, user_id);
- });
- } else {
- this.popover_alert(button, _t('You have already voted for this slide'));
- }
- }
- },
- popover_alert: function($el, message){
- $el.popover({
- trigger: 'focus',
- placement: 'bottom',
- container: 'body',
- html: true,
- content: function(){
- return message;
- }
- }).popover('show');
- },
- });
-
slides.page_widgets['likeButton'] = new LikeButton(widget_parent).setElement($('.oe_slide_js_like'));
slides.page_widgets['dislikeButton'] = new LikeButton(widget_parent).setElement($('.oe_slide_js_unlike'));
-
- })();
-
+ return this._super.apply(this, arguments);
+ },
+});
});
-
\ No newline at end of file
diff --git a/addons/website_slides/static/src/js/slides_share.js b/addons/website_slides/static/src/js/slides_share.js
index 72e810f16f6..e1ef6118cfe 100644
--- a/addons/website_slides/static/src/js/slides_share.js
+++ b/addons/website_slides/static/src/js/slides_share.js
@@ -1,43 +1,56 @@
odoo.define('website_slides.slides_share', function (require) {
- "use strict";
- var ajax = require('web.ajax');
- var Widget = require('web.Widget');
- var slides = require('website_slides.slides');
+"use strict";
+var ajax = require('web.ajax');
+var Widget = require('web.Widget');
+var sAnimations = require('website.content.snippets.animation');
+var slides = require('website_slides.slides');
- (function () {
+// Send by email Widget
+var ShareMail = Widget.extend({
+ events: {
+ 'click button': '_sendMail',
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ _sendMail: function () {
+ var self = this;
+ var input = this.$('input');
+ var slide_id = this.$('button').data('slide-id');
+ if (input.val() && input[0].checkValidity()){
+ this.$el.removeClass('o_has_error').find('.form-control, .custom-select').removeClass('is-invalid');
+ ajax.jsonRpc('/slides/slide/send_share_email', 'call', {
+ slide_id: slide_id,
+ email: input.val(),
+ }).then(function () {
+ self.$el.html($('
Thank you! Mail has been sent.
'));
+ });
+ } else {
+ this.$el.addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid');
+ input.focus();
+ }
+ },
+});
+
+sAnimations.registry.websiteSlidesShare = sAnimations.Class.extend({
+ selector: 'main',
+ read_events: {
+ 'click a.o_slides_social_share': '_onSlidesSocialShare'
+ },
+
+ /**
+ * @override
+ * @param {Object} parent
+ */
+ start: function (parent) {
var widget_parent = $('body');
-
- /*
- * Send by email Widget
- */
- var ShareMail = Widget.extend({
- events: {
- 'click button' : 'send_mail',
- },
- send_mail: function(){
- var self = this;
- var input = this.$('input');
- var slide_id = this.$('button').data('slide-id');
- if(input.val() && input[0].checkValidity()){
- this.$el.removeClass('o_has_error').find('.form-control, .custom-select').removeClass('is-invalid');
- ajax.jsonRpc('/slides/slide/send_share_email', 'call', {
- slide_id: slide_id,
- email: input.val(),
- }).then(function () {
- self.$el.html($('Thank you! Mail has been sent.
'));
- });
- }else{
- this.$el.addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid');
- input.focus();
- }
- },
- });
-
slides.page_widgets['share_mail'] = new ShareMail(widget_parent).setElement($('.oe_slide_js_share_email'));
- /*
- * Social Sharing Statistics Widget
- */
if ($('div#statistic').length) {
var slide_url = $("div#statistic").attr('slide-url');
var social_urls = {
@@ -45,66 +58,84 @@ odoo.define('website_slides.slides_share', function (require) {
'twitter': 'https://cdn.api.twitter.com/1/urls/count.json?url=',
'facebook': 'https://graph.facebook.com/?id=',
'gplus': 'https://clients6.google.com/rpc'
- }
-
- var update_statistics = function(social_site, slide_url) {
- if (social_site == 'gplus') {
- $.ajax({
- url: social_urls['gplus'],
- type: "POST",
- dataType: 'json',
- contentType: 'application/json',
- data: JSON.stringify([{
- "method": "pos.plusones.get",
- "id": "p",
- "params": {
- "nolog": true,
- "id": slide_url,
- "source": "widget",
- "userId": "@viewer",
- "groupId": "@self"
- },
- // TDE NOTE: should there be a key here ?
- "jsonrpc": "2.0",
- "apiVersion": "v1"
- }]),
- success: function(data) {
- $('#google-badge').text(data[0].result.metadata.globalCounts.count || 0);
- $('#total-share').text(parseInt($('#total-share').text()) + parseInt($('#google-badge').text()));
- },
- });
- } else {
- $.ajax({
- url: social_urls[social_site] + slide_url,
- dataType: 'jsonp',
- success: function(data) {
- var shareCount = (social_site === 'facebook' ? data.shares : data.count) || 0;
- $('#' + social_site + '-badge').text(shareCount);
- $('#total-share').text(parseInt($('#total-share').text()) + parseInt($('#' + social_site+ '-badge').text()));
- },
- });
- }
};
+ }
- $.each(social_urls, function(key, value) {
- update_statistics(key, slide_url);
+ $.each(social_urls, function (key, value) {
+ this._updateStatistics(key, slide_url);
+ });
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * @param {string} social_site
+ * @param {string} slide_url
+ */
+ _updateStatistics: function (social_site, slide_url) {
+ if (social_site === 'gplus') {
+ $.ajax({
+ url: this.social_urls['gplus'],
+ type: "POST",
+ dataType: 'json',
+ contentType: 'application/json',
+ data: JSON.stringify([{
+ "method": "pos.plusones.get",
+ "id": "p",
+ "params": {
+ "nolog": true,
+ "id": slide_url,
+ "source": "widget",
+ "userId": "@viewer",
+ "groupId": "@self"
+ },
+ // TDE NOTE: should there be a key here ?
+ "jsonrpc": "2.0",
+ "apiVersion": "v1"
+ }]),
+ success: function (data) {
+ $('#google-badge').text(data[0].result.metadata.globalCounts.count || 0);
+ $('#total-share').text(parseInt($('#total-share').text()) + parseInt($('#google-badge').text()));
+ },
});
-
- $("a.o_slides_social_share").on('click', function(ev) {
- ev.preventDefault();
- var key = $(ev.currentTarget).attr('social-key');
- var popUpURL = $(ev.currentTarget).attr('href');
- var popUp = window.open(
- popUpURL,
- 'Share Dialog',
- 'width=626,height=436');
- $(window).on('focus', function() {
- if (popUp.closed) {
- update_statistics(key, slide_url);
- $(window).off('focus');
- }
- });
+ } else {
+ $.ajax({
+ url: this.social_urls[social_site] + slide_url,
+ dataType: 'jsonp',
+ success: function (data) {
+ var shareCount = (social_site === 'facebook' ? data.shares : data.count) || 0;
+ $('#' + social_site + '-badge').text(shareCount);
+ $('#total-share').text(parseInt($('#total-share').text()) + parseInt($('#' + social_site+ '-badge').text()));
+ },
});
}
- })();
-})
\ No newline at end of file
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ * @param {Object} ev
+ */
+ _onSlidesSocialShare: function (ev) {
+ ev.preventDefault();
+ var key = $(ev.currentTarget).attr('social-key');
+ var popUpURL = $(ev.currentTarget).attr('href');
+ var popUp = window.open(
+ popUpURL,
+ 'Share Dialog',
+ 'width=626,height=436');
+ $(window).on('focus', function () {
+ if (popUp.closed) {
+ this._updateStatistics(key, this.slide_url);
+ $(window).off('focus');
+ }
+ });
+ },
+});
+});
diff --git a/addons/website_slides/static/src/js/slides_upload.js b/addons/website_slides/static/src/js/slides_upload.js
index aa638882930..382caf451e2 100644
--- a/addons/website_slides/static/src/js/slides_upload.js
+++ b/addons/website_slides/static/src/js/slides_upload.js
@@ -1,81 +1,311 @@
odoo.define('website_slides.upload', function (require) {
"use strict";
+var sAnimations = require('website.content.snippets.animation');
var ajax = require('web.ajax');
var core = require('web.core');
var Widget = require('web.Widget');
-require('web.dom_ready');
-var weContext = require("web_editor.context");
var slides = require('website_slides.slides');
-var qweb = core.qweb;
var _t = core._t;
-if (!$('.oe_slide_js_upload').length) {
- return $.Deferred().reject("DOM doesn't contain '.oe_slide_js_upload'");
-}
-
-ajax.loadXML('/website_slides/static/src/xml/website_slides.xml', qweb);
-
var SlideDialog = Widget.extend({
template: 'website.slide.upload',
events: {
'hidden.bs.modal': 'destroy',
- 'click button.save': 'save',
- 'click button[data-dismiss="modal"]': 'cancel',
- 'change input#upload': 'slide_upload',
- 'change input#url': 'slide_url',
+ 'click button.save': '_save',
+ 'click button[data-dismiss="modal"]': '_cancel',
+ 'change input#upload': '_slideUpload',
+ 'change input#url': '_slideUrl',
'click .list-group-item': function (ev) {
this.$('.list-group-item').removeClass('active');
$(ev.target).closest('li').addClass('active');
}
},
+
+ /**
+ * @override
+ * @param {Object} el
+ * @param {number} channel_id
+ */
init: function (el, channel_id) {
this._super(el, channel_id);
this.channel_id = parseInt(channel_id, 10);
this.file = {};
this.index_content = "";
},
- start: function () {
+ /**
+ * @override
+ * @param {Object} parent
+ */
+ start: function (parent) {
this.$el.modal({
backdrop: 'static'
});
- this.set_category_id();
- this.set_tag_ids();
+ this._setCategoryId();
+ this._setTagIds();
},
- slide_url: function (ev) {
- var self = this,
- value = {
- 'url': $(ev.target).val(),
- 'channel_id': self.channel_id
- };
- this.$('.alert-warning').remove();
- this.is_valid_url = false;
- this.$('.save').button('loading');
- ajax.jsonRpc('/slides/dialog_preview/', 'call', value).then(function (data) {
- self.$('.save').button('reset');
- if (data.error) {
- self.display_alert(data.error);
- } else {
- self.$("#slide-image").attr("src", data.url_src);
- self.$('#name').val(data.title);
- self.$('#description').val(data.description);
- self.is_valid_url = true;
- }
- });
- },
- check_unique_slide: function (file_name) {
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * @param {string} file_name
+ */
+ _checkUniqueSlide: function (file_name) {
var self = this;
- return ajax.jsonRpc('/web/dataset/call_kw', 'call', {
+ return this._rpc({
model: 'slide.slide',
method: 'search_count',
args: [[['channel_id', '=', self.channel_id], ['name', '=', file_name]]],
- kwargs: {
- context: weContext.get(), // TODO use this._rpc
- }
});
},
- slide_upload: function (ev) {
+ /**
+ * @private
+ */
+ _resetFile: function () {
+ var control = this.$('#upload');
+ control.replaceWith(control = control.clone(true));
+ this.file.name = false;
+ },
+ /**
+ * @private
+ * @param {string} message
+ */
+ _displayAlert: function (message) {
+ this.$('.alert-warning').remove();
+ $('' + message + '
').insertBefore(this.$('form'));
+ },
+
+ /**
+ * Wrapper for select2 load data from server at once and store it.
+ *
+ * @private
+ * @param {String} Placeholder for element.
+ * @param {bool} true for multiple selection box, false for single selection
+ * @param {Function} Function to fetch data from remote location should return $.deferred object
+ * resolved data should be array of object with id and name. eg. [{'id': id, 'name': 'text'}, ...]
+ * @returns {Object} select2 wrapper object
+ */
+ _select2Wrapper: function (tag, multi, fetch_fnc) {
+ return {
+ width: '100%',
+ placeholder: tag,
+ allowClear: true,
+ formatNoMatches: false,
+ multiple: multi,
+ selection_data: false,
+ fetch_rpc_fnc : fetch_fnc,
+ formatSelection: function (data) {
+ if (data.tag) {
+ data.text = data.tag;
+ }
+ return data.text;
+ },
+ createSearchChoice: function (term, data) {
+ var added_tags = $(this.opts.element).select2('data');
+ if (_.filter(_.union(added_tags, data), function (tag) {
+ return tag.text.toLowerCase().localeCompare(term.toLowerCase()) === 0;
+ }).length === 0) {
+ return {
+ id: _.uniqueId('tag_'),
+ create: true,
+ tag: term,
+ text: _.str.sprintf(_t("Create new tag '%s'"), term),
+ };
+ }
+ },
+ fill_data: function (query, data) {
+ var that = this,
+ tags = {results: []};
+ _.each(data, function (obj) {
+ if (that.matcher(query.term, obj.name)) {
+ tags.results.push({id: obj.id, text: obj.name });
+ }
+ });
+ query.callback(tags);
+ },
+ query: function (query) {
+ var that = this;
+ // fetch data only once and store it
+ if (!this.selection_data) {
+ this.fetch_rpc_fnc().then(function (data) {
+ that.fill_data(query, data);
+ that.selection_data = data;
+ });
+ } else {
+ this.fill_data(query, this.selection_data);
+ }
+ }
+ };
+ },
+ /**
+ * Category management from select2
+ *
+ * @private
+ */
+ _setCategoryId: function () {
+ var self = this;
+ $('#category_id').select2(this._select2Wrapper(_t('Category'), false,
+ function () {
+ return this._rpc({
+ model: 'slide.category',
+ method: 'search_read',
+ args: [],
+ kwargs: {
+ fields: ['name'],
+ domain: [['channel_id', '=', self.channel_id]],
+ }
+ });
+ }));
+ },
+ /**
+ * @private
+ */
+ _getCategoryId: function () {
+ var value = $('#category_id').select2('data');
+ if (value && value.create) {
+ return [0, {'name': value.text}];
+ }
+ return [value ? value.id : null];
+ },
+ /**
+ * Tags management from select2
+ *
+ * @private
+ */
+ _setTagIds: function () {
+ $('#tag_ids').select2(this._select2Wrapper(_t('Tags'), true, function () {
+ return this._rpc({
+ model: 'slide.tag',
+ method: 'search_read',
+ args: [],
+ kwargs: {
+ fields: ['name'],
+ }
+ });
+ }));
+ },
+ /**
+ * @private
+ */
+ _getTagIds: function () {
+ var res = [];
+ _.each($('#tag_ids').select2('data'),
+ function (val) {
+ if (val.create) {
+ res.push([0, 0, {'name': val.text}]);
+ } else {
+ res.push([4, val.id]);
+ }
+ });
+ return res;
+ },
+ /**
+ * @private
+ */
+ // TODO: Remove this part, as now SVG support in image resize tools is included
+ //Python PIL does not support SVG, so converting SVG to PNG
+ _svgToPng: function () {
+ var img = this.$el.find("img#slide-image")[0];
+ var canvas = document.createElement("canvas");
+ canvas.width = img.width;
+ canvas.height = img.height;
+ canvas.getContext("2d").drawImage(img, 0, 0);
+ return canvas.toDataURL("image/png").split(',')[1];
+ },
+ /**
+ * Values and save
+ *
+ * @private
+ */
+ _getValue: function () {
+ var canvas = this.$('#data_canvas')[0],
+ values = {
+ 'channel_id': this.channel_id || '',
+ 'name': this.$('#name').val(),
+ 'url': this.$('#url').val(),
+ 'description': this.$('#description').val(),
+ 'tag_ids': this._getTagIds(),
+ 'category_id': this._getCategoryId()
+ };
+ if (this.file.type === 'application/pdf') {
+ _.extend(values, {
+ 'image': canvas.toDataURL().split(',')[1],
+ 'index_content': this.index_content,
+ 'slide_type': canvas.height > canvas.width ? 'document' : 'presentation',
+ 'mime_type': this.file.type,
+ 'datas': this.file.data
+ });
+ }
+ if (/^image\/.*/.test(this.file.type)) {
+ _.extend(values, {
+ 'slide_type': 'infographic',
+ 'mime_type': this.file.type === 'image/svg+xml' ? 'image/png' : this.file.type,
+ 'datas': this.file.type === 'image/svg+xml' ? this._svgToPng() : this.file.data
+ });
+ }
+ return values;
+ },
+ /**
+ * @private
+ */
+ _validate: function () {
+ this.$('.form-group').removeClass('o_has_error').find('.form-control, .custom-select').removeClass('is-invalid');
+ if (!this.$('#name').val()) {
+ this.$('#name').closest('.form-group').addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid');
+ return false;
+ }
+ var url = this.$('#url').val() ? this.is_valid_url : false;
+ if (!(this.file.name || url)) {
+ this.$('#url').closest('.form-group').addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid');
+ return false;
+ }
+ return true;
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ * @param {Object} ev
+ */
+ _save: function (ev) {
+ var self = this;
+ if (this._validate()) {
+ var values = this._getValue();
+ if ($(ev.target).data('published')) {
+ values.website_published = true;
+ }
+ this.$('.oe_slides_upload_loading').show();
+ this.$('.modal-footer, .modal-body').hide();
+ ajax.jsonRpc("/slides/add_slide", 'call', values).then(function (data) {
+ if (data.error) {
+ self._displayAlert(data.error);
+ self.$('.oe_slides_upload_loading').hide();
+ self.$('.modal-footer, .modal-body').show();
+
+ } else {
+ window.location = data.url;
+ }
+ });
+ }
+ },
+ /**
+ * @override
+ */
+ _cancel: function () {
+ this.trigger("cancel");
+ },
+ /**
+ * @override
+ * @param {Object} ev
+ */
+ _slideUpload: function (ev) {
var self = this,
file = ev.target.files[0],
is_image = /^image\/.*/.test(file.type),
@@ -83,13 +313,13 @@ var SlideDialog = Widget.extend({
this.file.name = file.name;
this.file.type = file.type;
if (!(is_image || this.file.type === 'application/pdf')) {
- this.display_alert(_t("Invalid file type. Please select pdf or image file"));
- this.reset_file();
+ this._displayAlert(_t("Invalid file type. Please select pdf or image file"));
+ this._resetFile();
return;
}
if (file.size / 1024 / 1024 > 25) {
- this.display_alert(_t("File is too big. File size cannot exceed 25MB"));
- this.reset_file();
+ this._displayAlert(_t("File is too big. File size cannot exceed 25MB"));
+ this._resetFile();
return;
}
this.$('.alert-warning').remove();
@@ -113,8 +343,8 @@ var SlideDialog = Widget.extend({
ArrayReader.onload = function (evt) {
var buffer = evt.target.result;
var passwordNeeded = function () {
- self.display_alert(_t("You can not upload password protected file."));
- self.reset_file();
+ self._displayAlert(_t("You can not upload password protected file."));
+ self._resetFile();
self.$('.save').button('reset');
};
PDFJS.getDocument(new Uint8Array(buffer), null, passwordNeeded).then(function getPdf(pdf) {
@@ -169,222 +399,72 @@ var SlideDialog = Widget.extend({
var input = file.name;
var input_val = input.substr(0, input.lastIndexOf('.')) || input;
- this.check_unique_slide(input_val).then(function (exist) {
+ this._checkUniqueSlide(input_val).then(function (exist) {
if (exist) {
var message = _t("Channel contains the given title, please change before Save or Publish.");
- self.display_alert(message);
+ self._displayAlert(message);
}
self.$('#name').val(input_val);
});
},
- reset_file: function () {
- var control = this.$('#upload');
- control.replaceWith(control = control.clone(true));
- this.file.name = false;
- },
- display_alert: function (message) {
+ /**
+ * @override
+ * @param {Object} ev
+ */
+ _slideUrl: function (ev) {
+ var self = this,
+ value = {
+ 'url': $(ev.target).val(),
+ 'channel_id': self.channel_id
+ };
this.$('.alert-warning').remove();
- $('' + message + '
').insertBefore(this.$('form'));
+ this.is_valid_url = false;
+ this.$('.save').button('loading');
+ ajax.jsonRpc('/slides/dialog_preview/', 'call', value).then(function (data) {
+ self.$('.save').button('reset');
+ if (data.error) {
+ self._displayAlert(data.error);
+ } else {
+ self.$("#slide-image").attr("src", data.url_src);
+ self.$('#name').val(data.title);
+ self.$('#description').val(data.description);
+ self.is_valid_url = true;
+ }
+ });
+ },
+
+});
+
+sAnimations.registry.websiteSlidesUpload = sAnimations.Class.extend({
+ selector: '.oe_slide_js_upload',
+ xmlDependencies: ['/website_slides/static/src/xml/website_slides.xml'],
+ read_events: {
+ 'click .oe_slide_js_upload': '_bindEventButton',
},
/**
- Wrapper for select2 load data from server at once and store it.
+ * @override
+ * @param {Object} parent
+ */
+ start: function (parent) {
+ // Automatically open the upload dialog if requested from query string
+ if ($.deparam.querystring().enable_slide_upload !== undefined) {
+ $('.oe_slide_js_upload').click();
+ }
+ },
- @param {String} Placeholder for element.
- @param {bool} true for multiple selection box, false for single selection
- @param {Function} Function to fetch data from remote location should return $.deferred object
- resolved data should be array of object with id and name. eg. [{'id': id, 'name': 'text'}, ...]
- @returns {Object} select2 wrapper object
- */
- select2_wrapper: function (tag, multi, fetch_fnc) {
- return {
- width: '100%',
- placeholder: tag,
- allowClear: true,
- formatNoMatches: false,
- multiple: multi,
- selection_data: false,
- fetch_rpc_fnc : fetch_fnc,
- formatSelection: function (data) {
- if (data.tag) {
- data.text = data.tag;
- }
- return data.text;
- },
- createSearchChoice: function (term, data) {
- var added_tags = $(this.opts.element).select2('data');
- if (_.filter(_.union(added_tags, data), function (tag) {
- return tag.text.toLowerCase().localeCompare(term.toLowerCase()) === 0;
- }).length === 0) {
- return {
- id: _.uniqueId('tag_'),
- create: true,
- tag: term,
- text: _.str.sprintf(_t("Create new tag '%s'"), term),
- };
- }
- },
- fill_data: function (query, data) {
- var that = this,
- tags = {results: []};
- _.each(data, function (obj) {
- if (that.matcher(query.term, obj.name)) {
- tags.results.push({id: obj.id, text: obj.name });
- }
- });
- query.callback(tags);
- },
- query: function (query) {
- var that = this;
- // fetch data only once and store it
- if (!this.selection_data) {
- this.fetch_rpc_fnc().then(function (data) {
- that.fill_data(query, data);
- that.selection_data = data;
- });
- } else {
- this.fill_data(query, this.selection_data);
- }
- }
- };
- },
- // Category management from select2
- set_category_id: function () {
- var self = this;
- $('#category_id').select2(this.select2_wrapper(_t('Category'), false,
- function () {
- return ajax.jsonRpc("/web/dataset/call_kw", 'call', {
- model: 'slide.category',
- method: 'search_read',
- args: [],
- kwargs: {
- fields: ['name'],
- domain: [['channel_id', '=', self.channel_id]],
- context: weContext.get(), // TODO use this._rpc
- }
- });
- }));
- },
- get_category_id: function () {
- var value = $('#category_id').select2('data');
- if (value && value.create) {
- return [0, {'name': value.text}];
- }
- return [value ? value.id : null];
- },
- // Tags management from select2
- set_tag_ids: function () {
- $('#tag_ids').select2(this.select2_wrapper(_t('Tags'), true, function () {
- return ajax.jsonRpc("/web/dataset/call_kw", 'call', {
- model: 'slide.tag',
- method: 'search_read',
- args: [],
- kwargs: {
- fields: ['name'],
- context: weContext.get(), // TODO use this._rpc
- }
- });
- }));
- },
- get_tag_ids: function () {
- var res = [];
- _.each($('#tag_ids').select2('data'),
- function (val) {
- if (val.create) {
- res.push([0, 0, {'name': val.text}]);
- } else {
- res.push([4, val.id]);
- }
- });
- return res;
- },
- // TODO: Remove this part, as now SVG support in image resize tools is included
- //Python PIL does not support SVG, so converting SVG to PNG
- svg_to_png: function () {
- var img = this.$el.find("img#slide-image")[0];
- var canvas = document.createElement("canvas");
- canvas.width = img.width;
- canvas.height = img.height;
- canvas.getContext("2d").drawImage(img, 0, 0);
- return canvas.toDataURL("image/png").split(',')[1];
- },
- // Values and save
- get_value: function () {
- var canvas = this.$('#data_canvas')[0],
- values = {
- 'channel_id': this.channel_id || '',
- 'name': this.$('#name').val(),
- 'url': this.$('#url').val(),
- 'description': this.$('#description').val(),
- 'tag_ids': this.get_tag_ids(),
- 'category_id': this.get_category_id()
- };
- if (this.file.type === 'application/pdf') {
- _.extend(values, {
- 'image': canvas.toDataURL().split(',')[1],
- 'index_content': this.index_content,
- 'slide_type': canvas.height > canvas.width ? 'document' : 'presentation',
- 'mime_type': this.file.type,
- 'datas': this.file.data
- });
- }
- if (/^image\/.*/.test(this.file.type)) {
- _.extend(values, {
- 'slide_type': 'infographic',
- 'mime_type': this.file.type === 'image/svg+xml' ? 'image/png' : this.file.type,
- 'datas': this.file.type === 'image/svg+xml' ? this.svg_to_png() : this.file.data
- });
- }
- return values;
- },
- validate: function () {
- this.$('.form-group').removeClass('o_has_error').find('.form-control, .custom-select').removeClass('is-invalid');
- if (!this.$('#name').val()) {
- this.$('#name').closest('.form-group').addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid');
- return false;
- }
- var url = this.$('#url').val() ? this.is_valid_url : false;
- if (!(this.file.name || url)) {
- this.$('#url').closest('.form-group').addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid');
- return false;
- }
- return true;
- },
- save: function (ev) {
- var self = this;
- if (this.validate()) {
- var values = this.get_value();
- if ($(ev.target).data('published')) {
- values.website_published = true;
- }
- this.$('.oe_slides_upload_loading').show();
- this.$('.modal-footer, .modal-body').hide();
- ajax.jsonRpc("/slides/add_slide", 'call', values).then(function (data) {
- if (data.error) {
- self.display_alert(data.error);
- self.$('.oe_slides_upload_loading').hide();
- self.$('.modal-footer, .modal-body').show();
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
- } else {
- window.location = data.url;
- }
- });
- }
+ /**
+ * @override
+ */
+ _bindEventButton: function () {
+ var channel_id = $(this).attr('channel_id');
+ slides.page_widgets['upload_dialog'] = new SlideDialog(this, channel_id).appendTo(document.body);
},
- cancel: function () {
- this.trigger("cancel");
- }
-});
-
-// bind the event to the button
-$('.oe_slide_js_upload').on('click', function () {
- var channel_id = $(this).attr('channel_id');
- slides.page_widgets['upload_dialog'] = new SlideDialog(this, channel_id).appendTo(document.body);
-});
-
-// automatically open the upload dialog if requested from query string
-if ($.deparam.querystring().enable_slide_upload !== undefined) {
- $('.oe_slide_js_upload').click();
-}
+
+});
});