diff options
Diffstat (limited to 'addons/pad/static/src')
| -rw-r--r-- | addons/pad/static/src/css/etherpad.css | 129 | ||||
| -rw-r--r-- | addons/pad/static/src/img/pad_link_companies.jpeg | bin | 0 -> 70544 bytes | |||
| -rw-r--r-- | addons/pad/static/src/js/pad.js | 193 | ||||
| -rw-r--r-- | addons/pad/static/src/xml/pad.xml | 21 |
4 files changed, 343 insertions, 0 deletions
diff --git a/addons/pad/static/src/css/etherpad.css b/addons/pad/static/src/css/etherpad.css new file mode 100644 index 00000000..a0157bb3 --- /dev/null +++ b/addons/pad/static/src/css/etherpad.css @@ -0,0 +1,129 @@ + +.oe_pad_switch_positioner { + position: relative; +} + +.oe_pad_switch { + position: absolute; + top: 5px; + left: 383px; + width: 28px; + height: 28px; + background-image: -webkit-linear-gradient(top, white, #f0f0f0); + border: solid 1px #ccc; + border-radius:3px; + text-align: center; + line-height: 28px; + overflow: hidden; + -webkit-box-sizing: border-box; + color: #666666; + cursor: pointer; + font-size: 14px; +} + +@media (max-width: 767px) { + .oe_pad_switch { + left: auto; + right: 5px; + } + html .o_scroll_hidden { + overflow: hidden; + } +} + +.oe_pad_switch:hover{ + background-image: -webkit-linear-gradient(top, #f4f4f4, #e4e4e4); +} + +.oe_pad_fullscreen .oe_pad_switch { + top:4px; +} + +.oe_pad_fullscreen { + position: fixed; + top: 0px; + left: 0px; + right: 0px; + bottom: 0px; + background-color: white; + margin:0; + padding:0; + border:none; + z-index: 1001; +} + +.oe_pad .oe_pad_content.oe_editing{ + border: solid 1px #c4c4c4; + height:500px; + -webkit-box-shadow: 0 5px 10px rgba(0,0,0,0.1); + -moz-box-shadow: 0 5px 10px rgba(0,0,0,0.1); + -ms-box-shadow: 0 5px 10px rgba(0,0,0,0.1); + -o-box-shadow: 0 5px 10px rgba(0,0,0,0.1); + box-shadow: 0 5px 10px rgba(0,0,0,0.1); +} + +.oe_pad.oe_pad_fullscreen .oe_pad_content { + height: 100%; + border: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + -ms-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; +} + +.oe_pad .oe_unconfigured { + text-align: center; + opacity: 0.75; +} + +.oe_pad_loading{ + text-align: center; + opacity: 0.75; + font-style: italic; +} + +.etherpad_readonly ul, .etherpad_readonly ol { + margin: 0; + margin-left: 1.5em; + padding: 0; +} +.etherpad_readonly ul li{ + list-style-type: disc; +} +.etherpad_readonly ol li{ + list-style-type: decimal; +} +.etherpad_readonly .indent li{ + list-style-type: none !important; +} + +.etherpad_readonly{ + font-family: arial, sans-serif; + font-size: 15px; + line-height: 19px; + word-wrap: break-word; +} + +.openerp .oe_form_nomargin .etherpad_readonly{ + padding: 10px; +} + +.etherpad_readonly ul.indent { list-style-type: none !important; } +.etherpad_readonly ol li{ list-style-type: decimal !important; } +.etherpad_readonly ol ol li{ list-style-type: lower-latin !important; } +.etherpad_readonly ol ol ol li{ list-style-type: lower-roman !important; } +.etherpad_readonly ol ol ol ol li{ list-style-type: decimal !important; } +.etherpad_readonly ol ol ol ol ol li{ list-style-type: lower-latin !important; } +.etherpad_readonly ol ol ol ol ol ol li{ list-style-type: lower-roman !important; } +.etherpad_readonly ol ol ol ol ol ol ol li{ list-style-type: decimal !important; } +.etherpad_readonly ol ol ol ol ol ol ol ol li{ list-style-type: lower-latin !important; } +.etherpad_readonly ul li { list-style-type: disc !important; } +.etherpad_readonly ul ul li { list-style-type: circle !important; } +.etherpad_readonly ul ul ul li { list-style-type: square !important; } +.etherpad_readonly ul ul ul ul li { list-style-type: disc !important; } +.etherpad_readonly ul ul ul ul ul li { list-style-type: circle !important; } +.etherpad_readonly ul ul ul ul ul ul li { list-style-type: square !important; } +.etherpad_readonly ul ul ul ul ul ul ul li { list-style-type: disc !important; } +.etherpad_readonly ul ul ul ul ul ul ul ul li { list-style-type: circle !important; } +.etherpad_readonly ul ul ul ul ul ul ul ul ul li { list-style-type: square !important; } diff --git a/addons/pad/static/src/img/pad_link_companies.jpeg b/addons/pad/static/src/img/pad_link_companies.jpeg Binary files differnew file mode 100644 index 00000000..1bce3a56 --- /dev/null +++ b/addons/pad/static/src/img/pad_link_companies.jpeg diff --git a/addons/pad/static/src/js/pad.js b/addons/pad/static/src/js/pad.js new file mode 100644 index 00000000..7107c2d6 --- /dev/null +++ b/addons/pad/static/src/js/pad.js @@ -0,0 +1,193 @@ +odoo.define('pad.pad', function (require) { +"use strict"; + +var AbstractField = require('web.AbstractField'); +var core = require('web.core'); +var fieldRegistry = require('web.field_registry'); + +var _t = core._t; + +var FieldPad = AbstractField.extend({ + template: 'FieldPad', + content: "", + events: { + 'click .oe_pad_switch': '_onToggleFullScreen', + }, + + /** + * @override + */ + willStart: function () { + if (this.isPadConfigured === undefined) { + return this._rpc({ + method: 'pad_is_configured', + model: this.model, + }).then(function (result) { + // we write on the prototype to share the information between + // all pad widgets instances, across all actions + FieldPad.prototype.isPadConfigured = result; + }); + } + return this._super.apply(this, arguments); + }, + /** + * @override + */ + start: function () { + if (!this.isPadConfigured) { + this.$(".oe_unconfigured").removeClass('d-none'); + this.$(".oe_configured").addClass('d-none'); + return Promise.resolve(); + } + if (this.mode === 'edit' && typeof(this.value) === 'object') { + this.value = this.value.toJSON(); + } + if (this.mode === 'edit' && _.str.startsWith(this.value, 'http')) { + this.url = this.value; + // please close your eyes and look elsewhere... + // Since the pad value (the url) will not change during the edition + // process, we have a problem: the description field will not be + // properly updated. We need to explicitely write the value each + // time someone edit the record in order to force the server to read + // the updated value of the pad and put it in the description field. + // + // However, the basic model optimizes away the changes if they are + // not really different from the current value. So, we need to + // either add special configuration options to the basic model, or + // to trick him into accepting the same value as being different... + // Guess what we decided... + var url = {}; + url.toJSON = _.constant(this.url); + this._setValue(url, {doNotSetDirty: true}); + } + + return this._super.apply(this, arguments); + }, + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + /** + * If we had to generate an url, we wait for the generation to be completed, + * so the current record will be associated with the correct pad url. + * + * @override + */ + commitChanges: function () { + return this.urlDef; + }, + /** + * @override + */ + isSet: function () { + return true; + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * Note that this method has some serious side effects: performing rpcs and + * setting the value of this field. This is not conventional and should not + * be copied in other code, unless really necessary. + * + * @override + * @private + */ + _renderEdit: function () { + if (this.url) { + // here, we have a valid url, so we can simply display an iframe + // with the correct src attribute + var userName = encodeURIComponent(this.getSession().name); + var url = this.url + '?showChat=false&userName=' + userName; + var content = '<iframe width="100%" height="100%" frameborder="0" src="' + url + '"></iframe>'; + this.$('.oe_pad_content').html(content); + } else if (this.value) { + // it looks like the field does not contain a valid url, so we just + // display it (it cannot be edited in that case) + this.$('.oe_pad_content').text(this.value); + } else { + // It is totally discouraged to have a render method that does + // non-rendering work, especially since the work in question + // involves doing RPCs and changing the value of the field. + // However, this is kind of necessary in this case, because the + // value of the field is actually only the url of the pad. The + // actual content will be loaded in an iframe. We could do this + // work in the basic model, but the basic model does not know that + // this widget is in edit or readonly, and we really do not want to + // create a pad url everytime a task without a pad is viewed. + var self = this; + this.urlDef = this._rpc({ + method: 'pad_generate_url', + model: this.model, + context: { + model: this.model, + field_name: this.name, + object_id: this.res_id, + record: this.recordData, + }, + }, { + shadow: true + }).then(function (result) { + // We need to write the url of the pad to trigger + // the write function which updates the actual value + // of the field to the value of the pad content + self.url = result.url; + self._setValue(result.url, {doNotSetDirty: true}); + }); + } + }, + /** + * @override + * @private + */ + _renderReadonly: function () { + if (_.str.startsWith(this.value, 'http')) { + var self = this; + this.$('.oe_pad_content') + .addClass('oe_pad_loading') + .text(_t("Loading")); + this._rpc({ + method: 'pad_get_content', + model: this.model, + args: [this.value] + }, { + shadow: true + }).then(function (data) { + self.$('.oe_pad_content') + .removeClass('oe_pad_loading') + .html('<div class="oe_pad_readonly"><div>'); + self.$('.oe_pad_readonly').html(data); + }).guardedCatch(function () { + self.$('.oe_pad_content').text(_t('Unable to load pad')); + }); + } else { + this.$('.oe_pad_content') + .addClass('oe_pad_loading') + .show() + .text(_t("This pad will be initialized on first edit")); + } + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @override + * @private + */ + _onToggleFullScreen: function () { + this.$el.toggleClass('oe_pad_fullscreen mb0'); + this.$('.oe_pad_switch').toggleClass('fa-expand fa-compress'); + this.$el.parents('.o_touch_device').toggleClass('o_scroll_hidden'); + }, +}); + +fieldRegistry.add('pad', FieldPad); + +return FieldPad; + +}); diff --git a/addons/pad/static/src/xml/pad.xml b/addons/pad/static/src/xml/pad.xml new file mode 100644 index 00000000..44eb11c8 --- /dev/null +++ b/addons/pad/static/src/xml/pad.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="FieldPad"> + <div class="oe_form_field_text oe_pad"> + <p class="oe_unconfigured d-none"> + Please, enter your Etherpad credentials through the Settings. + </p> + <t t-if="widget.mode === 'readonly'"> + <div class="oe_pad_content etherpad_readonly oe_configured" /> + </t> + <t t-if="widget.mode === 'edit'"> + <div class="oe_pad_switch_positioner oe_configured"> + <span class="fa fa-expand oe_pad_switch" role="img" aria-label="Switch pad" title="Switch pad"/> + </div> + <div class="oe_pad_content oe_editing oe_configured" /> + </t> + </div> + </t> + +</templates> |
