diff options
| author | aca <aca@odoo.com> | 2019-06-19 09:14:43 +0000 |
|---|---|---|
| committer | Yannick Tivisse <yti@odoo.com> | 2019-07-26 09:53:46 +0000 |
| commit | 78565b1dc933692abba46a73f2298b7ea8e03c88 (patch) | |
| tree | 05006de48a2099a35c39dc5571d4929ab0135a3b /addons/base_setup/static/src | |
| parent | a8893ad2994aad05961bdddcecb3e2c55f301ed5 (diff) | |
[REM] web_settings_dashboard: Merge module into base_setup
Purpose
=======
Currently, when we click on “Settings” on the Home Dashboard, we arrive
on a new Dashboard with several pieces of information like Installed Apps,
invite new users, or translations. Some informations are reachable in
several ways, which is not necessary.
We would like to remove this page and replace it with the General Settings
page directly. That makes more sense to the user who click on “Settings”. The
present informations will be dispatched in the menu or in the general settings
for a better usability.
Specification
=============
This commit move code from web_settings_dashboard in order to put the features
in settings directly. To do so, we choose to move code to base_setup, and create
widget on the settings form view to keep features. Concerned features are: invite
users, dev tools, odoo edition number and IAP account link.
TaskID: 2006910
closes odoo/odoo#34290
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
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 | 31 | ||||
| -rw-r--r-- | addons/base_setup/static/src/js/res_config_edition.js | 21 | ||||
| -rw-r--r-- | addons/base_setup/static/src/js/res_config_invite_users.js | 214 | ||||
| -rw-r--r-- | addons/base_setup/static/src/scss/settings.scss | 67 | ||||
| -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 | 54 |
9 files changed, 430 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 00000000000..65320714c06 --- /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 00000000000..229d939d728 --- /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 00000000000..b407a731a35 --- /dev/null +++ b/addons/base_setup/static/src/js/res_config_dev_tool.js @@ -0,0 +1,31 @@ +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', + + 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; + }); + }); + }, + }); + + 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 00000000000..bdc3f434f88 --- /dev/null +++ b/addons/base_setup/static/src/js/res_config_edition.js @@ -0,0 +1,21 @@ +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; + }, + }); + + widget_registry.add('res_config_edition', 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 00000000000..653a130868c --- /dev/null +++ b/addons/base_setup/static/src/js/res_config_invite_users.js @@ -0,0 +1,214 @@ +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 framework = require('web.framework'); + + var QWeb = core.qweb; + var _t = core._t; + + var ResConfigInviteUsers = Widget.extend({ + template: 'res_config_invite_users', + + events: { + 'click .o_web_settings_invite': '_onClickInvite', + 'click .o_web_settings_access_rights': '_onClickAccessRights', + 'click .o_web_settings_user': '_onClickUser', + 'click .o_web_settings_more': '_onClickMore', + 'click .o_badge_remove': '_onClickBadgeRemove', + '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 + //-------------------------------------------------------------------------- + + /** + * Creates and appends badges for valid and unique email addresses + * + * @private + */ + _createBadges: function () { + var $userEmails = this.$('.o_user_emails'); + 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(_.str.sprintf(_t('The following email addresses are invalid: %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(_.str.sprintf(_t('The following email addresses already exist: %s.'), existingEmails.join(', '))); + } + emails = _.difference(emails, existingEmails); + } + + // add valid email addresses, if any + if (emails.length) { + this.emails = this.emails.concat(emails); + this.$('.o_web_settings_invitation_form').append(QWeb.render('EmailBadge', {emails: emails})); + $userEmails.val(''); + } + } + }, + /** + * Removes a given badge from the DOM, and its associated email address + * + * @private + * @param {jQueryElement} $badge + */ + _removeBadge: function ($badge) { + var email = $badge.text().trim(); + this.emails = _.without(this.emails, email); + $badge.remove(); + }, + /** + * @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); + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @private + * @param {MouseEvent} ev + */ + _onClickAccessRights: function (e) { + e.preventDefault(); + this.do_action('base.action_res_users'); + }, + /** + * @private + * @param {MouseEvent} ev + */ + _onClickBadgeRemove: function (ev) { + var $badge = $(ev.target).closest('.badge'); + this._removeBadge($badge); + }, + /** + * @private + * @param {MouseEvent} ev + */ + _onClickInvite: function (ev) { + var self = this; + this._createBadges(); + if (this.emails.length) { + var $button = $(ev.target); + $button.button('loading'); + this._rpc({ + model: 'res.users', + method: 'web_create_users', + args: [this.emails], + }).then(function () { + return self.load().then(function () { + self.renderElement(); + }); + }).guardedCatch(function () { + // NOTE Not sure that this is needed + $button.button('reset'); + }); + } + }, + /** + * @private + * @param {MouseEvent} ev + */ + _onClickMore: function(ev) { + ev.preventDefault(); + this.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'], [false, 'form']], + }); + }, + /** + * @private + * @param {MouseEvent} ev + */ + _onClickUser: function (ev) { + ev.preventDefault(); + var user_id = $(e.currentTarget).data('user-id'); + this.do_action({ + type: 'ir.actions.act_window', + res_model: 'res.users', + view_mode: 'form', + views: [[false, 'form']], + res_id: user_id, + }); + }, + /** + * @private + * @param {KeyboardEvent} ev + */ + _onKeydownUserEmails: function (ev) { + var $userEmails = this.$('.o_user_emails'); + var keyCodes = [$.ui.keyCode.TAB, $.ui.keyCode.COMMA, $.ui.keyCode.ENTER, $.ui.keyCode.SPACE]; + if (_.contains(keyCodes, ev.which)) { + ev.preventDefault(); + this._createBadges(); + } + // remove last badge on backspace + if (ev.which === $.ui.keyCode.BACKSPACE && this.emails.length && !$userEmails.val()) { + this._removeBadge(this.$('.o_web_settings_invitation_form .badge:last')); + } + }, + }); + + 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 00000000000..2f385a3ad10 --- /dev/null +++ b/addons/base_setup/static/src/scss/settings.scss @@ -0,0 +1,67 @@ +.o_web_settings { + + $bg-dashboard-col: #FFF; + + @mixin o-web-settings-card-card { + box-shadow: 0 1px 2px 0 rgba(0,0,0,.14); + background: $bg-dashboard-col; + border-radius: 2px; + } + + background: #F7F7F7; + height: 100%; + + .o_web_settings_col { + > div > hr { + margin: 12px -18px 15px -18px; + border-color: #CBCBCB; + } + + > div { + @include o-web-settings-card-card; + padding: 25px 18px 18px 18px; + + .o_web_settings_header { + font-size: 22px; + margin-bottom: 8px; + } + } + .btn.o_browse_apps, .btn.o_web_settings_invitations { + margin-top: 12px; + } + .o_web_settings_compact_subtitle { + line-height: 12px; + display: block; + } + .o_web_settings_invitations { + .o_web_settings_invitation_form { + text-align: left; + > textarea { + resize: vertical; + width: 100%; + } + } + } + .o_web_settings_planner { + .progress { + height: 10px; + background-color: darken($bg-dashboard-col, 15%); + cursor: pointer; + margin-bottom: 30px; + } + .o_web_settings_planner_progress_text { + font-size: 18px; + padding-right: 0px; + padding-top: 3px; + } + .o_web_settings_planner_progress_bar { + padding-left: 10px; + } + .o_web_settings_progress_title { + font-weight: bold; + cursor: pointer; + color: $o-brand-primary; + } + } + } +} 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 00000000000..ab108bd2518 --- /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 && !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 00000000000..31485c33ab9 --- /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 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 00000000000..ba9bd5fbc7e --- /dev/null +++ b/addons/base_setup/static/src/xml/res_config_invite_users.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="utf-8"?> +<templates> + <div t-name='res_config_invite_users'> + <div class="row mt16 o_settings_container"> + <div class='col-12 col-lg-6 o_setting_box'> + <div class='o_setting_right_pane'> + <t t-if="widget.active_users"> + <div class='o_form_label'> + <t t-esc="widget.active_users"></t> + <t t-if="widget.active_users <= 1"> Active User</t> + <t t-if="widget.active_users > 1">Active Users</t> + </div> + </t> + <br/> + <a href="#" class="o_web_settings_access_rights d-flex"> + <i class='fa fa-fw o_button_icon fa-arrow-right'></i> + Manage Users + </a> + </div> + </div> + <div class="col-12 col-lg-6 o_setting_box"> + <div class="o_setting_right_pane"> + <t t-if="widget.pending_users.length"> + <p class="o_form_label">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> + </div> + <div class='col-12 col-lg-6 o_setting_box'> + <div class='o_setting_right_pane'> + <span class="o_form_label">Invite New Users:</span> + <span class="o_web_settings_invitation_form"/> + <input class="o_user_emails o_input mt8" type="text" placeholder="Enter e-mail addresses"/> + <button class="btn btn-primary btn-block o_web_settings_invite mt16" data-loading-text="Inviting..."><strong>Invite</strong></button> + </div> + </div> + </div> + </div> + + <t t-name="EmailBadge"> + <span t-foreach="emails" t-as="email" class="badge badge-pill"> + <span class="o_badge_text"> + <t t-esc='email'/> + </span> + <a href="#" class="fa fa-times o_badge_remove" title="Remove Email" aria-label="Remove Email" role="button"/> + </span> + </t> +</templates> |
