[REF] website_links: reorganize javascript
This commit is contained in:
@@ -1,266 +1,364 @@
|
||||
odoo.define('website_links.website_links', function (require) {
|
||||
'use strict';
|
||||
|
||||
require('web.dom_ready');
|
||||
var sAnimations = require('website.content.snippets.animation');
|
||||
var ajax = require('web.ajax');
|
||||
var core = require('web.core');
|
||||
var rpc = require('web.rpc');
|
||||
var Widget = require('web.Widget');
|
||||
var base = require('web_editor.base');
|
||||
var weContext = require('web_editor.context');
|
||||
|
||||
var qweb = core.qweb;
|
||||
var _t = core._t;
|
||||
|
||||
var exports = {};
|
||||
|
||||
if (!$('.o_website_links_create_tracked_url').length) {
|
||||
return $.Deferred().reject("DOM doesn't contain '.o_website_links_create_tracked_url'");
|
||||
}
|
||||
var SelectBox = Widget.extend({
|
||||
xmlDependencies: ['/website_links/static/src/xml/recent_link.xml'],
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} obj
|
||||
*/
|
||||
init: function (obj) {
|
||||
this.obj = obj;
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} parent
|
||||
* @param {Object} element
|
||||
* @param {String} placeholder
|
||||
*/
|
||||
start: function (element, placeholder, parent) {
|
||||
var self = this;
|
||||
this.element = element;
|
||||
this.placeholder = placeholder;
|
||||
|
||||
var SelectBox = Widget.extend({
|
||||
init: function (obj) {
|
||||
this.obj = obj;
|
||||
},
|
||||
start: function (element, placeholder) {
|
||||
var self = this;
|
||||
this.element = element;
|
||||
this.placeholder = placeholder;
|
||||
this._fetchObjects().then(function (results) {
|
||||
self.objects = results;
|
||||
|
||||
this.fetch_objects().then(function (results) {
|
||||
self.objects = results;
|
||||
element.select2({
|
||||
placeholder: self.placeholder,
|
||||
allowClear: true,
|
||||
createSearchChoice: function (term) {
|
||||
if (self._objectExists(term)) { return null; }
|
||||
|
||||
element.select2({
|
||||
placeholder: self.placeholder,
|
||||
allowClear: true,
|
||||
createSearchChoice: function (term) {
|
||||
if (self.object_exists(term)) { return null; }
|
||||
return {id:term, text:_.str.sprintf("Create '%s'", term)};
|
||||
},
|
||||
createSearchChoicePosition: 'bottom',
|
||||
multiple: false,
|
||||
data: self.objects,
|
||||
});
|
||||
|
||||
return {id:term, text:_.str.sprintf("Create '%s'", term)};
|
||||
},
|
||||
createSearchChoicePosition: 'bottom',
|
||||
multiple: false,
|
||||
data: self.objects,
|
||||
});
|
||||
element.on('change', function (e) {
|
||||
self._onChange(e);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
element.on('change', function (e) {
|
||||
self.on_change(e);
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_fetchObjects: function () {
|
||||
return this._rpc({
|
||||
model: this.obj,
|
||||
method: 'search_read',
|
||||
})
|
||||
.then(function (result) {
|
||||
return _.map(result, function (val) {
|
||||
return {id: val.id, text:val.name};
|
||||
});
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @param {String} query
|
||||
*/
|
||||
_objectExists: function (query) {
|
||||
return _.find(this.objects, function (val) {
|
||||
return val.text.toLowerCase() === query.toLowerCase();
|
||||
}) !== undefined;
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @param {String} name
|
||||
*/
|
||||
_createObject: function (name) {
|
||||
var self = this;
|
||||
return this._rpc({
|
||||
model: this.obj,
|
||||
method: 'create',
|
||||
args: [{name:name}],
|
||||
})
|
||||
.then(function (record) {
|
||||
self.element.attr('value', record);
|
||||
self.objects.push({'id': record, 'text': name});
|
||||
});
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} e
|
||||
*/
|
||||
_onChange: function (e) {
|
||||
if (e.added && _.isString(e.added.id)) {
|
||||
this._createObject(e.added.id);
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
var RecentLinkBox = Widget.extend({
|
||||
template: 'website_links.RecentLink',
|
||||
events: {
|
||||
'click .btn_shorten_url_clipboard':'_toggleCopyButton',
|
||||
'click .o_website_links_edit_code':'_editCode',
|
||||
'click .o_website_links_ok_edit':function (e) {
|
||||
e.preventDefault();
|
||||
this._submitCode();
|
||||
},
|
||||
fetch_objects: function () {
|
||||
return rpc.query({
|
||||
model: this.obj,
|
||||
method: 'search_read',
|
||||
context: weContext.get(), // TODO use this._rpc
|
||||
})
|
||||
.then(function (result) {
|
||||
return _.map(result, function (val) {
|
||||
return {id: val.id, text:val.name};
|
||||
});
|
||||
'click .o_website_links_cancel_edit': function (e) {
|
||||
e.preventDefault();
|
||||
this._cancelEdit();
|
||||
},
|
||||
'submit #o_website_links_edit_code_form': function (e) {
|
||||
e.preventDefault();
|
||||
this._submitCode();
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} obj
|
||||
*/
|
||||
init: function (parent, link_obj) {
|
||||
this._super(parent);
|
||||
this.link_obj = link_obj;
|
||||
this.animating_copy = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} parent
|
||||
* @param {Object} element
|
||||
* @param {String} placeholder
|
||||
*/
|
||||
start: function (element, placeholder, parent) {
|
||||
new ClipboardJS(this.$('.btn_shorten_url_clipboard').get(0));
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {String} query
|
||||
*/
|
||||
_toggleCopyButton: function () {
|
||||
var self = this;
|
||||
|
||||
if (!this.animating_copy) {
|
||||
this.animating_copy = true;
|
||||
var top = this.$('.o_website_links_short_url').position().top;
|
||||
this.$('.o_website_links_short_url').clone()
|
||||
.css('position', 'absolute')
|
||||
.css('left', 15)
|
||||
.css('top', top-2)
|
||||
.css('z-index', 2)
|
||||
.removeClass('o_website_links_short_url')
|
||||
.addClass('animated-link')
|
||||
.insertAfter(this.$('.o_website_links_short_url'))
|
||||
.animate({
|
||||
opacity: 0,
|
||||
top: "-=20",
|
||||
}, 500, function () {
|
||||
self.$('.animated-link').remove();
|
||||
self.animating_copy = false;
|
||||
});
|
||||
},
|
||||
object_exists: function (query) {
|
||||
return _.find(this.objects, function (val) {
|
||||
return val.text.toLowerCase() === query.toLowerCase();
|
||||
}) !== undefined;
|
||||
},
|
||||
on_change: function (e) {
|
||||
if (e.added && _.isString(e.added.id)) {
|
||||
this.create_object(e.added.id);
|
||||
}
|
||||
},
|
||||
create_object: function (name) {
|
||||
var self = this;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_remove: function () {
|
||||
this.getParent().remove_link(this);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @param {String} message
|
||||
*/
|
||||
_notification: function (message) {
|
||||
this.$('.notification').append('<strong>' + message + '</strong>');
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_editCode: function () {
|
||||
var init_code = this.$('#o_website_links_code').html();
|
||||
this.$('#o_website_links_code').html("<form style='display:inline;' id='o_website_links_edit_code_form'><input type='hidden' id='init_code' value='" + init_code + "'/><input type='text' id='new_code' value='" + init_code + "'/></form>");
|
||||
this.$('.o_website_links_edit_code').hide();
|
||||
this.$('.copy-to-clipboard').hide();
|
||||
this.$('.o_website_links_edit_tools').show();
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_cancelEdit: function () {
|
||||
this.$('.o_website_links_edit_code').show();
|
||||
this.$('.copy-to-clipboard').show();
|
||||
this.$('.o_website_links_edit_tools').hide();
|
||||
this.$('.o_website_links_code_error').hide();
|
||||
|
||||
return rpc.query({
|
||||
model: this.obj,
|
||||
method: 'create',
|
||||
args: [{name:name}],
|
||||
context: weContext.get(), // TODO use this._rpc
|
||||
})
|
||||
.then(function (record) {
|
||||
self.element.attr('value', record);
|
||||
self.objects.push({'id': record, 'text': name});
|
||||
});
|
||||
},
|
||||
});
|
||||
var old_code = this.$('#o_website_links_edit_code_form #init_code').val();
|
||||
this.$('#o_website_links_code').html(old_code);
|
||||
|
||||
var RecentLinkBox = Widget.extend({
|
||||
template: 'website_links.RecentLink',
|
||||
events: {
|
||||
'click .btn_shorten_url_clipboard':'toggle_copy_button',
|
||||
'click .o_website_links_edit_code':'edit_code',
|
||||
'click .o_website_links_ok_edit':function (e) {
|
||||
e.preventDefault();
|
||||
this.submit_code();
|
||||
},
|
||||
'click .o_website_links_cancel_edit': function (e) {
|
||||
e.preventDefault();
|
||||
this.cancel_edit();
|
||||
},
|
||||
'submit #o_website_links_edit_code_form': function (e) {
|
||||
e.preventDefault();
|
||||
this.submit_code();
|
||||
},
|
||||
},
|
||||
init: function (parent, link_obj) {
|
||||
this._super(parent);
|
||||
this.link_obj = link_obj;
|
||||
this.animating_copy = false;
|
||||
},
|
||||
start: function () {
|
||||
new ClipboardJS(this.$('.btn_shorten_url_clipboard').get(0));
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
toggle_copy_button: function () {
|
||||
var self = this;
|
||||
this.$('#code-error').remove();
|
||||
this.$('#o_website_links_code form').remove();
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_submitCode: function () {
|
||||
var self = this;
|
||||
|
||||
if (!this.animating_copy) {
|
||||
this.animating_copy = true;
|
||||
var top = this.$('.o_website_links_short_url').position().top;
|
||||
this.$('.o_website_links_short_url').clone()
|
||||
.css('position', 'absolute')
|
||||
.css('left', 15)
|
||||
.css('top', top-2)
|
||||
.css('z-index', 2)
|
||||
.removeClass('o_website_links_short_url')
|
||||
.addClass('animated-link')
|
||||
.insertAfter(this.$('.o_website_links_short_url'))
|
||||
.animate({
|
||||
opacity: 0,
|
||||
top: "-=20",
|
||||
}, 500, function () {
|
||||
self.$('.animated-link').remove();
|
||||
self.animating_copy = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
remove: function () {
|
||||
this.getParent().remove_link(this);
|
||||
},
|
||||
notification: function (message) {
|
||||
this.$('.notification').append('<strong>' + message + '</strong>');
|
||||
},
|
||||
edit_code: function () {
|
||||
var init_code = this.$('#o_website_links_code').html();
|
||||
var init_code = this.$('#o_website_links_edit_code_form #init_code').val();
|
||||
var new_code = this.$('#o_website_links_edit_code_form #new_code').val();
|
||||
|
||||
this.$('#o_website_links_code').html("<form style='display:inline;' id='o_website_links_edit_code_form'><input type='hidden' id='init_code' value='" + init_code + "'/><input type='text' id='new_code' value='" + init_code + "'/></form>");
|
||||
this.$('.o_website_links_edit_code').hide();
|
||||
this.$('.copy-to-clipboard').hide();
|
||||
this.$('.o_website_links_edit_tools').show();
|
||||
},
|
||||
cancel_edit: function () {
|
||||
this.$('.o_website_links_edit_code').show();
|
||||
this.$('.copy-to-clipboard').show();
|
||||
this.$('.o_website_links_edit_tools').hide();
|
||||
this.$('.o_website_links_code_error').hide();
|
||||
if (new_code === '') {
|
||||
self.$('.o_website_links_code_error').html("The code cannot be left empty");
|
||||
self.$('.o_website_links_code_error').show();
|
||||
return;
|
||||
}
|
||||
|
||||
var old_code = this.$('#o_website_links_edit_code_form #init_code').val();
|
||||
this.$('#o_website_links_code').html(old_code);
|
||||
function ShowNewCode(new_code) {
|
||||
self.$('.o_website_links_code_error').html('');
|
||||
self.$('.o_website_links_code_error').hide();
|
||||
|
||||
this.$('#code-error').remove();
|
||||
this.$('#o_website_links_code form').remove();
|
||||
},
|
||||
submit_code: function () {
|
||||
var self = this;
|
||||
self.$('#o_website_links_code form').remove();
|
||||
|
||||
var init_code = this.$('#o_website_links_edit_code_form #init_code').val();
|
||||
var new_code = this.$('#o_website_links_edit_code_form #new_code').val();
|
||||
// Show new code
|
||||
var host = self.$('#o_website_links_host').html();
|
||||
self.$('#o_website_links_code').html(new_code);
|
||||
|
||||
if (new_code === '') {
|
||||
self.$('.o_website_links_code_error').html("The code cannot be left empty");
|
||||
self.$('.o_website_links_code_error').show();
|
||||
return;
|
||||
}
|
||||
// Update button copy to clipboard
|
||||
self.$('.btn_shorten_url_clipboard').attr('data-clipboard-text', host + new_code);
|
||||
|
||||
function show_new_code(new_code) {
|
||||
self.$('.o_website_links_code_error').html('');
|
||||
self.$('.o_website_links_code_error').hide();
|
||||
// Show action again
|
||||
self.$('.o_website_links_edit_code').show();
|
||||
self.$('.copy-to-clipboard').show();
|
||||
self.$('.o_website_links_edit_tools').hide();
|
||||
}
|
||||
|
||||
self.$('#o_website_links_code form').remove();
|
||||
|
||||
// Show new code
|
||||
var host = self.$('#o_website_links_host').html();
|
||||
self.$('#o_website_links_code').html(new_code);
|
||||
|
||||
// Update button copy to clipboard
|
||||
self.$('.btn_shorten_url_clipboard').attr('data-clipboard-text', host + new_code);
|
||||
|
||||
// Show action again
|
||||
self.$('.o_website_links_edit_code').show();
|
||||
self.$('.copy-to-clipboard').show();
|
||||
self.$('.o_website_links_edit_tools').hide();
|
||||
}
|
||||
|
||||
if (init_code === new_code) {
|
||||
show_new_code(new_code);
|
||||
}
|
||||
else {
|
||||
ajax.jsonRpc('/website_links/add_code', 'call', {'init_code':init_code, 'new_code':new_code})
|
||||
.then(function (result) {
|
||||
show_new_code(result[0].code);
|
||||
})
|
||||
.fail(function () {
|
||||
self.$('.o_website_links_code_error').show();
|
||||
self.$('.o_website_links_code_error').html("This code is already taken");
|
||||
}) ;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
var RecentLinks = Widget.extend({
|
||||
init: function () {
|
||||
this._super();
|
||||
},
|
||||
get_recent_links: function (filter) {
|
||||
var self = this;
|
||||
|
||||
ajax.jsonRpc('/website_links/recent_links', 'call', {'filter':filter, 'limit':20})
|
||||
if (init_code === new_code) {
|
||||
ShowNewCode(new_code);
|
||||
}
|
||||
else {
|
||||
ajax.jsonRpc('/website_links/add_code', 'call', {'init_code':init_code, 'new_code':new_code})
|
||||
.then(function (result) {
|
||||
_.each(result.reverse(), function (link) {
|
||||
self.add_link(link);
|
||||
});
|
||||
|
||||
self.update_notification();
|
||||
ShowNewCode(result[0].code);
|
||||
})
|
||||
.fail(function () {
|
||||
var message = _t("Unable to get recent links");
|
||||
self.$el.append("<div class='alert alert-danger'>" + message + "</div>");
|
||||
self.$('.o_website_links_code_error').show();
|
||||
self.$('.o_website_links_code_error').html("This code is already taken");
|
||||
}) ;
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
var RecentLinks = Widget.extend({
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
init: function () {
|
||||
this._super();
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_getRecentLinks: function (filter) {
|
||||
var self = this;
|
||||
ajax.jsonRpc('/website_links/recent_links', 'call', {'filter':filter, 'limit':20})
|
||||
.then(function (result) {
|
||||
_.each(result.reverse(), function (link) {
|
||||
self._addLink(link);
|
||||
});
|
||||
},
|
||||
add_link: function (link) {
|
||||
var nb_links = this.getChildren().length;
|
||||
|
||||
var recent_link_box = new RecentLinkBox(this, link);
|
||||
recent_link_box.prependTo(this.$el);
|
||||
$('.link-tooltip').tooltip();
|
||||
self._updateNotification();
|
||||
})
|
||||
.fail(function () {
|
||||
var message = _t("Unable to get recent links");
|
||||
self.$el.append("<div class='alert alert-danger'>" + message + "</div>");
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_addLink: function (link) {
|
||||
var nb_links = this.getChildren().length;
|
||||
var recent_link_box = new RecentLinkBox(this, link);
|
||||
recent_link_box.prependTo(this.$el);
|
||||
$('.link-tooltip').tooltip();
|
||||
|
||||
if (nb_links === 0) {
|
||||
this.update_notification();
|
||||
}
|
||||
},
|
||||
remove_links: function () {
|
||||
_.invoke(this.getChildren(), 'remove');
|
||||
},
|
||||
remove_link: function (link) {
|
||||
link.destroy();
|
||||
},
|
||||
update_notification: function () {
|
||||
if (this.getChildren().length === 0) {
|
||||
var message = _t("You don't have any recent links.");
|
||||
$('.o_website_links_recent_links_notification').html("<div class='alert alert-info'>" + message + "</div>");
|
||||
}
|
||||
else {
|
||||
$('.o_website_links_recent_links_notification').empty();
|
||||
}
|
||||
},
|
||||
});
|
||||
if (nb_links === 0) {
|
||||
this._updateNotification();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_removeLinks: function () {
|
||||
$('#o_website_links_recent_links .link-row').each(function () {
|
||||
this.remove();
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_removeLink: function (link) {
|
||||
link.destroy();
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_updateNotification: function () {
|
||||
if (this.getChildren().length === 0) {
|
||||
var message = _t("You don't have any recent links.");
|
||||
$('.o_website_links_recent_links_notification').html("<div class='alert alert-info'>" + message + "</div>");
|
||||
}
|
||||
else {
|
||||
$('.o_website_links_recent_links_notification').empty();
|
||||
}
|
||||
},
|
||||
|
||||
ajax.loadXML('/website_links/static/src/xml/recent_link.xml', qweb);
|
||||
});
|
||||
|
||||
base.ready().done(function () {
|
||||
sAnimations.registry.websiteLinks = sAnimations.Class.extend({
|
||||
selector: '.o_website_links_create_tracked_url',
|
||||
read_events: {
|
||||
'click #filter-newest-links': '_onFilterNewestLinks',
|
||||
'click #filter-most-clicked-links': '_onFilterMostClickedLinks',
|
||||
'click #filter-recently-used-links': '_onFilterRecentlyUsedLinks',
|
||||
'click #generated_tracked_link a': '_onGeneratedTrackedLink',
|
||||
'keyup #url': '_onUrlKeyUp',
|
||||
'click #btn_shorten_url': '_onBtnShortenUrl',
|
||||
'submit #o_website_links_link_tracker_form': '_onSubmitForm'
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} parent
|
||||
*/
|
||||
start: function (parent) {
|
||||
// UTMS selects widgets
|
||||
var campaign_select = new SelectBox('utm.campaign');
|
||||
campaign_select.start($("#campaign-select"), _t('e.g. Promotion of June, Winter Newsletter, ..'));
|
||||
@@ -272,137 +370,162 @@ if (!$('.o_website_links_create_tracked_url').length) {
|
||||
source_select.start($("#source-select"), _t('e.g. Search Engine, Website page, ..'));
|
||||
|
||||
// Recent Links Widgets
|
||||
var recent_links = new RecentLinks();
|
||||
recent_links.appendTo($("#o_website_links_recent_links"));
|
||||
recent_links.get_recent_links('newest');
|
||||
|
||||
$('#filter-newest-links').click(function () {
|
||||
recent_links.remove_links();
|
||||
recent_links.get_recent_links('newest');
|
||||
});
|
||||
|
||||
$('#filter-most-clicked-links').click(function () {
|
||||
recent_links.remove_links();
|
||||
recent_links.get_recent_links('most-clicked');
|
||||
});
|
||||
|
||||
$('#filter-recently-used-links').click(function () {
|
||||
recent_links.remove_links();
|
||||
recent_links.get_recent_links('recently-used');
|
||||
});
|
||||
this.recent_links = new RecentLinks();
|
||||
this.recent_links.appendTo($("#o_website_links_recent_links"));
|
||||
this.recent_links._getRecentLinks('newest');
|
||||
|
||||
// Clipboard Library
|
||||
new ClipboardJS($("#btn_shorten_url").get(0));
|
||||
|
||||
$("#generated_tracked_link a").click(function () {
|
||||
$("#generated_tracked_link a").text("Copied").removeClass("btn-primary").addClass("btn-success");
|
||||
setTimeout(function () {
|
||||
$("#generated_tracked_link a").text("Copy").removeClass("btn-success").addClass("btn-primary");
|
||||
}, '5000');
|
||||
});
|
||||
|
||||
$('#url').on('keyup', function (e) {
|
||||
if ($('#btn_shorten_url').hasClass('btn-copy') && e.which !== 13) {
|
||||
$('#btn_shorten_url').removeClass('btn-success btn-copy').addClass('btn-primary').html('Get tracked link');
|
||||
$('#generated_tracked_link').css('display', 'none');
|
||||
$('.o_website_links_utm_forms').show();
|
||||
}
|
||||
});
|
||||
|
||||
var url_copy_animating = false;
|
||||
$('#btn_shorten_url').click(function () {
|
||||
if ($('#btn_shorten_url').hasClass('btn-copy')) {
|
||||
if (!url_copy_animating) {
|
||||
url_copy_animating = true;
|
||||
|
||||
$('#generated_tracked_link').clone()
|
||||
.css('position', 'absolute')
|
||||
.css('left', '78px')
|
||||
.css('bottom', '8px')
|
||||
.css('z-index', 2)
|
||||
.removeClass('#generated_tracked_link')
|
||||
.addClass('url-animated-link')
|
||||
.appendTo($('#generated_tracked_link'))
|
||||
.animate({
|
||||
opacity: 0,
|
||||
bottom: "+=20",
|
||||
}, 500, function () {
|
||||
$('.url-animated-link').remove();
|
||||
url_copy_animating = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Add the RecentLinkBox widget and send the form when the user generate the link
|
||||
$("#o_website_links_link_tracker_form").submit(function (event) {
|
||||
|
||||
if ($('#btn_shorten_url').hasClass('btn-copy')) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
// Get URL and UTMs
|
||||
var campaign_id = $('#campaign-select').attr('value');
|
||||
var medium_id = $('#channel-select').attr('value');
|
||||
var source_id = $('#source-select').attr('value');
|
||||
|
||||
var params = {};
|
||||
params.url = $("#url").val();
|
||||
if (campaign_id !== '') { params.campaign_id = parseInt(campaign_id); }
|
||||
if (medium_id !== '') { params.medium_id = parseInt(medium_id); }
|
||||
if (source_id !== '') { params.source_id = parseInt(source_id); }
|
||||
|
||||
$('#btn_shorten_url').text(_t('Generating link...'));
|
||||
|
||||
ajax.jsonRpc("/website_links/new", 'call', params)
|
||||
.then(function (result) {
|
||||
if ('error' in result) {
|
||||
// Handle errors
|
||||
if (result.error === 'empty_url') {
|
||||
$('.notification').html("<div class='alert alert-danger'>The URL is empty.</div>");
|
||||
}
|
||||
else if (result.error === 'url_not_found') {
|
||||
$('.notification').html("<div class='alert alert-danger'>URL not found (404)</div>");
|
||||
}
|
||||
else {
|
||||
$('.notification').html("<div class='alert alert-danger'>An error occur while trying to generate your link. Try again later.</div>");
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Link generated, clean the form and show the link
|
||||
var link = result[0];
|
||||
|
||||
$('#btn_shorten_url').removeClass('btn-primary').addClass('btn-success btn-copy').html('Copy');
|
||||
$('#btn_shorten_url').attr('data-clipboard-text', link.short_url);
|
||||
|
||||
$('.notification').html('');
|
||||
$('#generated_tracked_link').html(link.short_url);
|
||||
$('#generated_tracked_link').css('display', 'inline');
|
||||
|
||||
recent_links.add_link(link);
|
||||
|
||||
// Clean URL and UTM selects
|
||||
$('#campaign-select').select2('val', '');
|
||||
$('#channel-select').select2('val', '');
|
||||
$('#source-select').select2('val', '');
|
||||
|
||||
$('.o_website_links_utm_forms').hide();
|
||||
}
|
||||
});
|
||||
});
|
||||
this.url_copy_animating = false;
|
||||
|
||||
$(function () {
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
exports.SelectBox = SelectBox;
|
||||
exports.RecentLinkBox = RecentLinkBox;
|
||||
exports.RecentLinks = RecentLinks;
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_onFilterNewestLinks: function () {
|
||||
this.recent_links._removeLinks();
|
||||
this.recent_links._getRecentLinks('newest');
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_onFilterMostClickedLinks: function () {
|
||||
this.recent_links._removeLinks();
|
||||
this.recent_links._getRecentLinks('most-clicked');
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_onFilterRecentlyUsedLinks: function () {
|
||||
this.recent_links._removeLinks();
|
||||
this.recent_links._getRecentLinks('recently-used');
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_onGeneratedTrackedLink: function () {
|
||||
$("#generated_tracked_link a").text("Copied").removeClass("btn-primary").addClass("btn-success");
|
||||
setTimeout(function () {
|
||||
$("#generated_tracked_link a").text("Copy").removeClass("btn-success").addClass("btn-primary");
|
||||
}, '5000');
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} e
|
||||
*/
|
||||
_onUrlKeyUp: function (e) {
|
||||
if ($('#btn_shorten_url').hasClass('btn-copy') && e.which !== 13) {
|
||||
$('#btn_shorten_url').removeClass('btn-success btn-copy').addClass('btn-primary').html('Get tracked link');
|
||||
$('#generated_tracked_link').css('display', 'none');
|
||||
$('.o_website_links_utm_forms').show();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_onBtnShortenUrl: function () {
|
||||
if ($('#btn_shorten_url').hasClass('btn-copy')) {
|
||||
if (!this.url_copy_animating) {
|
||||
this.url_copy_animating = true;
|
||||
|
||||
$('#generated_tracked_link').clone()
|
||||
.css('position', 'absolute')
|
||||
.css('left', '78px')
|
||||
.css('bottom', '8px')
|
||||
.css('z-index', 2)
|
||||
.removeClass('#generated_tracked_link')
|
||||
.addClass('url-animated-link')
|
||||
.appendTo($('#generated_tracked_link'))
|
||||
.animate({
|
||||
opacity: 0,
|
||||
bottom: "+=20",
|
||||
}, 500, function () {
|
||||
$('.url-animated-link').remove();
|
||||
this.url_copy_animating = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Add the RecentLinkBox widget and send the form when the user generate the link
|
||||
*
|
||||
* @override
|
||||
* @param {Object} ev
|
||||
*/
|
||||
_onSubmitForm: function (ev) {
|
||||
if ($('#btn_shorten_url').hasClass('btn-copy')) {
|
||||
ev.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
|
||||
// Get URL and UTMs
|
||||
var campaign_id = $('#campaign-select').attr('value');
|
||||
var medium_id = $('#channel-select').attr('value');
|
||||
var source_id = $('#source-select').attr('value');
|
||||
|
||||
var params = {};
|
||||
params.url = $("#url").val();
|
||||
if (campaign_id !== '') { params.campaign_id = parseInt(campaign_id); }
|
||||
if (medium_id !== '') { params.medium_id = parseInt(medium_id); }
|
||||
if (source_id !== '') { params.source_id = parseInt(source_id); }
|
||||
|
||||
$('#btn_shorten_url').text(_t('Generating link...'));
|
||||
|
||||
ajax.jsonRpc("/website_links/new", 'call', params)
|
||||
.then(function (result) {
|
||||
if ('error' in result) {
|
||||
// Handle errors
|
||||
if (result.error === 'empty_url') {
|
||||
$('.notification').html("<div class='alert alert-danger'>The URL is empty.</div>");
|
||||
}
|
||||
else if (result.error === 'url_not_found') {
|
||||
$('.notification').html("<div class='alert alert-danger'>URL not found (404)</div>");
|
||||
}
|
||||
else {
|
||||
$('.notification').html("<div class='alert alert-danger'>An error occur while trying to generate your link. Try again later.</div>");
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Link generated, clean the form and show the link
|
||||
var link = result[0];
|
||||
|
||||
$('#btn_shorten_url').removeClass('btn-primary').addClass('btn-success btn-copy').html('Copy');
|
||||
$('#btn_shorten_url').attr('data-clipboard-text', link.short_url);
|
||||
|
||||
$('.notification').html('');
|
||||
$('#generated_tracked_link').html(link.short_url);
|
||||
$('#generated_tracked_link').css('display', 'inline');
|
||||
|
||||
this.recent_links._addLink(link);
|
||||
|
||||
// Clean URL and UTM selects
|
||||
$('#campaign-select').select2('val', '');
|
||||
$('#channel-select').select2('val', '');
|
||||
$('#source-select').select2('val', '');
|
||||
|
||||
$('.o_website_links_utm_forms').hide();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
exports.SelectBox = SelectBox;
|
||||
exports.RecentLinkBox = RecentLinkBox;
|
||||
exports.RecentLinks = RecentLinks;
|
||||
|
||||
return exports;
|
||||
|
||||
});
|
||||
|
||||
@@ -1,235 +1,199 @@
|
||||
odoo.define('website_links.charts', function (require) {
|
||||
'use strict';
|
||||
|
||||
require('web.dom_ready');
|
||||
var rpc = require('web.rpc');
|
||||
var sAnimations = require('website.content.snippets.animation');
|
||||
var Widget = require('web.Widget');
|
||||
var base = require('web_editor.base');
|
||||
var weContext = require('web_editor.context');
|
||||
var core = require('web.core');
|
||||
|
||||
var _t = core._t;
|
||||
var exports = {};
|
||||
|
||||
if (!$('.o_website_links_chart').length) {
|
||||
return $.Deferred().reject("DOM doesn't contain '.o_website_links_chart'");
|
||||
}
|
||||
var BarChart = Widget.extend({
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} $element
|
||||
* @param {Object} begin_date
|
||||
* @param {Object} end_date
|
||||
* @param {Object} dates
|
||||
*/
|
||||
init: function ($element, begin_date, end_date, dates) {
|
||||
this.$element = $element;
|
||||
this.begin_date = begin_date;
|
||||
this.end_date = end_date;
|
||||
this.number_of_days = this.end_date.diff(this.begin_date, 'days') + 2;
|
||||
this.dates = dates;
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} parent
|
||||
*/
|
||||
start: function (parent) {
|
||||
var self = this;
|
||||
|
||||
var BarChart = Widget.extend({
|
||||
init: function ($element, begin_date, end_date, dates) {
|
||||
this.$element = $element;
|
||||
this.begin_date = begin_date;
|
||||
this.end_date = end_date;
|
||||
this.number_of_days = this.end_date.diff(this.begin_date, 'days') + 2;
|
||||
this.dates = dates;
|
||||
},
|
||||
start: function () {
|
||||
var self = this;
|
||||
// Accessor functions
|
||||
function getDate(d) { return new Date(d[0]); }
|
||||
function getNbClicks(d) { return d[1]; }
|
||||
|
||||
// Accessor functions
|
||||
function getDate(d) { return new Date(d[0]); }
|
||||
function getNbClicks(d) { return d[1]; }
|
||||
// Prune tick values for visibility purpose
|
||||
function getPrunedTickValues(ticks, nb_desired_ticks) {
|
||||
var nb_values = ticks.length;
|
||||
var keep_one_of = Math.max(1, Math.floor(nb_values / nb_desired_ticks));
|
||||
|
||||
// Prune tick values for visibility purpose
|
||||
function getPrunedTickValues(ticks, nb_desired_ticks) {
|
||||
var nb_values = ticks.length;
|
||||
var keep_one_of = Math.max(1, Math.floor(nb_values / nb_desired_ticks));
|
||||
|
||||
return _.filter(ticks, function (d, i) {
|
||||
return i % keep_one_of === 0;
|
||||
});
|
||||
}
|
||||
|
||||
// Fill data for each day (with 0 click for days without data)
|
||||
var clicks_array = [];
|
||||
var begin_date_copy = this.begin_date;
|
||||
for (var i = 0 ; i < this.number_of_days ; i++) {
|
||||
var date_key = begin_date_copy.format('YYYY-MM-DD');
|
||||
clicks_array.push([date_key, (date_key in this.dates) ? this.dates[date_key] : 0]);
|
||||
begin_date_copy.add(1, 'days');
|
||||
}
|
||||
|
||||
// Set title
|
||||
var nb_clicks = _.reduce(clicks_array, function (total, val) { return total + val[1] ; }, 0);
|
||||
$(this.$element + ' .title').html(nb_clicks + _t(' clicks'));
|
||||
|
||||
// Fit data into the NVD3 scheme
|
||||
var chart_data = [{}];
|
||||
chart_data[0]['key'] = _t('# of clicks');
|
||||
chart_data[0]['values'] = clicks_array;
|
||||
|
||||
nv.addGraph(function () {
|
||||
var chart = nv.models.lineChart()
|
||||
.x(function (d) { return getDate(d); })
|
||||
.y(function (d) { return getNbClicks(d); })
|
||||
.margin({top: 10, right: 60, bottom: 60, left: 60})
|
||||
.showYAxis(true)
|
||||
.showXAxis(true);
|
||||
|
||||
// Reduce the number of labels on the X axis for visibility
|
||||
var tick_values = getPrunedTickValues(chart_data[0]['values'], 10);
|
||||
|
||||
chart.xAxis
|
||||
.tickFormat(function (d) { return d3.time.format("%d/%m/%y")(new Date(d)); })
|
||||
.tickValues(_.map(tick_values, function (d) { return getDate(d).getTime(); }))
|
||||
.rotateLabels(55);
|
||||
|
||||
chart.yAxis
|
||||
.tickFormat(d3.format("d"))
|
||||
.ticks(Math.min(chart_data[0]['values'].length - 1, 10));
|
||||
|
||||
d3.select(self.$element + ' svg')
|
||||
.datum(chart_data)
|
||||
.call(chart);
|
||||
|
||||
return self.chart = chart;
|
||||
return _.filter(ticks, function (d, i) {
|
||||
return i % keep_one_of === 0;
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
var PieChart = Widget.extend({
|
||||
init: function ($element, data) {
|
||||
this.data = data;
|
||||
this.$element = $element;
|
||||
},
|
||||
start: function () {
|
||||
var self = this;
|
||||
// Fill data for each day (with 0 click for days without data)
|
||||
var clicks_array = [];
|
||||
var begin_date_copy = this.begin_date;
|
||||
for (var i = 0 ; i < this.number_of_days ; i++) {
|
||||
var date_key = begin_date_copy.format('YYYY-MM-DD');
|
||||
clicks_array.push([date_key, (date_key in this.dates) ? this.dates[date_key] : 0]);
|
||||
begin_date_copy.add(1, 'days');
|
||||
}
|
||||
|
||||
// Process country data to fit into the NVD3 scheme
|
||||
var processed_data = [];
|
||||
for (var i = 0 ; i < this.data.length ; i++) {
|
||||
var country_name = this.data[i]['country_id'] ? this.data[i]['country_id'][1] : _t('Undefined');
|
||||
processed_data.push({'label':country_name + ' (' + this.data[i]['country_id_count'] + ')', 'value':this.data[i]['country_id_count']});
|
||||
}
|
||||
// Set title
|
||||
var nb_clicks = _.reduce(clicks_array, function (total, val) { return total + val[1] ; }, 0);
|
||||
$(this.$element + ' .title').html(nb_clicks + _t(' clicks'));
|
||||
|
||||
// Set title
|
||||
$(this.$element + ' .title').html(this.data.length + _t(' countries'));
|
||||
// Fit data into the NVD3 scheme
|
||||
var chart_data = [{}];
|
||||
chart_data[0]['key'] = _t('# of clicks');
|
||||
chart_data[0]['values'] = clicks_array;
|
||||
|
||||
nv.addGraph(function () {
|
||||
var chart = nv.models.pieChart()
|
||||
.x(function (d) { return d.label; })
|
||||
.y(function (d) { return d.value; })
|
||||
.showLabels(false);
|
||||
nv.addGraph(function () {
|
||||
var chart = nv.models.lineChart()
|
||||
.x(function (d) { return getDate(d); })
|
||||
.y(function (d) { return getNbClicks(d); })
|
||||
.showYAxis(true)
|
||||
.showXAxis(true);
|
||||
|
||||
d3.select(self.$element + ' svg')
|
||||
.datum(processed_data)
|
||||
.transition().duration(1200)
|
||||
.call(chart);
|
||||
// Reduce the number of labels on the X axis for visibility
|
||||
var tick_values = getPrunedTickValues(chart_data[0]['values'], 10);
|
||||
|
||||
return self.chart = chart;
|
||||
});
|
||||
},
|
||||
});
|
||||
chart.xAxis
|
||||
.tickFormat(function (d) { return d3.time.format("%d/%m/%y")(new Date(d)); })
|
||||
.tickValues(_.map(tick_values, function (d) { return getDate(d).getTime(); }))
|
||||
.rotateLabels(55);
|
||||
|
||||
base.ready().done(function () {
|
||||
// Resize the chart when a tab is opened, because NVD3 automatically reduce the size
|
||||
// of the chart to 5px width when the bootstrap tab is closed.
|
||||
var charts = {};
|
||||
$(".graph-tabs li a").click(function (e) {
|
||||
e.preventDefault();
|
||||
$(this).tab('show');
|
||||
_.chain(charts).pluck('chart').invoke('update'); // Force NVD3 to redraw the chart
|
||||
chart.yAxis
|
||||
.tickFormat(d3.format("d"))
|
||||
.ticks(chart_data[0]['values'].length - 1);
|
||||
|
||||
d3.select(self.$element + ' svg')
|
||||
.datum(chart_data)
|
||||
.call(chart);
|
||||
|
||||
return self.chart = chart;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
var PieChart = Widget.extend({
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} $element
|
||||
* @param {Object} data
|
||||
*/
|
||||
init: function ($element, data) {
|
||||
this.data = data;
|
||||
this.$element = $element;
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} parent
|
||||
*/
|
||||
start: function (parent) {
|
||||
var self = this;
|
||||
|
||||
// Process country data to fit into the NVD3 scheme
|
||||
var processed_data = [];
|
||||
for (var i = 0 ; i < this.data.length ; i++) {
|
||||
var country_name = this.data[i]['country_id'] ? this.data[i]['country_id'][1] : _t('Undefined');
|
||||
processed_data.push({'label':country_name + ' (' + this.data[i]['country_id_count'] + ')', 'value':this.data[i]['country_id_count']});
|
||||
}
|
||||
|
||||
// Set title
|
||||
$(this.$element + ' .title').html(this.data.length + _t(' countries'));
|
||||
|
||||
nv.addGraph(function () {
|
||||
var chart = nv.models.pieChart()
|
||||
.x(function (d) { return d.label; })
|
||||
.y(function (d) { return d.value; })
|
||||
.showLabels(false);
|
||||
|
||||
d3.select(self.$element + ' svg')
|
||||
.datum(processed_data)
|
||||
.transition().duration(1200)
|
||||
.call(chart);
|
||||
|
||||
return self.chart = chart;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
sAnimations.registry.websiteLinksCharts = sAnimations.Class.extend({
|
||||
selector: '.o_website_links_chart',
|
||||
read_events: {
|
||||
'click .graph-tabs li a': '_onResizeChart',
|
||||
'click .copy-to-clipboard': '_onCopyToClipboard'
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} parent
|
||||
*/
|
||||
start: function (parent) {
|
||||
this.charts = {};
|
||||
|
||||
// Get the code of the link
|
||||
var link_id = $('#link_id').val();
|
||||
|
||||
var links_domain = ['link_id', '=', parseInt(link_id)];
|
||||
this.links_domain = ['link_id', '=', parseInt(link_id)];
|
||||
|
||||
var total_clicks = function () {
|
||||
return rpc.query({
|
||||
model: 'link.tracker.click',
|
||||
method: 'search_count',
|
||||
args: [[links_domain]],
|
||||
context: weContext.get(), // TODO use this._rpc
|
||||
});
|
||||
};
|
||||
$.when(this._totalClicks(),
|
||||
this._clicksByDay(),
|
||||
this._clicksByCountry(),
|
||||
this._lastWeekClicksByCountry(),
|
||||
this._lastMonthClicksByCountry())
|
||||
.done(function (_totalClicks, _clicksByDay, _clicksByCountry, _lastWeekClicksByCountry, _lastMonthClicksByCountry) {
|
||||
|
||||
var clicks_by_day = function () {
|
||||
return rpc.query({
|
||||
model: 'link.tracker.click',
|
||||
method: 'read_group',
|
||||
args: [[links_domain], ['create_date']],
|
||||
kwargs: {groupby:'create_date:day'},
|
||||
context: weContext.get(), // TODO use this._rpc
|
||||
});
|
||||
};
|
||||
|
||||
var clicks_by_country = function () {
|
||||
return rpc.query({
|
||||
model: 'link.tracker.click',
|
||||
method: 'read_group',
|
||||
args: [[links_domain], ['country_id']],
|
||||
kwargs: {groupby:'country_id'},
|
||||
context: weContext.get(), // TODO use this._rpc
|
||||
});
|
||||
};
|
||||
|
||||
var last_week_clicks_by_country = function () {
|
||||
var interval = moment().subtract(7, 'days').format("YYYY-MM-DD");
|
||||
return rpc.query({
|
||||
model: 'link.tracker.click',
|
||||
method: 'read_group',
|
||||
args: [[links_domain, ['create_date', '>', interval]], ['country_id']],
|
||||
kwargs: {groupby:'country_id'},
|
||||
context: weContext.get(), // TODO use this._rpc
|
||||
});
|
||||
};
|
||||
|
||||
var last_month_clicks_by_country = function () {
|
||||
var interval = moment().subtract(30, 'days').format("YYYY-MM-DD");
|
||||
return rpc.query({
|
||||
model: 'link.tracker.click',
|
||||
method: 'read_group',
|
||||
args: [[links_domain, ['create_date', '>', interval]], ['country_id']],
|
||||
kwargs: {groupby: 'country_id'},
|
||||
context: weContext.get(), // TODO use this._rpc
|
||||
});
|
||||
};
|
||||
|
||||
$.when(total_clicks(),
|
||||
clicks_by_day(),
|
||||
clicks_by_country(),
|
||||
last_week_clicks_by_country(),
|
||||
last_month_clicks_by_country())
|
||||
.done(function (total_clicks, clicks_by_day, clicks_by_country, last_week_clicks_by_country, last_month_clicks_by_country) {
|
||||
|
||||
if (total_clicks) {
|
||||
if (_totalClicks) {
|
||||
this.charts = {};
|
||||
var formatted_clicks_by_day = {};
|
||||
var begin_date, end_date;
|
||||
for (var i = 0 ; i < clicks_by_day.length ; i++) {
|
||||
var date = moment(clicks_by_day[i]['create_date:day'], "DD MMMM YYYY");
|
||||
for (var i = 0 ; i < _clicksByDay.length ; i++) {
|
||||
var date = moment(_clicksByDay[i]['create_date:day'], "DD MMMM YYYY");
|
||||
if (i === 0) { begin_date = date; }
|
||||
if (i === clicks_by_day.length - 1) { end_date = date; }
|
||||
formatted_clicks_by_day[date.format("YYYY-MM-DD")] = clicks_by_day[i]['create_date_count'];
|
||||
if (i === _clicksByDay.length - 1) { end_date = date; }
|
||||
formatted_clicks_by_day[date.format("YYYY-MM-DD")] = _clicksByDay[i]['create_date_count'];
|
||||
}
|
||||
|
||||
// Process all time line chart data
|
||||
var now = moment();
|
||||
|
||||
charts.all_time_bar = new BarChart('#all_time_clicks_chart', begin_date, now, formatted_clicks_by_day);
|
||||
this.charts.all_time_bar = new BarChart('#all_time_clicks_chart', begin_date, now, formatted_clicks_by_day);
|
||||
|
||||
// Process month line chart data
|
||||
begin_date = moment().subtract(30, 'days');
|
||||
charts.last_month_bar = new BarChart('#last_month_clicks_chart', begin_date, now, formatted_clicks_by_day);
|
||||
this.charts.last_month_bar = new BarChart('#last_month_clicks_chart', begin_date, now, formatted_clicks_by_day);
|
||||
|
||||
// Process week line chart data
|
||||
begin_date = moment().subtract(7, 'days');
|
||||
charts.last_week_bar = new BarChart('#last_week_clicks_chart', begin_date, now, formatted_clicks_by_day);
|
||||
this.charts.last_week_bar = new BarChart('#last_week_clicks_chart', begin_date, now, formatted_clicks_by_day);
|
||||
|
||||
// Process pie charts
|
||||
charts.all_time_pie = new PieChart('#all_time_countries_charts', clicks_by_country);
|
||||
charts.last_month_pie = new PieChart('#last_month_countries_charts', last_month_clicks_by_country);
|
||||
charts.last_week_pie = new PieChart('#last_week_countries_charts', last_week_clicks_by_country);
|
||||
this.charts.all_time_pie = new PieChart('#all_time_countries_charts', _clicksByCountry);
|
||||
this.charts.last_month_pie = new PieChart('#last_month_countries_charts', _lastMonthClicksByCountry);
|
||||
this.charts.last_week_pie = new PieChart('#last_week_countries_charts', _lastWeekClicksByCountry);
|
||||
|
||||
var row_width = $('#all_time_countries_charts').parent().width();
|
||||
var charts_svg = $('#all_time_countries_charts,last_month_countries_charts,last_week_countries_charts').find('svg');
|
||||
charts_svg.css('height', Math.max(clicks_by_country.length * (row_width > 750 ? 1 : 2), 20) + 'em');
|
||||
charts_svg.css('height', Math.max(_clicksByCountry.length * (row_width > 750 ? 1 : 2), 20) + 'em');
|
||||
|
||||
_.invoke(charts, 'start');
|
||||
_.invoke(this.charts, 'start');
|
||||
|
||||
nv.utils.windowResize(function () {
|
||||
_.chain(charts).pluck('chart').invoke('update');
|
||||
_.chain(this.charts).pluck('chart').invoke('update');
|
||||
});
|
||||
}
|
||||
else {
|
||||
@@ -242,36 +206,119 @@ if (!$('.o_website_links_chart').length) {
|
||||
// Copy to clipboard link
|
||||
new ClipboardJS($('.copy-to-clipboard')[0]);
|
||||
|
||||
var animating_copy = false;
|
||||
this.animating_copy = false;
|
||||
},
|
||||
|
||||
$('.copy-to-clipboard').on('click', function (e) {
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
if (!animating_copy) {
|
||||
animating_copy = true;
|
||||
|
||||
$('.o_website_links_short_url').clone()
|
||||
.css('position', 'absolute')
|
||||
.css('left', '15px')
|
||||
.css('bottom', '10px')
|
||||
.css('z-index', 2)
|
||||
.removeClass('.o_website_links_short_url')
|
||||
.addClass('animated-link')
|
||||
.appendTo($('.o_website_links_short_url'))
|
||||
.animate({
|
||||
opacity: 0,
|
||||
bottom: "+=20",
|
||||
}, 500, function () {
|
||||
$('.animated-link').remove();
|
||||
animating_copy = false;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_totalClicks: function () {
|
||||
return this._rpc({
|
||||
model: 'link.tracker.click',
|
||||
method: 'search_count',
|
||||
args: [[this.links_domain]],
|
||||
});
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_clicksByDay: function () {
|
||||
return this._rpc({
|
||||
model: 'link.tracker.click',
|
||||
method: 'read_group',
|
||||
args: [[this.links_domain], ['create_date']],
|
||||
kwargs: {groupby:'create_date:day'},
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_clicksByCountry: function () {
|
||||
return this._rpc({
|
||||
model: 'link.tracker.click',
|
||||
method: 'read_group',
|
||||
args: [[this.links_domain], ['country_id']],
|
||||
kwargs: {groupby:'country_id'},
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_lastWeekClicksByCountry: function () {
|
||||
var interval = moment().subtract(7, 'days').format("YYYY-MM-DD");
|
||||
return this._rpc({
|
||||
model: 'link.tracker.click',
|
||||
method: 'read_group',
|
||||
args: [[this.links_domain, ['create_date', '>', interval]], ['country_id']],
|
||||
kwargs: {groupby:'country_id'},
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_lastMonthClicksByCountry: function () {
|
||||
var interval = moment().subtract(30, 'days').format("YYYY-MM-DD");
|
||||
return this._rpc({
|
||||
model: 'link.tracker.click',
|
||||
method: 'read_group',
|
||||
args: [[this.links_domain, ['create_date', '>', interval]], ['country_id']],
|
||||
kwargs: {groupby: 'country_id'},
|
||||
});
|
||||
},
|
||||
|
||||
exports.BarChart = BarChart;
|
||||
exports.PieChart = PieChart;
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resize the chart when a tab is opened, because NVD3 automatically reduce the size
|
||||
* of the chart to 5px width when the bootstrap tab is closed.
|
||||
*
|
||||
* @override
|
||||
* @param {Object} e
|
||||
*/
|
||||
_onResizeChart: function (e) {
|
||||
e.preventDefault();
|
||||
$('.graph-tabs li a').tab('show');
|
||||
_.chain(this.charts).pluck('chart').invoke('update'); // Force NVD3 to redraw the chart
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} e
|
||||
*/
|
||||
_onCopyToClipboard: function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (!this.animating_copy) {
|
||||
this.animating_copy = true;
|
||||
|
||||
$('.o_website_links_short_url').clone()
|
||||
.css('position', 'absolute')
|
||||
.css('left', '15px')
|
||||
.css('bottom', '10px')
|
||||
.css('z-index', 2)
|
||||
.removeClass('.o_website_links_short_url')
|
||||
.addClass('animated-link')
|
||||
.appendTo($('.o_website_links_short_url'))
|
||||
.animate({
|
||||
opacity: 0,
|
||||
bottom: "+=20",
|
||||
}, 500, function () {
|
||||
$('.animated-link').remove();
|
||||
this.animating_copy = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
exports.BarChart = BarChart;
|
||||
exports.PieChart = PieChart;
|
||||
|
||||
return exports;
|
||||
|
||||
});
|
||||
|
||||
@@ -1,91 +1,114 @@
|
||||
odoo.define('website_links.code_editor', function (require) {
|
||||
'use strict';
|
||||
|
||||
require('web.dom_ready');
|
||||
var sAnimations = require('website.content.snippets.animation');
|
||||
var ajax = require('web.ajax');
|
||||
|
||||
if (!$('.o_website_links_edit_code').length) {
|
||||
return $.Deferred().reject("DOM doesn't contain '.o_website_links_edit_code'");
|
||||
}
|
||||
sAnimations.registry.websiteLinksCodeEditor = sAnimations.Class.extend({
|
||||
selector: '.o_website_links_edit_code',
|
||||
read_events: {
|
||||
'click .o_website_links_edit_code': '_onEdit',
|
||||
'click .o_website_links_cancel_edit': '_onCancel',
|
||||
'submit #edit-code-form': '_onEditCodeForm',
|
||||
'click .o_website_links_ok_edit': '_onEditCodeForm'
|
||||
},
|
||||
|
||||
// Edit the short URL code
|
||||
$('.o_website_links_edit_code').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {String} new_code
|
||||
*/
|
||||
_showNewCode: function (new_code) {
|
||||
$('.o_website_links_code_error').html('');
|
||||
$('.o_website_links_code_error').hide();
|
||||
|
||||
$('#o_website_links_code form').remove();
|
||||
|
||||
// Show new code
|
||||
var host = $('#short-url-host').html();
|
||||
$('#o_website_links_code').html(new_code);
|
||||
|
||||
// Update button copy to clipboard
|
||||
$('.copy-to-clipboard').attr('data-clipboard-text', host + new_code);
|
||||
|
||||
// Show action again
|
||||
$('.o_website_links_edit_code').show();
|
||||
$('.copy-to-clipboard').show();
|
||||
$('.o_website_links_edit_tools').hide();
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_submitCode: function () {
|
||||
var init_code = $('#edit-code-form #init_code').val();
|
||||
var new_code = $('#edit-code-form #new_code').val();
|
||||
var self = this;
|
||||
|
||||
if (new_code === '') {
|
||||
self.$('.o_website_links_code_error').html("The code cannot be left empty");
|
||||
self.$('.o_website_links_code_error').show();
|
||||
return;
|
||||
}
|
||||
|
||||
this._showNewCode(new_code);
|
||||
|
||||
if (init_code === new_code) {
|
||||
this._showNewCode(new_code);
|
||||
} else {
|
||||
ajax.jsonRpc('/website_links/add_code', 'call', {'init_code':init_code, 'new_code':new_code})
|
||||
.then(function (result) {
|
||||
self._showNewCode(result[0].code);
|
||||
})
|
||||
.fail(function () {
|
||||
$('.o_website_links_code_error').show();
|
||||
$('.o_website_links_code_error').html("This code is already taken");
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_onEdit: function () {
|
||||
var init_code = $('#o_website_links_code').html();
|
||||
|
||||
$('#o_website_links_code').html("<form style='display:inline;' id='edit-code-form'><input type='hidden' id='init_code' value='" + init_code + "'/><input type='text' id='new_code' value='" + init_code + "'/></form>");
|
||||
$('.o_website_links_edit_code').hide();
|
||||
$('.copy-to-clipboard').hide();
|
||||
$('.o_website_links_edit_tools').show();
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} e
|
||||
*/
|
||||
_onCancel: function (e) {
|
||||
e.preventDefault();
|
||||
$('.o_website_links_edit_code').show();
|
||||
$('.copy-to-clipboard').show();
|
||||
$('.o_website_links_edit_tools').hide();
|
||||
$('.o_website_links_code_error').hide();
|
||||
|
||||
$('.o_website_links_cancel_edit').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
var old_code = $('#edit-code-form #init_code').val();
|
||||
$('#o_website_links_code').html(old_code);
|
||||
|
||||
$('.o_website_links_edit_code').show();
|
||||
$('.copy-to-clipboard').show();
|
||||
$('.o_website_links_edit_tools').hide();
|
||||
$('.o_website_links_code_error').hide();
|
||||
$('#code-error').remove();
|
||||
$('#o_website_links_code form').remove();
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} e
|
||||
*/
|
||||
_onEditCodeForm: function (e) {
|
||||
e.preventDefault();
|
||||
this._submitCode();
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
var old_code = $('#edit-code-form #init_code').val();
|
||||
$('#o_website_links_code').html(old_code);
|
||||
|
||||
$('#code-error').remove();
|
||||
$('#o_website_links_code form').remove();
|
||||
});
|
||||
|
||||
function submit_code() {
|
||||
var init_code = $('#edit-code-form #init_code').val();
|
||||
var new_code = $('#edit-code-form #new_code').val();
|
||||
|
||||
if (new_code === '') {
|
||||
self.$('.o_website_links_code_error').html("The code cannot be left empty");
|
||||
self.$('.o_website_links_code_error').show();
|
||||
return;
|
||||
}
|
||||
|
||||
function show_new_code(new_code) {
|
||||
$('.o_website_links_code_error').html('');
|
||||
$('.o_website_links_code_error').hide();
|
||||
|
||||
$('#o_website_links_code form').remove();
|
||||
|
||||
// Show new code
|
||||
var host = $('#short-url-host').html();
|
||||
$('#o_website_links_code').html(new_code);
|
||||
|
||||
// Update button copy to clipboard
|
||||
$('.copy-to-clipboard').attr('data-clipboard-text', host + new_code);
|
||||
|
||||
// Show action again
|
||||
$('.o_website_links_edit_code').show();
|
||||
$('.copy-to-clipboard').show();
|
||||
$('.o_website_links_edit_tools').hide();
|
||||
}
|
||||
|
||||
if (init_code === new_code) {
|
||||
show_new_code(new_code);
|
||||
}
|
||||
else {
|
||||
ajax.jsonRpc('/website_links/add_code', 'call', {'init_code':init_code, 'new_code':new_code})
|
||||
.then(function (result) {
|
||||
show_new_code(result[0].code);
|
||||
})
|
||||
.fail(function () {
|
||||
$('.o_website_links_code_error').show();
|
||||
$('.o_website_links_code_error').html("This code is already taken");
|
||||
}) ;
|
||||
}
|
||||
}
|
||||
|
||||
$('#edit-code-form').submit(function (e) {
|
||||
e.preventDefault();
|
||||
submit_code();
|
||||
});
|
||||
|
||||
$('.o_website_links_ok_edit').click(function (e) {
|
||||
e.preventDefault();
|
||||
submit_code();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,10 +3,22 @@
|
||||
* when the user click the link "Share this page" on top of the page.
|
||||
*/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
odoo.define('website_links.website_links_menu', function (require) {
|
||||
"use strict";
|
||||
|
||||
$(document).ready(function () {
|
||||
$('#o_website_links_share_page').attr('href', '/r?u=' + encodeURIComponent(window.location.href));
|
||||
});
|
||||
})();
|
||||
var sAnimations = require('website.content.snippets.animation');
|
||||
|
||||
sAnimations.registry.websiteLinksMenu = sAnimations.Class.extend({
|
||||
selector: '.navbar',
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} parent
|
||||
*/
|
||||
start: function (parent) {
|
||||
$('#o_website_links_share_page').attr('href', '/r?u=' + encodeURIComponent(window.location.href));
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<templates id="template" xml:space="preserve">
|
||||
<t t-name="website_links.RecentLink">
|
||||
<div class="row mb16">
|
||||
<div class="row mb16 link-row">
|
||||
<div class="col-md-1 col-2 text-center">
|
||||
<h4><t t-esc="widget.link_obj.count"/></h4>
|
||||
<p class="text-muted" style="margin-top: -5px;">clicks</p>
|
||||
|
||||
Reference in New Issue
Block a user