diff options
Diffstat (limited to 'addons/base_setup/static/src')
| -rw-r--r-- | addons/base_setup/static/src/img/app_store.png | bin | 0 -> 14016 bytes | |||
| -rw-r--r-- | addons/base_setup/static/src/img/google_play.png | bin | 0 -> 16858 bytes | |||
| -rw-r--r-- | addons/base_setup/static/src/js/res_config_dev_tool.js | 49 | ||||
| -rw-r--r-- | addons/base_setup/static/src/js/res_config_edition.js | 26 | ||||
| -rw-r--r-- | addons/base_setup/static/src/js/res_config_invite_users.js | 203 | ||||
| -rw-r--r-- | addons/base_setup/static/src/scss/settings.scss | 17 | ||||
| -rw-r--r-- | addons/base_setup/static/src/xml/res_config_dev_tool.xml | 19 | ||||
| -rw-r--r-- | addons/base_setup/static/src/xml/res_config_edition.xml | 24 | ||||
| -rw-r--r-- | addons/base_setup/static/src/xml/res_config_invite_users.xml | 21 |
9 files changed, 359 insertions, 0 deletions
diff --git a/addons/base_setup/static/src/img/app_store.png b/addons/base_setup/static/src/img/app_store.png Binary files differnew file mode 100644 index 00000000..65320714 --- /dev/null +++ b/addons/base_setup/static/src/img/app_store.png diff --git a/addons/base_setup/static/src/img/google_play.png b/addons/base_setup/static/src/img/google_play.png Binary files differnew file mode 100644 index 00000000..229d939d --- /dev/null +++ b/addons/base_setup/static/src/img/google_play.png diff --git a/addons/base_setup/static/src/js/res_config_dev_tool.js b/addons/base_setup/static/src/js/res_config_dev_tool.js new file mode 100644 index 00000000..7638d4f0 --- /dev/null +++ b/addons/base_setup/static/src/js/res_config_dev_tool.js @@ -0,0 +1,49 @@ +odoo.define('base_setup.ResConfigDevTool', function (require) { + "use strict"; + + var config = require('web.config'); + var Widget = require('web.Widget'); + var widget_registry = require('web.widget_registry'); + + var ResConfigDevTool = Widget.extend({ + template: 'res_config_dev_tool', + events: { + 'click .o_web_settings_force_demo': '_onClickForceDemo', + }, + + init: function () { + this._super.apply(this, arguments); + this.isDebug = config.isDebug(); + this.isAssets = config.isDebug("assets"); + this.isTests = config.isDebug("tests"); + }, + + willStart: function () { + var self = this; + return this._super.apply(this, arguments).then(function () { + return self._rpc({ + route: '/base_setup/demo_active', + }).then(function (demo_active) { + self.demo_active = demo_active; + }); + }); + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * Forces demo data to be installed in a database without demo data installed. + * + * @private + * @param {MouseEvent} ev + */ + _onClickForceDemo: function (ev) { + ev.preventDefault(); + this.do_action('base.demo_force_install_action'); + }, + }); + + widget_registry.add('res_config_dev_tool', ResConfigDevTool); +}); diff --git a/addons/base_setup/static/src/js/res_config_edition.js b/addons/base_setup/static/src/js/res_config_edition.js new file mode 100644 index 00000000..d8abae43 --- /dev/null +++ b/addons/base_setup/static/src/js/res_config_edition.js @@ -0,0 +1,26 @@ +odoo.define('base_setup.ResConfigEdition', function (require) { + "use strict"; + + var Widget = require('web.Widget'); + var widget_registry = require('web.widget_registry'); + var session = require ('web.session'); + + var ResConfigEdition = Widget.extend({ + template: 'res_config_edition', + + /** + * @override + */ + init: function () { + this._super.apply(this, arguments); + this.server_version = session.server_version; + this.expiration_date = session.expiration_date + ? moment(session.expiration_date) + : moment().add(30, 'd'); + }, + }); + + widget_registry.add('res_config_edition', ResConfigEdition); + + return ResConfigEdition; +}); diff --git a/addons/base_setup/static/src/js/res_config_invite_users.js b/addons/base_setup/static/src/js/res_config_invite_users.js new file mode 100644 index 00000000..9da1350d --- /dev/null +++ b/addons/base_setup/static/src/js/res_config_invite_users.js @@ -0,0 +1,203 @@ +odoo.define('base_setup.ResConfigInviteUsers', function (require) { + "use strict"; + + var Widget = require('web.Widget'); + var widget_registry = require('web.widget_registry'); + var core = require('web.core'); + + var _t = core._t; + + var ResConfigInviteUsers = Widget.extend({ + template: 'res_config_invite_users', + + events: { + 'click .o_web_settings_invite': '_onClickInvite', + 'click .o_web_settings_user': '_onClickUser', + 'click .o_web_settings_more': '_onClickMore', + 'keydown .o_user_emails': '_onKeydownUserEmails', + }, + + /** + * @override + */ + init: function () { + this._super.apply(this, arguments); + this.emails = []; + }, + + willStart: function () { + var self = this; + + return this._super.apply(this, arguments).then(function () { + return self.load(); + }); + }, + + load: function () { + var self = this; + + return this._rpc({ + route: '/base_setup/data', + }).then(function (data) { + self.active_users = data.active_users; + self.pending_users = data.pending_users; + self.pending_count = data.pending_count; + self.resend_invitation = data.resend_invitation || false; + }); + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @private + * @param {string} email + * @returns {boolean} true if the given email address is valid + */ + _validateEmail: function (email) { + var re = /^([a-z0-9][-a-z0-9_\+\.]*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,63}(?:\.[a-z]{2})?)$/i; + return re.test(email); + }, + + /** + * Send invitation for valid and unique email addresses + * + * @private + */ + _invite: function () { + var self = this; + + var $userEmails = this.$('.o_user_emails'); + $userEmails.prop('disabled', true); + this.$('.o_web_settings_invite').prop('disabled', true); + var value = $userEmails.val().trim(); + if (value) { + // filter out duplicates + var emails = _.uniq(value.split(/[ ,;\n]+/)); + + // filter out invalid email addresses + var invalidEmails = _.reject(emails, this._validateEmail); + if (invalidEmails.length) { + this.do_warn(false, _.str.sprintf( + _t('Invalid email addresses: %s.'), + invalidEmails.join(', ') + )); + } + emails = _.difference(emails, invalidEmails); + + if (!this.resend_invitation) { + // filter out already processed or pending addresses + var pendingEmails = _.map(this.pending_users, function (info) { + return info[1]; + }); + var existingEmails = _.intersection(emails, this.emails.concat(pendingEmails)); + if (existingEmails.length) { + this.do_warn(false, _.str.sprintf( + _t('Email addresses already existing: %s.'), + existingEmails.join(', ') + )); + } + emails = _.difference(emails, existingEmails); + } + + if (emails.length) { + $userEmails.val(''); + this._rpc({ + model: 'res.users', + method: 'web_create_users', + args: [emails], + }).then(function () { + return self.load().then(function () { + self.renderElement(); + self.$('.o_user_emails').focus(); + }); + }); + } else { + $userEmails.prop('disabled', false); + this.$('.o_web_settings_invite').prop('disabled', false); + self.$('.o_user_emails').focus(); + } + } + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @private + * @param {MouseEvent} ev + */ + _onClickInvite: function (ev) { + if (this.$('.o_user_emails').val().length) { + var $button = $(ev.target); + $button.button('loading'); + return this._invite(); + } + }, + /** + * @private + * @param {MouseEvent} ev + */ + _onClickMore: function (ev) { + var self = this; + ev.preventDefault(); + this._rpc({ + model: 'ir.model.data', + method: 'xmlid_to_res_model_res_id', + args: ["base.view_users_form"], + }) + .then(function (data) { + self.do_action({ + name: _t('Users'), + type: 'ir.actions.act_window', + view_mode: 'tree,form', + res_model: 'res.users', + domain: [['log_ids', '=', false]], + context: { + search_default_no_share: true, + }, + views: [[false, 'list'], [data[1], 'form']], + }); + }); + }, + /** + * @private + * @param {MouseEvent} ev + */ + _onClickUser: function (ev) { + var self = this; + ev.preventDefault(); + var user_id = $(ev.currentTarget).data('user-id'); + this._rpc({ + model: 'ir.model.data', + method: 'xmlid_to_res_model_res_id', + args: ["base.view_users_form"], + }) + .then(function (data) { + self.do_action({ + type: 'ir.actions.act_window', + res_model: 'res.users', + view_mode: 'form', + res_id: user_id, + views: [[data[1], 'form']], + }); + }); + }, + /** + * @private + * @param {KeyboardEvent} ev + */ + _onKeydownUserEmails: function (ev) { + var keyCodes = [$.ui.keyCode.TAB, $.ui.keyCode.COMMA, $.ui.keyCode.ENTER]; + if (_.contains(keyCodes, ev.which)) { + ev.preventDefault(); + this._invite(); + } + }, + }); + + widget_registry.add('res_config_invite_users', ResConfigInviteUsers); + +}); diff --git a/addons/base_setup/static/src/scss/settings.scss b/addons/base_setup/static/src/scss/settings.scss new file mode 100644 index 00000000..62dc5fe8 --- /dev/null +++ b/addons/base_setup/static/src/scss/settings.scss @@ -0,0 +1,17 @@ +.o_setting_container { + .o_web_settings_user { + font-size: 95%; + font-weight: 500; + } +} + +.o_doc_link { + text-decoration: none; + font-weight: normal; + + &::after{ + content: "\f059"; //fa-question-circle + font-family: 'FontAwesome'; + font-size: 1.2rem; + } +}
\ No newline at end of file diff --git a/addons/base_setup/static/src/xml/res_config_dev_tool.xml b/addons/base_setup/static/src/xml/res_config_dev_tool.xml new file mode 100644 index 00000000..af44a231 --- /dev/null +++ b/addons/base_setup/static/src/xml/res_config_dev_tool.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<template> + <div t-name='res_config_dev_tool'> + <div id="developer_tool"> + <h2>Developer Tools</h2> + <div class="row mt16 o_settings_container"> + <div class="col-12 col-lg-6 o_setting_box" id="devel_tool"> + <div class="o_setting_right_pane"> + <a t-if="!widget.isDebug" class="d-block" href="?debug=1">Activate the developer mode</a> + <a t-if="!widget.isAssets" class="d-block" href="?debug=assets">Activate the developer mode (with assets)</a> + <a t-if="!widget.isTests" class="d-block" href="?debug=assets,tests">Activate the developer mode (with tests assets)</a> + <a t-if="widget.isDebug" class="d-block" href="?debug=">Deactivate the developer mode</a> + <a t-if="widget.isDebug and !widget.demo_active" class="o_web_settings_force_demo" href="#">Load demo data</a> + </div> + </div> + </div> + </div> + </div> +</template> diff --git a/addons/base_setup/static/src/xml/res_config_edition.xml b/addons/base_setup/static/src/xml/res_config_edition.xml new file mode 100644 index 00000000..3555ebfd --- /dev/null +++ b/addons/base_setup/static/src/xml/res_config_edition.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- TODO See if this has to be editable in some way, see if it is easy for someone to change this --> +<!-- TODO Also see what is done to override the (Community Edition) --> +<template> + <div t-name='res_config_edition'> + <div class="col-12 o_setting_box" id="edition"> + <div class="o_setting_right_pane"> + <div class="user-heading"> + <h3> + Odoo <t t-esc="widget.server_version"/> + (Community Edition) + </h3> + </div> + <div> + <div class="tab-content"> + <div role="tabpanel" id="settings" class="tab-pane active text-muted o_web_settings_compact_subtitle"> + <small>Copyright © 2004 <a target="_blank" href="https://www.odoo.com" style="text-decoration: underline;">Odoo S.A.</a> <a id="license" target="_blank" href="http://www.gnu.org/licenses/lgpl.html" style="text-decoration: underline;">GNU LGPL Licensed</a></small> + </div> + </div> + </div> + </div> + </div> + </div> +</template> diff --git a/addons/base_setup/static/src/xml/res_config_invite_users.xml b/addons/base_setup/static/src/xml/res_config_invite_users.xml new file mode 100644 index 00000000..cfb67afd --- /dev/null +++ b/addons/base_setup/static/src/xml/res_config_invite_users.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<templates> + <div t-name='res_config_invite_users'> + <p class="o_form_label">Invite New Users</p> + <div class="d-flex"> + <input class="o_user_emails o_input mt8" type="text" placeholder="Enter e-mail address"/> + <button class="btn btn-primary o_web_settings_invite" data-loading-text="Inviting..."><strong>Invite</strong></button> + </div> + + <t t-if="widget.pending_users.length"> + <p class="o_form_label pt-3">Pending Invitations:</p> + <span t-foreach="widget.pending_users" t-as="pending"> + <a href="#" class="badge badge-pill o_web_settings_user" t-att-data-user-id="pending[0]"> <t t-esc="pending[1]"/> </a> + </span> + <t t-if="widget.pending_users.length < widget.pending_count"> + <br/> + <a href="#" class="o_web_settings_more"><t t-esc="widget.pending_count - widget.pending_users.length"/> more </a> + </t> + </t> + </div> +</templates> |
