summaryrefslogtreecommitdiff
path: root/addons/sms/static/src/js
diff options
context:
space:
mode:
Diffstat (limited to 'addons/sms/static/src/js')
-rw-r--r--addons/sms/static/src/js/fields_phone_widget.js100
-rw-r--r--addons/sms/static/src/js/fields_sms_widget.js185
2 files changed, 285 insertions, 0 deletions
diff --git a/addons/sms/static/src/js/fields_phone_widget.js b/addons/sms/static/src/js/fields_phone_widget.js
new file mode 100644
index 00000000..82b8e5b3
--- /dev/null
+++ b/addons/sms/static/src/js/fields_phone_widget.js
@@ -0,0 +1,100 @@
+odoo.define('sms.fields', function (require) {
+"use strict";
+
+var basic_fields = require('web.basic_fields');
+var core = require('web.core');
+var session = require('web.session');
+
+var _t = core._t;
+
+/**
+ * Override of FieldPhone to add a button calling SMS composer if option activated (default)
+ */
+
+var Phone = basic_fields.FieldPhone;
+Phone.include({
+ /**
+ * By default, enable_sms is activated
+ *
+ * @override
+ */
+ init() {
+ this._super.apply(this, arguments);
+ this.enableSMS = 'enable_sms' in this.attrs.options ? this.attrs.options.enable_sms : true;
+ // reinject in nodeOptions (and thus in this.attrs) to signal the property
+ this.attrs.options.enable_sms = this.enableSMS;
+ },
+ /**
+ * When the send SMS button is displayed, $el becomes a div wrapping
+ * the original links.
+ * This method makes sure we always focus the phone number
+ *
+ * @override
+ */
+ getFocusableElement() {
+ if (this.enableSMS && this.mode === 'readonly') {
+ return this.$el.filter('.' + this.className);
+ }
+ return this._super.apply(this, arguments);
+ },
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * Open SMS composer wizard
+ *
+ * @private
+ */
+ _onClickSMS: function (ev) {
+ ev.preventDefault();
+ ev.stopPropagation();
+
+ var context = session.user_context;
+ context = _.extend({}, context, {
+ default_res_model: this.model,
+ default_res_id: parseInt(this.res_id),
+ default_number_field_name: this.name,
+ default_composition_mode: 'comment',
+ });
+ var self = this;
+ return this.do_action({
+ title: _t('Send SMS Text Message'),
+ type: 'ir.actions.act_window',
+ res_model: 'sms.composer',
+ target: 'new',
+ views: [[false, 'form']],
+ context: context,
+ }, {
+ on_close: function () {
+ self.trigger_up('reload');
+ }});
+ },
+
+ /**
+ * Add a button to call the composer wizard
+ *
+ * @override
+ * @private
+ */
+ _renderReadonly: function () {
+ var def = this._super.apply(this, arguments);
+ if (this.enableSMS && this.value) {
+ var $composerButton = $('<a>', {
+ title: _t('Send SMS Text Message'),
+ href: '',
+ class: 'ml-3 d-inline-flex align-items-center o_field_phone_sms',
+ html: $('<small>', {class: 'font-weight-bold ml-1', html: 'SMS'}),
+ });
+ $composerButton.prepend($('<i>', {class: 'fa fa-mobile'}));
+ $composerButton.on('click', this._onClickSMS.bind(this));
+ this.$el = this.$el.add($composerButton);
+ }
+
+ return def;
+ },
+});
+
+return Phone;
+
+});
diff --git a/addons/sms/static/src/js/fields_sms_widget.js b/addons/sms/static/src/js/fields_sms_widget.js
new file mode 100644
index 00000000..5a52d68e
--- /dev/null
+++ b/addons/sms/static/src/js/fields_sms_widget.js
@@ -0,0 +1,185 @@
+odoo.define('sms.sms_widget', function (require) {
+"use strict";
+
+var core = require('web.core');
+var fieldRegistry = require('web.field_registry');
+var FieldTextEmojis = require('mail.field_text_emojis');
+
+var _t = core._t;
+/**
+ * SmsWidget is a widget to display a textarea (the body) and a text representing
+ * the number of SMS and the number of characters. This text is computed every
+ * time the user changes the body.
+ */
+var SmsWidget = FieldTextEmojis.extend({
+ className: 'o_field_text',
+ enableEmojis: false,
+ /**
+ * @constructor
+ */
+ init: function () {
+ this._super.apply(this, arguments);
+ this.nbrChar = 0;
+ this.nbrSMS = 0;
+ this.encoding = 'GSM7';
+ this.enableEmojis = !!this.nodeOptions.enable_emojis;
+ },
+
+ /**
+ * @override
+ *"This will add the emoji dropdown to a target field (controlled by the "enableEmojis" attribute)
+ */
+ on_attach_callback: function () {
+ if (this.enableEmojis) {
+ this._super.apply(this, arguments);
+ }
+ },
+
+ //--------------------------------------------------------------------------
+ // Private: override widget
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * @override
+ */
+ _renderEdit: function () {
+ var def = this._super.apply(this, arguments);
+
+ this._compute();
+ $('.o_sms_container').remove();
+ var $sms_container = $('<div class="o_sms_container"/>');
+ $sms_container.append(this._renderSMSInfo());
+ $sms_container.append(this._renderIAPButton());
+ this.$el = this.$el.add($sms_container);
+
+ return def;
+ },
+
+ //--------------------------------------------------------------------------
+ // Private: SMS
+ //--------------------------------------------------------------------------
+
+ /**
+ * Compute the number of characters and sms
+ * @private
+ */
+ _compute: function () {
+ var content = this._getValue();
+ this.encoding = this._extractEncoding(content);
+ this.nbrChar = content.length;
+ this.nbrChar += (content.match(/\n/g) || []).length;
+ this.nbrSMS = this._countSMS(this.nbrChar, this.encoding);
+ },
+
+ /**
+ * Count the number of SMS of the content
+ * @private
+ * @returns {integer} Number of SMS
+ */
+ _countSMS: function () {
+ if (this.nbrChar === 0) {
+ return 0;
+ }
+ if (this.encoding === 'UNICODE') {
+ if (this.nbrChar <= 70) {
+ return 1;
+ }
+ return Math.ceil(this.nbrChar / 67);
+ }
+ if (this.nbrChar <= 160) {
+ return 1;
+ }
+ return Math.ceil(this.nbrChar / 153);
+ },
+
+ /**
+ * Extract the encoding depending on the characters in the content
+ * @private
+ * @param {String} content Content of the SMS
+ * @returns {String} Encoding of the content (GSM7 or UNICODE)
+ */
+ _extractEncoding: function (content) {
+ if (String(content).match(RegExp("^[@£$¥èéùìòÇ\\nØø\\rÅåΔ_ΦΓΛΩΠΨΣΘΞÆæßÉ !\\\"#¤%&'()*+,-./0123456789:;<=>?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà]*$"))) {
+ return 'GSM7';
+ }
+ return 'UNICODE';
+ },
+
+ /**
+ * Render the IAP button to redirect to IAP pricing
+ * @private
+ */
+ _renderIAPButton: function () {
+ return $('<a>', {
+ 'href': 'https://iap-services.odoo.com/iap/sms/pricing',
+ 'target': '_blank',
+ 'title': _t('SMS Pricing'),
+ 'aria-label': _t('SMS Pricing'),
+ 'class': 'fa fa-lg fa-info-circle',
+ });
+ },
+
+ /**
+ * Render the number of characters, sms and the encoding.
+ * @private
+ */
+ _renderSMSInfo: function () {
+ var string = _.str.sprintf(_t('%s characters, fits in %s SMS (%s) '), this.nbrChar, this.nbrSMS, this.encoding);
+ var $span = $('<span>', {
+ 'class': 'text-muted o_sms_count',
+ });
+ $span.text(string);
+ return $span;
+ },
+
+ /**
+ * Update widget SMS information with re-computed info about length, ...
+ * @private
+ */
+ _updateSMSInfo: function () {
+ this._compute();
+ var string = _.str.sprintf(_t('%s characters, fits in %s SMS (%s) '), this.nbrChar, this.nbrSMS, this.encoding);
+ this.$('.o_sms_count').text(string);
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ * @private
+ */
+ _onBlur: function () {
+ var content = this._getValue();
+ if( !content.trim().length && content.length > 0) {
+ this.do_warn(_t("Your SMS Text Message must include at least one non-whitespace character"));
+ this.$input.val(content.trim());
+ this._updateSMSInfo();
+ }
+ },
+
+ /**
+ * @override
+ * @private
+ */
+ _onChange: function () {
+ this._super.apply(this, arguments);
+ this._updateSMSInfo();
+ },
+
+ /**
+ * @override
+ * @private
+ */
+ _onInput: function () {
+ this._super.apply(this, arguments);
+ this._updateSMSInfo();
+ },
+});
+
+fieldRegistry.add('sms_widget', SmsWidget);
+
+return SmsWidget;
+});