diff options
| author | qsm-odoo <qsm@odoo.com> | 2018-03-14 16:21:14 +0100 |
|---|---|---|
| committer | qsm-odoo <qsm@odoo.com> | 2018-07-27 12:36:54 +0200 |
| commit | 1c1c0897e8eca607c7f1b96b68a06c026c543e6a (patch) | |
| tree | 1f667224be28146cbcbe602892094046052ea93b /addons | |
| parent | 220e49f9d66f2e2ea875143c2da0c20919ec0b3e (diff) | |
[REF] *: BS4, adapt dropdowns and carets
- The dropdown structure was simplified, allowing to get rid of the
3-levels structure induced by <ul/> elements and dropdowns can now
contain anything. The class 'dropdown-item' is now mandatory for
each dropdown clickable element. The class 'dropdown-item-text' can
be used to add same padding and style but without making the element
have a clickable look.
- Dividers now use the class 'dropdown-divider'
- The way dropdowns are opened and hidden also changed (before the
'open' class was added on the `.dropdown-menu` parent, now the
'show' class is added on both the `.dropdown-menu` parent and the
`.dropdown-menu` itself).
- JS-wise, no click event handlers can be put on `.dropdown-toggle`
elements anymore (instead, use handlers for dropdown events).
- Carets are automatically put on `.dropdown-toggle` elements, so this
commit replaces the `.caret` elements with this. This feature was
possible to disable but would prevent us from adding a caret with
scss. Also, this simplifies the DOM. The 'o-no-caret' class was also
introduced to allow using the 'dropdown-toggle' class on non-caret
elements.
- Also adapt the scss to use $caret-width instead of $caret-width-base
Diffstat (limited to 'addons')
107 files changed, 1181 insertions, 1279 deletions
diff --git a/addons/account/static/src/xml/account_reconciliation.xml b/addons/account/static/src/xml/account_reconciliation.xml index 1c0d535e5bc..44986549a92 100644 --- a/addons/account/static/src/xml/account_reconciliation.xml +++ b/addons/account/static/src/xml/account_reconciliation.xml @@ -164,10 +164,10 @@ </div> <div class="dropdown pull-right"> <a data-toggle="dropdown" href="#"><span class="fa fa-cog" role="img" aria-label="Settings"/></a> - <ul class="dropdown-menu dropdown-menu-right" role="menu" aria-label="Presets config"> - <li><a role="menuitem" class="reconcile_model_create" href="#">Create model</a></li> - <li><a role="menuitem" class="reconcile_model_edit" href="#">Modify models</a></li> - </ul> + <div class="dropdown-menu dropdown-menu-right" role="menu" aria-label="Presets config"> + <a role="menuitem" class="dropdown-item reconcile_model_create" href="#">Create model</a> + <a role="menuitem" class="dropdown-item reconcile_model_edit" href="#">Modify models</a> + </div> </div> </div> <table class="pull-left"> @@ -218,8 +218,8 @@ <td class="cell_label"> <t t-if="line.partner_id && line.partner_id !== state.st_line.partner_id"> <t t-if="line.partner_name.length"> - <t t-esc="line.partner_name"/>: - </t> + <t t-esc="line.partner_name"/>: + </t> </t> <t t-esc="line.label || line.name"/> <t t-if="line.ref && line.ref.length"> : </t> diff --git a/addons/board/static/src/scss/dashboard.scss b/addons/board/static/src/scss/dashboard.scss index 67f3d818b76..683bdf52eaf 100644 --- a/addons/board/static/src/scss/dashboard.scss +++ b/addons/board/static/src/scss/dashboard.scss @@ -148,5 +148,5 @@ // Favorites menu in control panel .o_add_to_dashboard { display: none; // hidden by default - @include o-search-options-dropdown-custom-li; + @include o-search-options-dropdown-custom-item; } diff --git a/addons/board/static/src/xml/board.xml b/addons/board/static/src/xml/board.xml index 00e94d73162..cb907290fd1 100644 --- a/addons/board/static/src/xml/board.xml +++ b/addons/board/static/src/xml/board.xml @@ -75,14 +75,12 @@ </t> <t t-name="SearchView.addtodashboard"> - <li class="o_add_to_dashboard_link o_closed_menu"> - <a href="#">Add to my Dashboard</a> - </li> - <li class="o_add_to_dashboard"> - <input class="o_add_to_dashboard_input" type="text"/> - </li> - <li class="o_add_to_dashboard"> + <a href="#" class="dropdown-item o_add_to_dashboard_link o_closed_menu">Add to my Dashboard</a> + <div class="dropdown-item-text o_add_to_dashboard"> + <input class="o_input o_add_to_dashboard_input" type="text"/> + </div> + <div class="dropdown-item-text o_add_to_dashboard"> <button type="button" class="btn btn-primary o_add_to_dashboard_button">Add</button> - </li> + </div> </t> </template> diff --git a/addons/crm/views/crm_lead_views.xml b/addons/crm/views/crm_lead_views.xml index dbf50c5d896..d72c2fd29c8 100644 --- a/addons/crm/views/crm_lead_views.xml +++ b/addons/crm/views/crm_lead_views.xml @@ -324,16 +324,16 @@ <div t-attf-class="#{kanban_color(record.color.raw_value)} oe_kanban_global_click"> <div class="o_dropdown_kanban dropdown"> - <a class="dropdown-toggle btn" role="button" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> + <a class="dropdown-toggle o-no-caret btn" role="button" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> <span class="fa fa-ellipsis-v"/> </a> - <ul class="dropdown-menu" role="menu"> - <t t-if="widget.editable"><li><a role="menuitem" type="edit">Edit</a></li></t> - <t t-if="widget.deletable"><li><a role="menuitem" type="delete">Delete</a></li></t> - <li t-if="! record.active.value"><a role="menuitem" name="action_set_active" type="object">Restore</a></li> - <li t-if="record.active.value"><a role="menuitem" name="action_set_unactive" type="object">Archive</a></li> - <li role="menuitem" aria-haspopup="true"><ul class="oe_kanban_colorpicker" data-field="color" role="menu"/></li> - </ul> + <div class="dropdown-menu" role="menu"> + <t t-if="widget.editable"><a role="menuitem" type="edit" class="dropdown-item">Edit</a></t> + <t t-if="widget.deletable"><a role="menuitem" type="delete" class="dropdown-item">Delete</a></t> + <a t-if="! record.active.value" role="menuitem" name="action_set_active" type="object" class="dropdown-item">Restore</a> + <a t-if="record.active.value" role="menuitem" name="action_set_unactive" type="object" class="dropdown-item">Archive</a> + <ul class="oe_kanban_colorpicker" data-field="color"/> + </div> </div> <div class="oe_kanban_content"> <div> diff --git a/addons/event/views/event_views.xml b/addons/event/views/event_views.xml index 87c51f7f92f..ebdc52397c5 100644 --- a/addons/event/views/event_views.xml +++ b/addons/event/views/event_views.xml @@ -238,7 +238,7 @@ <div> <field name="seats_availability" widget='radio'/> <span attrs="{'invisible': [('seats_availability', '=', 'unlimited')]}" class="oe_read_only"> - to + to </span> <field name="seats_max" attrs="{'invisible': [('seats_availability', '=', 'unlimited')], 'required': [('seats_availability', '=', 'limited')]}"/> </div> @@ -305,15 +305,15 @@ <div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click"> <div class="o_dropdown_kanban dropdown"> - <a class="dropdown-toggle btn" role="button" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> + <a class="dropdown-toggle o-no-caret btn" role="button" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> <span class="fa fa-ellipsis-v"/> </a> - <ul class="dropdown-menu" role="menu"> + <div class="dropdown-menu" role="menu"> <t t-if="widget.deletable"> - <li><a role="menuitem" type="delete">Delete</a></li> + <a role="menuitem" type="delete" class="dropdown-item">Delete</a> </t> - <li role="menuitem" aria-haspopup="true"><ul class="oe_kanban_colorpicker" data-field="color" role="menu"/></li> - </ul> + <ul class="oe_kanban_colorpicker" data-field="color" role="menu"/> + </div> </div> <div class="o_event_left"> <div class="o_day"><t t-esc="record.date_begin.raw_value.getDate()"/></div> diff --git a/addons/google_drive/static/tests/gdrive_test.js b/addons/google_drive/static/tests/gdrive_test.js index edf6a0c4ca2..78fac5f39b6 100644 --- a/addons/google_drive/static/tests/gdrive_test.js +++ b/addons/google_drive/static/tests/gdrive_test.js @@ -94,16 +94,16 @@ QUnit.module('gdrive_integration', { return $.when(); } return this._super.apply(this, arguments); - } + }, }); - var google_action = form.sidebar.$('.oe_share_gdoc'); + var $googleAction = form.sidebar.$('.oe_share_gdoc'); - assert.strictEqual(google_action.length, 1, + assert.strictEqual($googleAction.length, 1, 'The button to the google action should be present'); // Trigger opening of the dynamic link - google_action.find('a:first').click(); + $googleAction.click(); form.destroy(); }); diff --git a/addons/hr_contract/views/hr_contract_views.xml b/addons/hr_contract/views/hr_contract_views.xml index ef1cfad0f33..9e5b234c956 100644 --- a/addons/hr_contract/views/hr_contract_views.xml +++ b/addons/hr_contract/views/hr_contract_views.xml @@ -175,13 +175,13 @@ <t t-name="kanban-box"> <div class="oe_kanban_card oe_kanban_global_click"> <div class="o_dropdown_kanban dropdown" groups="base.group_user"> - <a class="dropdown-toggle btn" role="button" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> + <a class="dropdown-toggle o-no-caret btn" role="button" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> <span class="fa fa-ellipsis-v"/> </a> - <ul class="dropdown-menu" role="menu"> - <t t-if="widget.editable"><li><a role="menuitem" type="edit">Edit Contract</a></li></t> - <t t-if="widget.deletable"><li><a role="menuitem" type="delete">Delete</a></li></t> - </ul> + <div class="dropdown-menu" role="menu"> + <t t-if="widget.editable"><a role="menuitem" type="edit" class="dropdown-item">Edit Contract</a></t> + <t t-if="widget.deletable"><a role="menuitem" type="delete" class="dropdown-item">Delete</a></t> + </div> </div> <div class="oe_kanban_content"> <div> diff --git a/addons/hr_recruitment/views/hr_recruitment_views.xml b/addons/hr_recruitment/views/hr_recruitment_views.xml index 2569e5a59a4..10b4ddd7b33 100644 --- a/addons/hr_recruitment/views/hr_recruitment_views.xml +++ b/addons/hr_recruitment/views/hr_recruitment_views.xml @@ -290,14 +290,14 @@ <div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click oe_applicant_kanban oe_semantic_html_override"> <div class="o_dropdown_kanban dropdown"> - <a class="dropdown-toggle btn" role="button" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> + <a class="dropdown-toggle o-no-caret btn" role="button" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> <span class="fa fa-ellipsis-v"/> </a> - <ul class="dropdown-menu" role="menu"> - <t t-if="widget.deletable"><li><a role="menuitem" type="delete">Delete</a></li></t> - <li><a role="menuitem" name="action_makeMeeting" type="object">Schedule Interview</a></li> - <li role="menuitem" aira-haspopup="true"><ul role="menu" class="oe_kanban_colorpicker" data-field="color"/></li> - </ul> + <div class="dropdown-menu" role="menu"> + <t t-if="widget.deletable"><a role="menuitem" type="delete" class="dropdown-item">Delete</a></t> + <a role="menuitem" name="action_makeMeeting" type="object" class="dropdown-item">Schedule Interview</a> + <ul class="oe_kanban_colorpicker" data-field="color"/> + </div> </div> <div class="oe_kanban_content"> <div class="o_kanban_record_top"> @@ -340,7 +340,7 @@ </div> <img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)" t-att-title="record.user_id.value" t-att-alt="record.user_id.value" width="30" height="30" class="oe_kanban_avatar"/> </div> - + </div> </div> <div class="oe_clear"></div> @@ -971,7 +971,7 @@ (0, 0, {'view_mode': 'graph', 'view_id': ref('hr_applicant_view_graph')})]"/> <field name="context">{}</field> <!-- force empty --> </record> - <menuitem name="Reports" id="report_hr_recruitment" parent="menu_hr_recruitment_root" + <menuitem name="Reports" id="report_hr_recruitment" parent="menu_hr_recruitment_root" sequence="99" action="hr_applicant_action_analysis"/> <record id="action_hr_recruitment_report_filtered_department" model="ir.actions.act_window"> <field name="name">Recruitment Analysis</field> diff --git a/addons/im_support/static/src/xml/systray.xml b/addons/im_support/static/src/xml/systray.xml index eb182a04ff4..1cb14637b36 100644 --- a/addons/im_support/static/src/xml/systray.xml +++ b/addons/im_support/static/src/xml/systray.xml @@ -3,10 +3,10 @@ <t t-extend="mail.systray.MessagingMenu"> <t t-jquery=".o_mail_systray_dropdown" t-operation="append"> - <li t-if="widget.supportChannel" class="o_mail_systray_dropdown_bottom"> + <div t-if="widget.supportChannel" class="o_mail_systray_dropdown_bottom"> <t t-set="preview" t-value="widget.supportChannel"/> <t t-call="mail.Preview"/> - </li> + </div> </t> </t> diff --git a/addons/mail/static/src/js/activity.js b/addons/mail/static/src/js/activity.js index 3a63b1fbd60..c8a3b8dddde 100644 --- a/addons/mail/static/src/js/activity.js +++ b/addons/mail/static/src/js/activity.js @@ -371,7 +371,7 @@ var Activity = AbstractActivityField.extend({ var KanbanActivity = AbstractActivityField.extend({ template: 'mail.KanbanActivity', events: { - 'click .o_activity_btn': '_onButtonClicked', + 'show.bs.dropdown': '_onDropdownShow', 'click .o_schedule_activity': '_onScheduleActivity', 'click .o_mark_as_done': '_onMarkActivityDone', }, @@ -411,7 +411,7 @@ var KanbanActivity = AbstractActivityField.extend({ }).join(' '); }); $span.addClass('o_activity_color_' + (this.activityState || 'default')); - if (this.$el.hasClass('open')) { + if (this.$el.hasClass('show')) { // note: this part of the rendering might be asynchronous this._renderDropdown(); } @@ -455,13 +455,9 @@ var KanbanActivity = AbstractActivityField.extend({ /** * @private - * @param {MouseEvent} ev */ - _onButtonClicked: function (ev) { - ev.preventDefault(); - if (!this.$el.hasClass('open')) { - this._renderDropdown(); - } + _onDropdownShow: function () { + this._renderDropdown(); }, /** * @private diff --git a/addons/mail/static/src/js/composers/mention_manager.js b/addons/mail/static/src/js/composers/mention_manager.js index fb8d9ddc065..62608fbf511 100644 --- a/addons/mail/static/src/js/composers/mention_manager.js +++ b/addons/mail/static/src/js/composers/mention_manager.js @@ -319,15 +319,18 @@ var MentionManager = Widget.extend({ suggestions: suggestions, })); this.$el - .addClass('open') - .find('ul') + .addClass('show') + .find('.dropdown-menu') + .addClass('show') .css('max-width', this._composer.$input.width()) .find('.o_mention_proposition') .first() .addClass('active'); this._open = true; } else { - this.$el.removeClass('open'); + this.$el.removeClass('show') + .find('.dropdown-menu') + .removeClass('show'); this.$el.empty(); this._open = false; } diff --git a/addons/mail/static/src/js/followers.js b/addons/mail/static/src/js/followers.js index a28f72edb1c..42d5519ff40 100644 --- a/addons/mail/static/src/js/followers.js +++ b/addons/mail/static/src/js/followers.js @@ -135,9 +135,9 @@ var Followers = AbstractField.extend({ var old_parent_model; var $list; if (dialog) { - $list = $('<ul>').appendTo(this.dialog.$el); + $list = $('<div>').appendTo(this.dialog.$el); } else { - $list = this.$('.o_subtypes_list ul'); + $list = this.$('.o_subtypes_list .dropdown-menu'); } $list.empty(); @@ -145,7 +145,7 @@ var Followers = AbstractField.extend({ _.each(data, function (record) { if (old_parent_model !== record.parent_model && old_parent_model !== undefined) { - $list.append($('<li>').addClass('divider')); + $list.append($('<div>', {class: 'dropdown-divider'})); } old_parent_model = record.parent_model; record.followed = record.followed || undefined; @@ -408,11 +408,11 @@ var Followers = AbstractField.extend({ ev.stopPropagation(); this._updateSubscription(ev); var $list = this.$('.o_subtypes_list'); - if (!$list.hasClass('open')) { - $list.addClass('open'); + if (!$list.hasClass('show')) { + $list.addClass('show'); } - if (this.$('.o_subtypes_list ul')[0].children.length < 1) { - $list.removeClass('open'); + if (this.$('.o_subtypes_list .dropdown-menu')[0].children.length < 1) { + $list.removeClass('show'); } }, }); diff --git a/addons/mail/static/src/scss/abstract_thread_window.scss b/addons/mail/static/src/scss/abstract_thread_window.scss index 21fc4ebd7ad..39de4fc9c51 100644 --- a/addons/mail/static/src/scss/abstract_thread_window.scss +++ b/addons/mail/static/src/scss/abstract_thread_window.scss @@ -119,7 +119,7 @@ $o-mail-thread-window-zindex: $zindex-modal + 1 !default; font-size: smaller; } } - &.open .o_thread_window_dropdown_toggler .o_total_unread_counter, .o_thread_window_expand { + &.show .o_thread_window_dropdown_toggler .o_total_unread_counter, .o_thread_window_expand { display: none; } diff --git a/addons/mail/static/src/scss/composer.scss b/addons/mail/static/src/scss/composer.scss index 884ca88134e..1eb2de031d5 100644 --- a/addons/mail/static/src/scss/composer.scss +++ b/addons/mail/static/src/scss/composer.scss @@ -45,7 +45,7 @@ width: 100%; resize: none; } - .o_composer_mention_dropdown .o_mention_proposition > a { + .o_composer_mention_dropdown .o_mention_proposition { @include o-text-overflow; width: 100%; padding: 3px 15px; diff --git a/addons/mail/static/src/scss/discuss.scss b/addons/mail/static/src/scss/discuss.scss index 5995cab52e2..2c07068d9a9 100644 --- a/addons/mail/static/src/scss/discuss.scss +++ b/addons/mail/static/src/scss/discuss.scss @@ -401,7 +401,7 @@ @include media-breakpoint-down(sm) { - .o_main_navbar > ul.o_menu_systray > li.open .dropdown-menu { + .o_main_navbar > ul.o_menu_systray > li .dropdown-menu.show { border: none; } diff --git a/addons/mail/static/src/scss/systray.scss b/addons/mail/static/src/scss/systray.scss index 4d774b2824a..d52add73ec4 100644 --- a/addons/mail/static/src/scss/systray.scss +++ b/addons/mail/static/src/scss/systray.scss @@ -15,7 +15,7 @@ display: none; } } - &.open .o_mail_systray_dropdown { + &.show .o_mail_systray_dropdown { display: flex; flex-flow: column nowrap; } diff --git a/addons/mail/static/src/xml/composer.xml b/addons/mail/static/src/xml/composer.xml index 9a373dad533..8ecf3f8a7c6 100644 --- a/addons/mail/static/src/xml/composer.xml +++ b/addons/mail/static/src/xml/composer.xml @@ -47,17 +47,15 @@ @param {boolean} [suggestions.divider=false] --> <t t-name="mail.MentionSuggestions"> - <ul class="dropdown-menu" role="menu"> + <div class="dropdown-menu" role="menu"> <t t-foreach="suggestions" t-as="suggestion"> - <li role="separator" t-if="suggestion.divider" class="divider"/> - <li t-if="!suggestion.divider" class="o_mention_proposition" t-att-data-id="suggestion.id"> - <a role="menuitem" href="#"/> - </li> + <div role="separator" t-if="suggestion.divider" class="dropdown-divider"/> + <a t-else="" href="#" class="dropdown-item o_mention_proposition" t-att-data-id="suggestion.id" role="menuitem"/> </t> - </ul> + </div> </t> <t t-name="mail.MentionSuggestions.Partner" t-extend="mail.MentionSuggestions"> - <t t-jquery=".o_mention_proposition a" t-operation="append"> + <t t-jquery=".o_mention_proposition" t-operation="append"> <span class="o_mention_name"><t t-esc="suggestion.name"/></span> <t t-if="suggestion.email"> <span class="o_mention_info">(<t t-esc="suggestion.email"/>)</span> @@ -65,18 +63,18 @@ </t> </t> <t t-name="mail.MentionSuggestions.Channel" t-extend="mail.MentionSuggestions"> - <t t-jquery=".o_mention_proposition a" t-operation="append"> + <t t-jquery=".o_mention_proposition" t-operation="append"> <span class="o_mention_name"><t t-esc="suggestion.name"/></span> </t> </t> <t t-name="mail.MentionSuggestions.CannedResponse" t-extend="mail.MentionSuggestions"> - <t t-jquery=".o_mention_proposition a" t-operation="append"> + <t t-jquery=".o_mention_proposition" t-operation="append"> <span class="o_mention_name"><t t-esc="suggestion.source"/></span> <span class="o_mention_info"><t t-esc="suggestion.substitution"/></span> </t> </t> <t t-name="mail.MentionSuggestions.Command" t-extend="mail.MentionSuggestions"> - <t t-jquery=".o_mention_proposition a" t-operation="append"> + <t t-jquery=".o_mention_proposition" t-operation="append"> <span class="o_mention_name">/<t t-esc="suggestion.name"/></span> <span class="o_mention_info"><t t-esc="suggestion.help"/></span> </t> diff --git a/addons/mail/static/src/xml/followers.xml b/addons/mail/static/src/xml/followers.xml index a19831308a6..bbf51ca5c68 100644 --- a/addons/mail/static/src/xml/followers.xml +++ b/addons/mail/static/src/xml/followers.xml @@ -12,7 +12,7 @@ <i class="fa fa-user" role="img" aria-label="Dropdown menu - Followers"></i> <span class="o_followers_count"/> </button> - <ul class="dropdown-menu o_followers_list" role="menu"></ul> + <div class="dropdown-menu o_followers_list" role="menu"/> </div> <div class="o_followers_actions"> <div class="btn-group o_subtypes_list"> @@ -25,7 +25,7 @@ </button><button class="btn btn-link dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> <span class="fa fa-bell" role="img" aria-label="Alarm menu" title="Alarm menu"/> </button> - <ul class="dropdown-menu" role="menu"/> + <div class="dropdown-menu" role="menu"/> </div> </div> </div> @@ -59,13 +59,9 @@ --> <t t-name="mail.Followers.add_more"> <t t-if="widget.isEditable"> - <li role="menuitem" class="o_add_follower"> - <a href="#"> Add Followers </a> - </li> - <li role="menuitem" class="o_add_follower_channel"> - <a href="#"> Add Channels </a> - </li> - <li role="separator" t-if="widget.followers.length > 0" class="divider"/> + <a href="#" role="menuitem" class="dropdown-item o_add_follower">Add Followers</a> + <a href="#" role="menuitem" class="dropdown-item o_add_follower_channel">Add Channels</a> + <div role="separator" t-if="widget.followers.length > 0" class="dropdown-divider"/> </t> </t> @@ -73,7 +69,7 @@ Message subtypes of a follower subscription --> <t t-name="mail.Followers.subtype"> - <li role="menuitem" class="o_subtype"> + <div role="menuitem" class="o_subtype dropdown-item"> <div class="o_checkbox"> <input type="checkbox" t-att-checked="record.followed" t-att-id="'input_mail_followers_subtype_'+record.id+(dialog ? '_in_dialog': '')" @@ -84,7 +80,7 @@ <t t-esc="record.name"/> </span> <i t-if="display_warning" class="fa fa-warning text-warning" role="img" aria-label="Warning" title="Warning"/> - </li> + </div> </t> <t t-name="mail.Followers.subtypes.warning"> <span class="text-warning"> diff --git a/addons/mail/static/src/xml/systray.xml b/addons/mail/static/src/xml/systray.xml index 1f0cf850f8c..16fe5c9ef10 100644 --- a/addons/mail/static/src/xml/systray.xml +++ b/addons/mail/static/src/xml/systray.xml @@ -6,25 +6,25 @@ --> <t t-name="mail.systray.MessagingMenu"> <li class="o_mail_systray_item"> - <a class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false" title="Conversations" href="#"> + <a class="dropdown-toggle o-no-caret" data-toggle="dropdown" aria-expanded="false" title="Conversations" href="#"> <i class="fa fa-comments" role="img" aria-label="Messages"/> <span class="o_notification_counter badge"/> </a> - <ul class="o_mail_systray_dropdown dropdown-menu" role="menu"> - <li role="menuitem" t-if="widget.isMobile()"> + <div class="o_mail_systray_dropdown dropdown-menu dropdown-menu-right" role="menu"> + <t t-if="widget.isMobile()"> <div class="o_mail_systray_mobile_header"> <button type="button" class="btn btn-secondary o_new_message"> New message </button> </div> - </li> - <li role="menuitem" t-if="!widget.isMobile()" class="o_mail_systray_dropdown_top"> + </t> + <div t-if="!widget.isMobile()" class="o_mail_systray_dropdown_top"> <div> <button type="button" class="btn btn-link o_filter_button active"> All </button> <button type="button" class="btn btn-link o_filter_button" data-filter='chat'> Chat </button> <button type="button" class="btn btn-link o_filter_button" data-filter='channels'> Channels </button> </div> <button type="button" class="btn btn-link o_new_message"> New message </button> - </li> - <li role="menuitem" class="o_mail_systray_dropdown_items"/> - <li role="menuitem" t-if="widget.isMobile()"> + </div> + <div class="o_mail_systray_dropdown_items"/> + <t t-if="widget.isMobile()"> <div class="o_mail_mobile_tabs"> <div class="o_mail_mobile_tab o_filter_button active"> <span class="fa fa-envelope"/> @@ -39,8 +39,8 @@ <span class="o_tab_title">Channels</span> </div> </div> - </li> - </ul> + </t> + </div> </li> </t> @@ -64,9 +64,9 @@ --> <t t-name="mail.systray.ActivityMenu.Previews"> <t t-if="_.isEmpty(activities)"> - <li class="text-center o_no_activity"> + <div class="dropdown-item-text text-center o_no_activity"> <span>No activities planned.</span> - </li> + </div> </t> <t t-foreach="activities" t-as="activity"> <div class="o_mail_preview" t-att-data-res_model="activity.model" t-att-data-model_name="activity.name" data-filter='my'> @@ -94,12 +94,12 @@ <t t-name="mail.systray.ActivityMenu"> <li class="o_mail_systray_item"> - <a class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false" title="Activities" href="#"> + <a class="dropdown-toggle o-no-caret" data-toggle="dropdown" aria-expanded="false" title="Activities" href="#"> <i class="fa fa-clock-o" role="img" aria-label="Activities"/> <span class="o_notification_counter badge"/> </a> - <ul class="o_mail_systray_dropdown dropdown-menu" role="menu"> - <li role="menuitem" class="o_mail_systray_dropdown_items"/> - </ul> + <div class="o_mail_systray_dropdown dropdown-menu dropdown-menu-right" role="menu"> + <div class="o_mail_systray_dropdown_items"/> + </div> </li> </t> </templates> diff --git a/addons/mail/static/src/xml/web_kanban_activity.xml b/addons/mail/static/src/xml/web_kanban_activity.xml index c3148f13e95..65ece45d865 100644 --- a/addons/mail/static/src/xml/web_kanban_activity.xml +++ b/addons/mail/static/src/xml/web_kanban_activity.xml @@ -3,25 +3,24 @@ <t t-name="mail.KanbanActivity"> <div class="o_kanban_inline_block dropdown o_kanban_selection o_mail_activity"> - <a class="dropdown-toggle o_activity_btn" data-toggle="dropdown"> + <a class="dropdown-toggle o-no-caret o_activity_btn" data-toggle="dropdown"> <span class="fa fa-clock-o fa-lg fa-fw" t-att-title="widget.selection[widget.activityState]" role="img" t-att-aria-label="widget.selection[widget.activity_state]"/> </a> - <ul class="dropdown-menu o_activity" role="menu"> - </ul> + <div class="dropdown-menu o_activity" role="menu"/> </div> </t> <t t-name="mail.KanbanActivityLoading"> - <li class="text-center o_no_activity"> + <div class="dropdown-item text-center o_no_activity"> <span class="fa fa-spinner fa-spin fa-2x" role="img" aria-label="Loading..." title="Loading..."/> - </li> + </div> </t> <t t-name="mail.KanbanActivityDropdown"> - <li role="menuitem" t-if="_.isEmpty(records)" class="text-center o_no_activity"> - <span>No activities planned.</span> - </li> - <li t-if="!_.isEmpty(records)" aria-haspopup="true" role="menu"> + <span role="menuitem" t-if="_.isEmpty(records)" class="dropdown-item-text text-center o_no_activity"> + No activities planned. + </span> + <div t-else="" class="dropdown-item" aria-haspopup="true" role="menu"> <ul class="nav o_activity_log" role="menu"> <t t-foreach="_.keys(records)" t-as="key"> <t t-set="logs" t-value="records[key]" /> @@ -51,12 +50,12 @@ </li> </t> </ul> - </li> - <li role="menuitem" class="o_schedule_activity text-center"> + </div> + <div role="menuitem" class="o_schedule_activity text-center"> <a role="button" class="btn btn-link btn-block"> <i class="fa fa-plus fa-fw"></i><strong>Schedule an activity</strong> </a> - </li> + </div> </t> </templates> diff --git a/addons/mail/static/tests/chatter_tests.js b/addons/mail/static/tests/chatter_tests.js index 43675fedcee..088a854333e 100644 --- a/addons/mail/static/tests/chatter_tests.js +++ b/addons/mail/static/tests/chatter_tests.js @@ -410,7 +410,7 @@ QUnit.test('kanban activity widget with an activity', function (assert) { assert.strictEqual(rpcCount, 5, 'should have done an RPC to mark activity as done, and a read'); assert.ok($record.find('.o_mail_activity .o_activity_color_default:not(.o_activity_color_today)').length, "activity widget should have been updated correctly"); - assert.strictEqual($record.find('.o_mail_activity.open').length, 1, + assert.strictEqual($record.find('.o_mail_activity.show').length, 1, "dropdown should remain open when marking an activity as done"); assert.strictEqual($record.find('.o_no_activity').length, 1, "should have no activity scheduled"); @@ -1466,9 +1466,9 @@ QUnit.test('followers widget: follow/unfollow, edit subtypes', function (assert) assert.strictEqual(form.$('.o_subtypes_list .o_subtype_checkbox:checked').length, 2, 'two subtypes should be checked by default'); form.$('.o_subtypes_list .dropdown-toggle').click(); // click to open the dropdown - assert.ok(form.$('.o_subtypes_list.open').length, 'dropdown should be opened'); + assert.ok(form.$('.o_subtypes_list.show').length, 'dropdown should be opened'); form.$('.o_subtypes_list .o_subtype input[data-id=2]').click(); // uncheck second subtype - assert.ok(form.$('.o_subtypes_list.open').length, 'dropdown should remain opened'); + assert.ok(form.$('.o_subtypes_list.show').length, 'dropdown should remain opened'); assert.ok(!form.$('.o_subtypes_list .o_subtype_checkbox[data-id=2]:checked').length, 'second subtype should now be unchecked'); diff --git a/addons/mail/static/tests/discuss_tests.js b/addons/mail/static/tests/discuss_tests.js index 54f13eb48a5..a061873c39b 100644 --- a/addons/mail/static/tests/discuss_tests.js +++ b/addons/mail/static/tests/discuss_tests.js @@ -211,7 +211,7 @@ QUnit.test('@ mention in channel', function (assert) { fetchListenersDef .then(concurrency.delay.bind(concurrency, 0)) .then(function () { - assert.strictEqual(discuss.$('.dropup.o_composer_mention_dropdown.open').length, 1, + assert.strictEqual(discuss.$('.dropup.o_composer_mention_dropdown.show').length, 1, "dropup menu for partner mentions should be open"); var $mentionPropositions = discuss.$('.o_mention_proposition'); diff --git a/addons/mail/static/tests/systray/systray_activity_menu_tests.js b/addons/mail/static/tests/systray/systray_activity_menu_tests.js index 83dbcbdfe4c..1b034dbdfd7 100644 --- a/addons/mail/static/tests/systray/systray_activity_menu_tests.js +++ b/addons/mail/static/tests/systray/systray_activity_menu_tests.js @@ -100,9 +100,9 @@ QUnit.test('activity menu widget: activity menu with 3 records', function (asser search_default_activities_overdue: 1, }; activityMenu.$('.dropdown-toggle').click(); - assert.strictEqual(activityMenu.$el.hasClass("open"), true, 'ActivityMenu should be open'); + assert.strictEqual(activityMenu.$el.hasClass("show"), true, 'ActivityMenu should be open'); activityMenu.$(".o_activity_filter_button[data-model_name='Issue'][data-filter='overdue']").click(); - assert.strictEqual(activityMenu.$el.hasClass("open"), false, 'ActivityMenu should be closed'); + assert.strictEqual(activityMenu.$el.hasClass("show"), false, 'ActivityMenu should be closed'); // case 2: click on "today" context = { search_default_activities_today: 1, diff --git a/addons/mail/static/tests/systray/systray_messaging_menu_tests.js b/addons/mail/static/tests/systray/systray_messaging_menu_tests.js index 54859060437..e1c5ef1851c 100644 --- a/addons/mail/static/tests/systray/systray_messaging_menu_tests.js +++ b/addons/mail/static/tests/systray/systray_messaging_menu_tests.js @@ -242,7 +242,7 @@ QUnit.test("messaging menu widget: mark as read on thread preview", function ( a messagingMenu.$('.dropdown-toggle').click(); assert.ok(messagingMenu.$el.hasClass('o_mail_systray_item'), 'should be the instance of widget'); - assert.ok(messagingMenu.$el.hasClass('open'), + assert.ok(messagingMenu.$el.hasClass('show'), 'MessagingMenu should be open'); var $preview = messagingMenu.$('.o_mail_preview.o_preview_unread'); diff --git a/addons/maintenance/views/maintenance_views.xml b/addons/maintenance/views/maintenance_views.xml index 5e06a9eff59..7c4d3a00995 100644 --- a/addons/maintenance/views/maintenance_views.xml +++ b/addons/maintenance/views/maintenance_views.xml @@ -134,14 +134,14 @@ <div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click oe_semantic_html_override"> <div class="o_dropdown_kanban dropdown"> - <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> + <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> <span class="fa fa-ellipsis-v"/> </a> - <ul class="dropdown-menu" role="menu"> - <t t-if="widget.editable"><li><a role="menuitem" type="edit">Edit...</a></li></t> - <t t-if="widget.deletable"><li><a role="menuitem" type="delete">Delete</a></li></t> - <li role="menuitem" aria-haspopup="true"><ul role="menu" class="oe_kanban_colorpicker" data-field="color"/></li> - </ul> + <div class="dropdown-menu" role="menu"> + <t t-if="widget.editable"><a role="menuitem" type="edit" class="dropdown-item">Edit...</a></t> + <t t-if="widget.deletable"><a role="menuitem" type="delete" class="dropdown-item">Delete</a></t> + <ul class="oe_kanban_colorpicker" data-field="color"/> + </div> </div> <div class="oe_kanban_content" tooltip="kanban-tooltip"> <div class="o_kanban_record_top"> @@ -431,16 +431,16 @@ <div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click"> <div class="o_dropdown_kanban dropdown"> - <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> + <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> <span class="fa fa-ellipsis-v"/> </a> - <ul class="dropdown-menu" role="menu"> - <t t-if="widget.editable"><li><a role="menuitem" type="edit">Edit...</a></li></t> - <t t-if="widget.deletable"><li><a role="menuitem" type="delete">Delete</a></li></t> - <li role="separator" class="divider"></li> - <li role="separator" class="dropdown-header">Record Colour</li> - <li role="menuitem" aria-haspopup="true"><ul role="menu" class="oe_kanban_colorpicker" data-field="color"/></li> - </ul> + <div class="dropdown-menu" role="menu"> + <t t-if="widget.editable"><a role="menuitem" type="edit" class="dropdown-item">Edit...</a></t> + <t t-if="widget.deletable"><a role="menuitem" type="delete" class="dropdown-item">Delete</a></t> + <div role="separator" class="dropdown-divider"></div> + <div role="separator" class="dropdown-header">Record Colour</div> + <ul class="oe_kanban_colorpicker" data-field="color"/> + </div> </div> <div class="oe_kanban_content" tooltip="kanban-tooltip"> <div class="o_kanban_record_top"> diff --git a/addons/mass_mailing/static/src/js/mass_mailing_editor.js b/addons/mass_mailing/static/src/js/mass_mailing_editor.js index ae38436ea2c..ec7f01bbc25 100644 --- a/addons/mass_mailing/static/src/js/mass_mailing_editor.js +++ b/addons/mass_mailing/static/src/js/mass_mailing_editor.js @@ -197,7 +197,7 @@ snippets_editor.Class.include({ * Add proposition to install enterprise themes if not installed. */ var $mail_themes_upgrade = $dropdown.find(".o_mass_mailing_themes_upgrade"); - $mail_themes_upgrade.on("click", "> a", function (e) { + $mail_themes_upgrade.on("click", function (e) { e.stopImmediatePropagation(); e.preventDefault(); odoo_top[window.callback+"_do_action"]("mass_mailing.action_mass_mailing_configuration"); @@ -208,15 +208,15 @@ snippets_editor.Class.include({ * is pressed. */ var selected_theme = false; - $dropdown.on("mouseenter", "li > a", function (e) { + $dropdown.on("mouseenter", ".dropdown-item", function (e) { if (first_choice) return; e.preventDefault(); - var theme_params = themes_params[$(e.currentTarget).parent().index()]; + var theme_params = themes_params[$(e.currentTarget).index()]; switch_theme(theme_params); }); - $dropdown.on("click", "li > a", function (e) { + $dropdown.on("click", ".dropdown-item", function (e) { e.preventDefault(); - var theme_params = themes_params[$(e.currentTarget).parent().index()]; + var theme_params = themes_params[$(e.currentTarget).index()]; if (first_choice) { switch_theme(theme_params); $body.removeClass("o_force_mail_theme_choice"); @@ -244,7 +244,7 @@ snippets_editor.Class.include({ */ $dropdown.on("shown.bs.dropdown", function () { check_selected_theme(); - $dropdown.find("li").removeClass("selected").filter(function () { + $dropdown.find(".dropdown-item").removeClass("selected").filter(function () { return ($(this).has(".o_thumb[style=\""+ "background-image: url(" + (selected_theme && selected_theme.img) + "_small.png)"+ "\"]").length > 0); }).addClass("selected"); }); diff --git a/addons/mass_mailing/static/src/scss/mass_mailing.ui.scss b/addons/mass_mailing/static/src/scss/mass_mailing.ui.scss index 93ea1689882..daaf956fc68 100644 --- a/addons/mass_mailing/static/src/scss/mass_mailing.ui.scss +++ b/addons/mass_mailing/static/src/scss/mass_mailing.ui.scss @@ -27,7 +27,7 @@ } } - &.open > a { + &.show > a { color: white; background-color: $o-we-color-dark; } @@ -39,26 +39,23 @@ overflow: auto; background-color: $o-we-color-dark; - > li { - margin: 0; + .dropdown-item { + padding: 10px 10px; - > a { - padding: 10px 10px; - - .o_thumb { - display: none; - background-size: cover; - padding-top: 50%; - border: 1px solid $o-we-color-light; - border-top: 1px solid $o-we-color-text-normal; + .o_thumb { + display: none; + background-size: cover; + padding-top: 50%; + border: 1px solid $o-we-color-light; + border-top: 1px solid $o-we-color-text-normal; - &.logo { - display: block; - } + &.logo { + display: block; } } - &:hover > a { + + &:hover { background-color: $o-we-color-darker; .o_thumb { @@ -66,7 +63,7 @@ } } - &.selected > a .o_thumb { + &.selected .o_thumb { border: 2px solid $o-brand-primary; background-color: $o-we-color-dark; } @@ -86,41 +83,39 @@ body.o_force_mail_theme_choice { .dropdown-menu { display: block; - > li { + .dropdown-item { margin: 0; float: left; + clear: none; width: 100%; max-width: 25%; - - > a { + transition: all 0.3s ease 0s; + + .o_thumb { + display: none; + padding-top: 107%; + border: 1px solid $o-we-color-light; + border-top: 1px solid $o-we-color-text-normal; + box-shadow: 0 5px 10px rgba(black, 0.8); + will-change: transform; + backface-visibility: hidden; transition: all 0.3s ease 0s; - .o_thumb { - display: none; - padding-top: 107%; - border: 1px solid $o-we-color-light; - border-top: 1px solid $o-we-color-text-normal; - box-shadow: 0 5px 10px rgba(black, 0.8); - will-change: transform; - backface-visibility: hidden; - transition: all 0.3s ease 0s; + &.small { + display: block; + } + @media screen and (min-width: 900px) { &.small { - display: block; + display: none; } - - @media screen and (min-width: 900px) { - &.small { - display: none; - } - &.large { - display: block; - } + &.large { + display: block; } } } - &:hover > a { + &:hover { background-color: $o-we-color-dark; .o_thumb { @@ -128,7 +123,7 @@ body.o_force_mail_theme_choice { } } - &.o_mass_mailing_themes_upgrade > a .o_thumb { + &.o_mass_mailing_themes_upgrade .o_thumb { position: relative; display: block; border: 1px dashed white; diff --git a/addons/mass_mailing/static/src/xml/mass_mailing.xml b/addons/mass_mailing/static/src/xml/mass_mailing.xml index ae79ebff979..cdc23484cdd 100644 --- a/addons/mass_mailing/static/src/xml/mass_mailing.xml +++ b/addons/mass_mailing/static/src/xml/mass_mailing.xml @@ -5,18 +5,18 @@ <i class="fa fa-paint-brush"/> Change Style </a> <div class="dropdown-menu" role="menu"> - <li t-foreach="themes" t-as="theme"> - <a role="menuitem" href="#"> + <t t-foreach="themes" t-as="theme"> + <a role="menuitem" href="#" class="dropdown-item"> <div class="o_thumb small" t-attf-style="background-image: url(#{theme.img}_small.png)"/> <div class="o_thumb large" t-attf-style="background-image: url(#{theme.img}_large.png)"/> <div class="o_thumb logo" t-attf-style="background-image: url(#{theme.img}_logo.png)"/> </a> - </li> - <li t-if="themes.length === 1" class="o_mass_mailing_themes_upgrade"> - <a role="menuitem" href="#"> + </t> + <t t-if="themes.length === 1"> + <a role="menuitem" href="#" class="dropdown-item o_mass_mailing_themes_upgrade"> <div class="o_thumb"><i class="fa fa-plus" role="img" aria-label="Upgrade theme" title="Upgrade theme"/></div> </a> - </li> + </t> </div> </div> </templates> diff --git a/addons/mass_mailing/views/mass_mailing_views.xml b/addons/mass_mailing/views/mass_mailing_views.xml index b0f1e7cc44e..c94d197d7c8 100644 --- a/addons/mass_mailing/views/mass_mailing_views.xml +++ b/addons/mass_mailing/views/mass_mailing_views.xml @@ -313,17 +313,13 @@ </div> <div class="o_kanban_card_manage_pane"> <div class="o_kanban_card_manage_section o_dropdown_kanban dropdown"> - <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> + <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> <span class="fa fa-ellipsis-v"/> </a> - <ul class="dropdown-menu" role="menu"> - <li t-if="widget.editable"> - <a role="menuitem" type="edit">Edit</a> - </li> - <li t-if="widget.deletable"> - <a role="menuitem" type="delete">Delete</a> - </li> - </ul> + <div class="dropdown-menu" role="menu"> + <a t-if="widget.editable" role="menuitem" type="edit" class="dropdown-item">Edit</a> + <a t-if="widget.deletable" role="menuitem" type="delete" class="dropdown-item">Delete</a> + </div> </div> </div> </div> @@ -566,15 +562,15 @@ <t t-name="kanban-box"> <div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click oe_kanban_mass_mailing"> <div class="o_dropdown_kanban dropdown"> - <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> + <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> <span class="fa fa-ellipsis-v"/> </a> - <ul class="dropdown-menu" role="menu"> - <li role="menuitem" aria-haspopup="true"><ul role="menu" class="oe_kanban_colorpicker" data-field="color"/></li> + <div class="dropdown-menu" role="menu"> + <ul class="oe_kanban_colorpicker" data-field="color"/> <t t-if="widget.deletable"> - <li><a role="menuitem" type="delete">Delete</a></li> + <a role="menuitem" type="delete" class="dropdown-item">Delete</a> </t> - </ul> + </div> </div> <div class="oe_kanban_content"> <div class="o_kanban_record_top"> @@ -920,20 +916,20 @@ <div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click oe_kanban_mass_mailing_campaign"> <div class="o_dropdown_kanban dropdown"> - <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> + <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> <span class="fa fa-ellipsis-v"/> </a> - <ul class="dropdown-menu" role="menu"> + <div class="dropdown-menu" role="menu"> <t t-if="widget.editable"> - <li><a role="menuitem" type="edit">Settings</a></li> + <a role="menuitem" type="edit" class="dropdown-item">Settings</a> </t> <t t-if="widget.deletable"> - <li><a role="menuitem" type="delete">Delete</a></li> + <a role="menuitem" type="delete" class="dropdown-item">Delete</a> </t> - <li role="separator" class="divider"/> - <li role="separator" class="dropdown-header">Colour</li> - <li role="menuitem" aria-haspopup="true"><ul class="oe_kanban_colorpicker" role="menu" data-field="color"/></li> - </ul> + <div role="separator" class="dropdown-divider"/> + <div role="separator" class="dropdown-header">Colour</div> + <ul class="oe_kanban_colorpicker" data-field="color"/> + </div> </div> <div class="oe_kanban_content"> <div class="o_kanban_record_top mb16"> diff --git a/addons/mass_mailing/views/snippets_themes_options.xml b/addons/mass_mailing/views/snippets_themes_options.xml index 0a2a4a7bf81..65b25bc76bf 100644 --- a/addons/mass_mailing/views/snippets_themes_options.xml +++ b/addons/mass_mailing/views/snippets_themes_options.xml @@ -43,9 +43,7 @@ data-exclude=".o_mail_no_colorpicker, .o_mail_no_options"> <li class="dropdown-submenu"> <a tabindex="-1" href="#"><i class="fa fa-eyedropper"/>Background Color</a> - <ul class="dropdown-menu" role="menu"> - <li></li> - </ul> + <div class="dropdown-menu" role="menu"/> </li> </div> </template> diff --git a/addons/note/views/note_views.xml b/addons/note/views/note_views.xml index 772b320dc12..d9b5fb8f052 100644 --- a/addons/note/views/note_views.xml +++ b/addons/note/views/note_views.xml @@ -97,13 +97,13 @@ <field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color'}"/> <div class="o_dropdown_kanban dropdown"> - <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> + <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> <span class="fa fa-ellipsis-v"/> </a> - <ul class="dropdown-menu" role="menu"> - <li><a role="menuitem" type="delete">Delete</a></li> - <li role="menuitem" aria-haspopup="true"><ul role="menu" class="oe_kanban_colorpicker" data-field="color"/></li> - </ul> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" type="delete" class="dropdown-item">Delete</a> + <ul class="oe_kanban_colorpicker" data-field="color"/> + </div> </div> <span> <a name="action_close" type="object" t-if="record.open.raw_value"><i class="fa fa-check" role="img" aria-label="Opened" title="Opened"/></a> diff --git a/addons/point_of_sale/views/pos_templates.xml b/addons/point_of_sale/views/pos_templates.xml index c6be6011cdd..7327aa936c6 100644 --- a/addons/point_of_sale/views/pos_templates.xml +++ b/addons/point_of_sale/views/pos_templates.xml @@ -98,26 +98,26 @@ <div data-js='pos_company_logo' data-selector=".pos-company_logo"/> <div data-js='pos_palette' data-selector=".pos-customer_facing_display"> - <li data-select-class="pos-palette_01"><a href="#" class="pos-palette_01"/></li> - <li data-select-class="pos-palette_02"><a href="#" class="pos-palette_02"/></li> - <li data-select-class="pos-palette_03"><a href="#" class="pos-palette_03"/></li> - <li data-select-class="pos-palette_04"><a href="#" class="pos-palette_04"/></li> - <li data-select-class="pos-palette_05"><a href="#" class="pos-palette_05"/></li> - <li data-select-class="pos-palette_06"><a href="#" class="pos-palette_06"/></li> - <li data-select-class="pos-palette_07"><a href="#" class="pos-palette_07"/></li> - <li data-select-class="pos-palette_08"><a href="#" class="pos-palette_08"/></li> - <li data-select-class="pos-palette_09"><a href="#" class="pos-palette_09"/></li> - <li data-select-class="pos-palette_10"><a href="#" class="pos-palette_10"/></li> - <li data-select-class="pos-palette_11"><a href="#" class="pos-palette_11"/></li> - <li data-select-class="pos-palette_12"><a href="#" class="pos-palette_12"/></li> - <li data-select-class="pos-palette_13"><a href="#" class="pos-palette_13"/></li> + <a href="#" class="pos-palette_01 dropdown-item" data-select-class="pos-palette_01"></a> + <a href="#" class="pos-palette_02 dropdown-item" data-select-class="pos-palette_02"></a> + <a href="#" class="pos-palette_03 dropdown-item" data-select-class="pos-palette_03"></a> + <a href="#" class="pos-palette_04 dropdown-item" data-select-class="pos-palette_04"></a> + <a href="#" class="pos-palette_05 dropdown-item" data-select-class="pos-palette_05"></a> + <a href="#" class="pos-palette_06 dropdown-item" data-select-class="pos-palette_06"></a> + <a href="#" class="pos-palette_07 dropdown-item" data-select-class="pos-palette_07"></a> + <a href="#" class="pos-palette_08 dropdown-item" data-select-class="pos-palette_08"></a> + <a href="#" class="pos-palette_09 dropdown-item" data-select-class="pos-palette_09"></a> + <a href="#" class="pos-palette_10 dropdown-item" data-select-class="pos-palette_10"></a> + <a href="#" class="pos-palette_11 dropdown-item" data-select-class="pos-palette_11"></a> + <a href="#" class="pos-palette_12 dropdown-item" data-select-class="pos-palette_12"></a> + <a href="#" class="pos-palette_13 dropdown-item" data-select-class="pos-palette_13"></a> </div> <div data-js='pos_background' data-selector=".pos-company_logo, .pos-adv"> - <li data-choose-image="true" data-no-preview="true"><a href="#"><b>Set Custom Image...</b></a></li> - <li class="d-none pos-use_default_logo" data-background=""><a href="#">Default company logo</a></li> - <li class="divider"/> - <li data-toggle-class="pos-hidden"><a href="#"><i class="fa fa-eye-slash"/>Hide</a></li> + <a href="#" class="dropdown-item" data-choose-image="true" data-no-preview="true"><b>Set Custom Image...</b></a> + <a href="#" class="dropdown-item d-none pos-use_default_logo" data-background="">Default company logo</a> + <div class="dropdown-divider"/> + <a href="#" class="dropdown-item" data-toggle-class="pos-hidden"><i class="fa fa-eye-slash"/>Hide</a> </div> </div> </template> diff --git a/addons/portal/static/src/js/portal.js b/addons/portal/static/src/js/portal.js index 5842596db1b..f750bab1318 100644 --- a/addons/portal/static/src/js/portal.js +++ b/addons/portal/static/src/js/portal.js @@ -23,21 +23,21 @@ odoo.define('portal.portal', function (require) { if ($('.o_portal_search_panel').length) { $('.o_portal_search_panel .search-submit').click(function () { var search = $.deparam(window.location.search.substring(1)); - search.search_in = $(".o_portal_search_panel li.active a").attr("href").replace("#",""); + search.search_in = $(".o_portal_search_panel .dropdown-item.active").attr("href").replace("#",""); search.search = $(".o_portal_search_panel input[name='search']").val(); window.location.search = $.param(search); }); - $('.o_portal_search_panel .dropdown-menu').find('a').click(function (e) { + $('.o_portal_search_panel .dropdown-menu').find('.dropdown-item').click(function (e) { e.preventDefault(); - $(this).parents('.dropdown-menu').find('li').removeClass('active'); - $(this).parent('li').addClass('active'); + $(this).parents('.dropdown-menu').find('.dropdown-item').removeClass('active'); + $(this).closest('.dropdown-item').addClass('active'); var label = $(this).clone(); label.find('span.nolabel').remove(); $(".o_portal_search_panel span#search_label").text(label.text()); }); // init search label - $('.o_portal_search_panel .dropdown-menu').find('li.active a').trigger('click'); + $('.o_portal_search_panel .dropdown-menu').find('.dropdown-item.active').trigger('click'); $(".o_portal_search_panel input[name='search']").on('keyup', function (e) { if (e.keyCode === 13) { diff --git a/addons/portal/views/portal_templates.xml b/addons/portal/views/portal_templates.xml index 89bc191cf32..da0ca7f5f2c 100644 --- a/addons/portal/views/portal_templates.xml +++ b/addons/portal/views/portal_templates.xml @@ -47,12 +47,11 @@ <a href="#" class="dropdown-toggle" data-toggle="dropdown"> <b> <span t-esc="user_id.name[:23] + '...' if user_id.name and len(user_id.name) > 25 else user_id.name"/> - <span class="caret"></span> </b> </a> - <ul class="dropdown-menu js_usermenu" role="menu"> - <li id="o_logout"><a t-attf-href="/web/session/logout?redirect=/" role="menuitem">Logout</a></li> - </ul> + <div class="dropdown-menu js_usermenu" role="menu"> + <a id="o_logout" class="dropdown-item" t-attf-href="/web/session/logout?redirect=/" role="menuitem">Logout</a> + </div> </li> </ul> </div> @@ -175,46 +174,46 @@ <ul class="nav pull-left"> <t t-raw="0"/> <li t-if="searchbar_sortings" class="dropdown pull-left ml16"> - <button id="portal_searchbar_sortby" data-toggle="dropdown" class="btn btn-secondary navbar-btn"> + <button id="portal_searchbar_sortby" data-toggle="dropdown" class="btn btn-secondary dropdown-toggle navbar-btn"> <span class="fa fa-sort"/> <span class="d-none d-lg-inline"><t t-esc="searchbar_sortings[sortby].get('label', 'Newest')"/></span> - <span class="caret"/> </button> - <ul class="dropdown-menu" aria-labelledby="portal_searchbar_sortby"> - <li t-foreach="searchbar_sortings" t-as="option" t-attf-class="#{sortby == option and 'active'}"> - <a t-att-href="request.httprequest.path + '?' + keep_query('*', sortby=option)"> + <div class="dropdown-menu" aria-labelledby="portal_searchbar_sortby"> + <t t-foreach="searchbar_sortings" t-as="option"> + <a t-att-href="request.httprequest.path + '?' + keep_query('*', sortby=option)" + t-attf-class="dropdown-item#{sortby == option and ' active' or ''}"> <span t-esc="searchbar_sortings[option].get('label')"/> </a> - </li> - </ul> + </t> + </div> </li> <li t-if="searchbar_filters" class="dropdown pull-left ml4"> - <button id="portal_searchbar_filters" data-toggle="dropdown" class="btn btn-secondary navbar-btn"> + <button id="portal_searchbar_filters" data-toggle="dropdown" class="btn btn-secondary dropdown-toggle navbar-btn"> <span class="fa fa-filter"/> <span class="d-none d-lg-inline"><t t-esc="searchbar_filters[filterby].get('label', 'All')"/></span> - <span class="caret"/> </button> - <ul class="dropdown-menu" aria-labelledby="portal_searchbar_filters"> - <li t-foreach="searchbar_filters" t-as="option" t-att-class="filterby == option and 'active'"> - <a t-att-href="default_url + '?' + keep_query('*', filterby=option)"> + <div class="dropdown-menu" aria-labelledby="portal_searchbar_filters"> + <t t-foreach="searchbar_filters" t-as="option"> + <a t-att-href="default_url + '?' + keep_query('*', filterby=option)" + t-attf-class="dropdown-item#{filterby == option and ' active' or ''}"> <span t-esc="searchbar_filters[option].get('label')"/> </a> - </li> - </ul> + </t> + </div> </li> <li t-if="searchbar_groupby" class="dropdown pull-left ml4"> - <button id="portal_searchbar_groupby" data-toggle="dropdown" class="btn btn-secondary navbar-btn"> + <button id="portal_searchbar_groupby" data-toggle="dropdown" class="btn btn-secondary dropdown-toggle navbar-btn"> <span class="fa fa-object-group"/> <span class="d-none d-lg-inline"><t t-esc="searchbar_groupby[groupby].get('label', 'None')"/></span> - <span class="caret"/> </button> - <ul class="dropdown-menu" aria-labelledby="portal_searchbar_groupby"> - <li t-foreach="searchbar_groupby" t-as="option" t-att-class="groupby == option and 'active'"> - <a t-att-href="default_url + '?' + keep_query('*', groupby=option)"> + <div class="dropdown-menu" aria-labelledby="portal_searchbar_groupby"> + <t t-foreach="searchbar_groupby" t-as="option"> + <a t-att-href="default_url + '?' + keep_query('*', groupby=option)" + t-attf-class="dropdown-item#{groupby == option and ' active' or ''}"> <span t-esc="searchbar_groupby[option].get('label')"/> </a> - </li> - </ul> + </t> + </div> </li> </ul> <button t-if='searchbar_inputs' type="button" class="navbar-toggle collapsed btn ml16" data-toggle="collapse" data-target="#o_portal_searchbar_collapse"><span class="fa fa-search"/></button> @@ -227,13 +226,16 @@ <div class="input-group"> <div class="input-group-btn"> <button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown"> - <span id="search_label" class="d-none d-md-inline mr4">Search</span><span class="caret"></span> + <span id="search_label" class="d-none d-md-inline mr4">Search</span> </button> - <ul class="dropdown-menu" role="menu"> - <li t-foreach='searchbar_inputs' t-as='input' t-att-class="search_in == searchbar_inputs[input]['input'] and 'active'"> - <a t-att-href="'#' + searchbar_inputs[input]['input']"><span t-raw="searchbar_inputs[input]['label']"/></a> - </li> - </ul> + <div class="dropdown-menu" role="menu"> + <t t-foreach='searchbar_inputs' t-as='input'> + <a t-att-href="'#' + searchbar_inputs[input]['input']" + t-attf-class="dropdown-item#{search_in == searchbar_inputs[input]['input'] and ' active' or ''}"> + <span t-raw="searchbar_inputs[input]['label']"/> + </a> + </t> + </div> </div> <input type="text" class="form-control" t-att-value='search' name="search"/> <span class="input-group-btn"> @@ -383,8 +385,8 @@ </template> <template id="my_account_link" name="Link to frontend portal" inherit_id="portal.frontend_layout"> - <xpath expr="//li[@id='o_logout']" position="before"> - <li><a href="/my/home" role="menuitem">My Account</a></li> + <xpath expr="//a[@id='o_logout']" position="before"> + <a href="/my/home" role="menuitem" class="dropdown-item">My Account</a> </xpath> </template> diff --git a/addons/project/static/tests/project_tests.js b/addons/project/static/tests/project_tests.js index e659658a7a2..35b41e93e9d 100644 --- a/addons/project/static/tests/project_tests.js +++ b/addons/project/static/tests/project_tests.js @@ -82,14 +82,12 @@ QUnit.module('project', { '<div>' + '<field name="name"/>' + '<div class="o_dropdown_kanban dropdown">' + - '<a class="dropdown-toggle btn" data-toggle="dropdown" href="#">' + + '<a class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#">' + '<span class="fa fa-bars fa-lg"/>' + '</a>' + - '<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">' + - '<li>' + - '<a type="set_cover">Set Cover Image</a>'+ - '</li>' + - '</ul>' + + '<div class="dropdown-menu" role="menu">' + + '<a type="set_cover" class="dropdown-item">Set Cover Image</a>'+ + '</div>' + '</div>' + '<div>'+ '<field name="displayed_image_id" widget="attachment_image"/>'+ diff --git a/addons/project/views/project_views.xml b/addons/project/views/project_views.xml index de6663ec65d..835dcf868f0 100644 --- a/addons/project/views/project_views.xml +++ b/addons/project/views/project_views.xml @@ -552,19 +552,17 @@ </small> </div> <div class="o_dropdown_kanban dropdown" groups="base.group_user"> - <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> + <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> <span class="fa fa-ellipsis-v"/> </a> - <ul class="dropdown-menu" role="menu"> - <li t-if="widget.editable"><a role="menuitem" type="set_cover">Set Cover Image</a></li> - <li t-if="widget.editable"><a role="menuitem" type="edit">Edit Task</a></li> - <li t-if="widget.deletable"><a role="menuitem" type="delete">Delete</a></li> - <li role="separator" class="divider"></li> - <li role="separator" class="dropdown-header">Record's Colour</li> - <li role="menuitem" aria-haspopup="true"> - <ul role="menu" class="oe_kanban_colorpicker" data-field="color"/> - </li> - </ul> + <div class="dropdown-menu" role="menu"> + <a t-if="widget.editable" role="menuitem" type="set_cover" class="dropdown-item">Set Cover Image</a> + <a t-if="widget.editable" role="menuitem" type="edit" class="dropdown-item">Edit Task</a> + <a t-if="widget.deletable" role="menuitem" type="delete" class="dropdown-item">Delete</a> + <div role="separator" class="dropdown-divider"></div> + <div role="separator" class="dropdown-header">Record's Colour</div> + <ul class="oe_kanban_colorpicker" data-field="color"/> + </div> </div> </div> <div class="o_kanban_record_body"> diff --git a/addons/survey/views/survey_views.xml b/addons/survey/views/survey_views.xml index 94db82a6a8e..4a259b67e51 100644 --- a/addons/survey/views/survey_views.xml +++ b/addons/survey/views/survey_views.xml @@ -239,16 +239,16 @@ <div t-name="kanban-box" t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click"> <div class="o_dropdown_kanban dropdown" t-if="widget.editable"> - <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> + <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> <span class="fa fa-ellipsis-v"/> </a> - <ul class="dropdown-menu" role="menu"> - <li><a role="menuitem" type="edit">Edit Survey</a></li> - <li t-if="widget.deletable"><a role="menuitem" type="delete">Delete</a></li> - <li role="separator" class="divider"/> - <li role="separator">Color</li> - <li role="menuitem" aria-haspopup="true"><ul role="menu" class="oe_kanban_colorpicker" data-field="color"/></li> - </ul> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" type="edit" class="dropdown-item">Edit Survey</a> + <a t-if="widget.deletable" role="menuitem" type="delete" class="dropdown-item">Delete</a> + <div role="separator" class="dropdown-divider"/> + <div role="separator" class="dropdown-item-text">Color</div> + <ul class="oe_kanban_colorpicker" data-field="color"/> + </div> </div> <div class="o_kanban_record_top"> <h4 class="o_kanban_record_title mb4"><field name="title" /></h4> diff --git a/addons/web/static/src/js/chrome/sidebar.js b/addons/web/static/src/js/chrome/sidebar.js index 47d598aaeb8..d02c936f470 100644 --- a/addons/web/static/src/js/chrome/sidebar.js +++ b/addons/web/static/src/js/chrome/sidebar.js @@ -11,7 +11,7 @@ var _t = core._t; var Sidebar = Widget.extend({ events: { - "click .dropdown-menu li a": "_onDropdownClicked" + "click .dropdown-item": "_onDropdownClicked" }, /** * @override @@ -177,9 +177,10 @@ var Sidebar = Widget.extend({ this.$el.html(QWeb.render('Sidebar', {widget: this})); // Hides Sidebar sections when item list is empty - this.$('.o_dropdown').each(function () { - if (!$(this).find('li').length) { - $(this).hide(); + _.each(this.$('.o_dropdown'), function (el) { + var $dropdown = $(el); + if (!$dropdown.find('.dropdown-item').length) { + $dropdown.hide(); } }); this.$("[title]").tooltip({ diff --git a/addons/web/static/src/js/chrome/user_menu.js b/addons/web/static/src/js/chrome/user_menu.js index 84c16b51f82..1251c9b6b5b 100644 --- a/addons/web/static/src/js/chrome/user_menu.js +++ b/addons/web/static/src/js/chrome/user_menu.js @@ -23,7 +23,7 @@ var UserMenu = Widget.extend({ start: function () { var self = this; var session = this.getSession(); - this.$el.on('click', 'li a[data-menu]', function (ev) { + this.$el.on('click', '[data-menu]', function (ev) { ev.preventDefault(); var menu = $(this).data('menu'); self['_onMenu' + menu.charAt(0).toUpperCase() + menu.slice(1)](); diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index 51816220c9f..00092073d6a 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -1612,10 +1612,7 @@ var AttachmentImage = AbstractField.extend({ var StateSelectionWidget = AbstractField.extend({ template: 'FormSelection', events: { - 'click a': function (e) { - e.preventDefault(); - }, - 'click li': '_setSelection' + 'click .dropdown-item': '_setSelection', }, supportedFieldTypes: ['selection'], @@ -1696,13 +1693,12 @@ var StateSelectionWidget = AbstractField.extend({ * @param {MouseEvent} ev */ _setSelection: function (ev) { - var li = $(ev.target).closest('li'); - if (li.length) { - var value = String(li.data('value')); - this._setValue(value); - if (this.mode === 'edit') { - this._render(); - } + ev.preventDefault(); + var $item = $(ev.currentTarget); + var value = String($item.data('value')); + this._setValue(value); + if (this.mode === 'edit') { + this._render(); } }, }); diff --git a/addons/web/static/src/js/views/form/form_renderer.js b/addons/web/static/src/js/views/form/form_renderer.js index 5d4e2ad4cb5..a0bb82d569f 100644 --- a/addons/web/static/src/js/views/form/form_renderer.js +++ b/addons/web/static/src/js/views/form/form_renderer.js @@ -363,11 +363,11 @@ var FormRenderer = BasicRenderer.extend({ text: _t("More"), })); - var $ul = $("<ul>", {'class': "dropdown-menu o_dropdown_more", role: "menu"}); + var $dropdown = $("<div>", {'class': "dropdown-menu o_dropdown_more", role: "menu"}); _.each(folded_buttons, function ($button) { - $('<li>').appendTo($ul).append($button); + $button.addClass('dropdown-item').appendTo($dropdown); }); - $ul.appendTo($result); + $dropdown.appendTo($result); } this._handleAttributes($result, node); diff --git a/addons/web/static/src/js/views/graph/graph_controller.js b/addons/web/static/src/js/views/graph/graph_controller.js index 36a05af7653..b6a1c121f0f 100644 --- a/addons/web/static/src/js/views/graph/graph_controller.js +++ b/addons/web/static/src/js/views/graph/graph_controller.js @@ -161,8 +161,9 @@ var GraphController = AbstractController.extend(GroupByMenuInterfaceMixin,{ this.$buttons .find('.o_graph_button[data-mode="' + state.mode + '"]') .addClass('active'); - this.$measureList.find('li').each(function (index, li) { - $(li).toggleClass('selected', $(li).data('field') === state.measure); + _.each(this.$measureList.find('.dropdown-item'), function (item) { + var $item = $(item); + $item.toggleClass('selected', $item.data('field') === state.measure); }); }, @@ -185,8 +186,7 @@ var GraphController = AbstractController.extend(GroupByMenuInterfaceMixin,{ } else if ($target.parents('.o_graph_measures_list').length) { event.preventDefault(); event.stopPropagation(); - parent = $target.parent(); - field = parent.data('field'); + field = $target.data('field'); this._setMeasure(field); } }, diff --git a/addons/web/static/src/js/views/pivot/pivot_controller.js b/addons/web/static/src/js/views/pivot/pivot_controller.js index f0976c9a8b4..945cc132b03 100644 --- a/addons/web/static/src/js/views/pivot/pivot_controller.js +++ b/addons/web/static/src/js/views/pivot/pivot_controller.js @@ -164,9 +164,9 @@ var PivotController = AbstractController.extend({ fields: fields })); - this.$fieldSelection.find('ul').first() + this.$fieldSelection.find('.dropdown-menu').first() .css({top: top, left: left}) - .show(); + .addClass('show'); }, /** * @private @@ -186,7 +186,7 @@ var PivotController = AbstractController.extend({ var state = this.model.get({raw: true}); _.each(this.measures, function (measure, name) { var isSelected = _.contains(state.measures, name); - self.$buttons.find('li[data-field="' + name + '"]') + self.$buttons.find('.dropdown-item[data-field="' + name + '"]') .toggleClass('selected', isSelected); }); }, @@ -215,8 +215,7 @@ var PivotController = AbstractController.extend({ .then(this.update.bind(this, {}, {reload: false})); } if ($target.parents('.o_pivot_measures_list').length) { - var parent = $target.parent(); - var field = parent.data('field'); + var field = $target.data('field'); event.preventDefault(); event.stopPropagation(); this.model @@ -298,11 +297,11 @@ var PivotController = AbstractController.extend({ _onFieldMenuSelection: function (event) { event.preventDefault(); var $target = $(event.target); - if ($target.parent().hasClass('disabled')) { + if ($target.hasClass('disabled')) { event.stopPropagation(); return; } - var field = $target.parent().data('field'); + var field = $target.data('field'); var interval = $target.data('interval'); var header = this.model.getHeader(this.lastHeaderSelected); if (interval) { diff --git a/addons/web/static/src/js/views/search/favorites_menu.js b/addons/web/static/src/js/views/search/favorites_menu.js index 1e62ffb5ce3..47e99aec573 100644 --- a/addons/web/static/src/js/views/search/favorites_menu.js +++ b/addons/web/static/src/js/views/search/favorites_menu.js @@ -14,14 +14,11 @@ var _t = core._t; return Widget.extend({ template: 'SearchView.FavoriteMenu', events: { - 'click li': function (event) { - event.stopImmediatePropagation(); + 'click .dropdown-item': function (ev) { + ev.preventDefault(); }, - 'click li a': function (event) { - event.preventDefault(); - }, - 'click .o_save_search a': function (event) { - event.preventDefault(); + 'click .o_save_search': function (ev) { + ev.preventDefault(); this.toggle_save_menu(); }, 'click .o_save_name button': 'save_favorite', @@ -49,8 +46,8 @@ return Widget.extend({ this.$save_search = this.$('.o_save_search'); this.$save_name = this.$('.o_save_name'); this.$inputs = this.$save_name.find('input'); - this.$user_divider = this.$('.divider.user_filter'); - this.$shared_divider = this.$('.divider.shared_filter'); + this.$user_divider = this.$('.dropdown-divider.user_filter'); + this.$shared_divider = this.$('.dropdown-divider.shared_filter'); this.$inputs.eq(0).val(this.searchview.get_title()); var $shared_filter = this.$inputs.eq(1), $default_filter = this.$inputs.eq(2); @@ -207,7 +204,7 @@ return Widget.extend({ }; }, clear_selection: function () { - this.$('li.selected').removeClass('selected'); + this.$('.selected').removeClass('selected'); }, /** * Adds a filter description to the filters dict @@ -230,10 +227,10 @@ return Widget.extend({ this.$shared_divider.show(); } if (!(key in this.$filters)) { - var $filter = $('<li>') + var $filter = $('<div>', {class: 'position-relative'}) .addClass(filter.user_id ? 'o-searchview-custom-private' : 'o-searchview-custom-public') - .append($('<a>', {'href': '#'}).text(filter.name)) + .append($('<a>', {href: '#', class: 'dropdown-item'}).text(filter.name)) .append($('<span>', { class: 'fa fa-trash-o o-remove-filter', on: { @@ -256,7 +253,7 @@ return Widget.extend({ }); if (current) { this.query.remove(current); - this.$filters[this.key_for(filter)].removeClass('selected'); + this.$filters[this.key_for(filter)].find('.dropdown-item').removeClass('selected'); return; } this.query.reset([this.facet_for(filter)], { @@ -268,7 +265,7 @@ return Widget.extend({ this.searchview.dataset.set_sort(sort_items); } - this.$filters[this.key_for(filter)].addClass('selected'); + this.$filters[this.key_for(filter)].find('.dropdown-item').addClass('selected'); }, remove_filter: function (filter, $filter, key) { var self = this; diff --git a/addons/web/static/src/js/views/search/filters_menu.js b/addons/web/static/src/js/views/search/filters_menu.js index 221f98faa97..cf79bec2640 100644 --- a/addons/web/static/src/js/views/search/filters_menu.js +++ b/addons/web/static/src/js/views/search/filters_menu.js @@ -76,7 +76,7 @@ var FiltersMenu = DropdownMenu.extend({ category: 'filterCategory', title: 'Filters', icon: 'fa fa-filter', - symbol: this.isMobile ? 'fa fa-chevron-right pull-right mt4' : 'caret' + symbol: this.isMobile ? 'fa fa-chevron-right pull-right mt4' : false, }; this._super(parent, dropdownHeader, filters, this.fields); }, @@ -88,7 +88,7 @@ var FiltersMenu = DropdownMenu.extend({ * @private */ start: function () { - this.$menu = this.$('ul.o_dropdown_menu'); + this.$menu = this.$('.o_dropdown_menu'); this.$menu.addClass('o_filters_menu'); var generatorMenu = QWeb.render('FiltersMenuGenerator', {widget: this}); this.$menu.append(generatorMenu); diff --git a/addons/web/static/src/js/views/search/groupby_menu.js b/addons/web/static/src/js/views/search/groupby_menu.js index 7be61ae6606..8540e702589 100644 --- a/addons/web/static/src/js/views/search/groupby_menu.js +++ b/addons/web/static/src/js/views/search/groupby_menu.js @@ -14,7 +14,7 @@ var DEFAULT_INTERVAL = 'month'; var GroupByMenu = DropdownMenu.extend({ events: _.extend({}, DropdownMenu.prototype.events, { - 'click .o_add_custom_group a': '_onAddCustomGroupClick', + 'click .o_add_custom_group': '_onAddCustomGroupClick', 'click button.o_apply_group': '_onButtonApplyClick', 'click .o_group_selector': '_onGroupSelectorClick', }), @@ -85,7 +85,7 @@ var GroupByMenu = DropdownMenu.extend({ category: 'groupByCategory', title: 'Group By', icon: 'fa fa-bars', - symbol: this.isMobile ? 'fa fa-chevron-right pull-right mt4' : 'caret', + symbol: this.isMobile ? 'fa fa-chevron-right pull-right mt4' : false, style: style, }; this._super(parent, dropdownHeader, groupbys, options); @@ -98,7 +98,7 @@ var GroupByMenu = DropdownMenu.extend({ * @private */ start: function () { - this.$menu = this.$('ul.o_dropdown_menu'); + this.$menu = this.$('.o_dropdown_menu'); this.$menu.addClass('o_group_by_menu'); var $generatorMenu = QWeb.render('GroupbyMenuGenerator', {widget: this}); this.$menu.append($generatorMenu); diff --git a/addons/web/static/src/js/views/search/search_inputs.js b/addons/web/static/src/js/views/search/search_inputs.js index ee179d7da74..81f53ee4053 100644 --- a/addons/web/static/src/js/views/search/search_inputs.js +++ b/addons/web/static/src/js/views/search/search_inputs.js @@ -503,8 +503,13 @@ var ManyToOneField = CharField.extend({ var FilterGroup = Input.extend(/** @lends instance.web.search.FilterGroup# */{ template: 'SearchView.filters', + events: { + click: 'toggle_filter', + }, + icon: "fa-filter", completion_label: _lt("Filter on: %s"), + /** * Inclusive group of filters, creates a continuous "button" with clickable * sections (the normal display for filters is to be a self-contained button) @@ -536,7 +541,6 @@ var FilterGroup = Input.extend(/** @lends instance.web.search.FilterGroup# */{ this.searchview.query.on('add remove change reset', this.proxy('search_change')); }, start: function () { - this.$el.on('click', 'a', this.proxy('toggle_filter')); return $.when(null); }, /** @@ -684,7 +688,7 @@ var FilterGroup = Input.extend(/** @lends instance.web.search.FilterGroup# */{ toggle_filter: function (e) { e.preventDefault(); e.stopPropagation(); - this.toggle(this.filters[Number($(e.target).parent().data('index'))]); + this.toggle(this.filters[Number($(e.currentTarget).data('index'))]); }, toggle: function (filter, options) { this.searchview.query.toggle(this.make_facet([this.make_value(filter)]), options); diff --git a/addons/web/static/src/js/widgets/data_export.js b/addons/web/static/src/js/widgets/data_export.js index 30e17604077..d05bf2d33fc 100644 --- a/addons/web/static/src/js/widgets/data_export.js +++ b/addons/web/static/src/js/widgets/data_export.js @@ -49,7 +49,7 @@ var DataExport = Dialog.extend({ function process_children() { var $this = $(this); - if($this.hasClass('open')) { + if($this.hasClass('show')) { $this.children('.o_export_tree_item') .addClass('o_selected') .each(process_children); @@ -77,19 +77,19 @@ var DataExport = Dialog.extend({ switch(e.keyCode || e.which) { case $.ui.keyCode.LEFT: - if ($elem.hasClass('open')) { + if ($elem.hasClass('show')) { this.on_expand_action(record); } break; case $.ui.keyCode.RIGHT: - if (!$elem.hasClass('open')) { + if (!$elem.hasClass('show')) { this.on_expand_action(record); } break; case $.ui.keyCode.UP: var $prev = $elem.prev('.o_export_tree_item'); if($prev.length === 1) { - while($prev.hasClass('open')) { + while($prev.hasClass('show')) { $prev = $prev.children('.o_export_tree_item').last(); } } else { @@ -104,7 +104,7 @@ var DataExport = Dialog.extend({ break; case $.ui.keyCode.DOWN: var $next; - if($elem.hasClass('open')) { + if($elem.hasClass('show')) { $next = $elem.children('.o_export_tree_item').first(); } else { $next = $elem.next('.o_export_tree_item'); @@ -408,7 +408,7 @@ var DataExport = Dialog.extend({ var self = this; if(expansion) { this.$('.o_export_tree_item[data-id="' + expansion + '"]') - .addClass('open') + .addClass('show') .find('.o_expand_parent') .toggleClass('fa-chevron-right fa-chevron-down') .next() @@ -429,8 +429,8 @@ var DataExport = Dialog.extend({ }, show_content: function(id) { var $this = this.$('.o_export_tree_item[data-id="' + id + '"]'); - $this.toggleClass('open'); - var is_open = $this.hasClass('open'); + $this.toggleClass('show'); + var is_open = $this.hasClass('show'); $this.children('.o_expand_parent').toggleClass('fa-chevron-down', !!is_open).toggleClass('fa-chevron-right', !is_open); @@ -441,8 +441,8 @@ var DataExport = Dialog.extend({ if(!is_open) { $child.hide(); } else if(child_len === $child_field.eq(i).data('id').split("/").length) { - if ($child.hasClass('open')) { - $child.removeClass('open'); + if ($child.hasClass('show')) { + $child.removeClass('show'); $child.children('.o_expand_parent').removeClass('fa-chevron-down').addClass('fa-chevron-right'); } $child.show(); diff --git a/addons/web/static/src/js/widgets/debug_manager.js b/addons/web/static/src/js/widgets/debug_manager.js index 4eee9266594..d553387f153 100644 --- a/addons/web/static/src/js/widgets/debug_manager.js +++ b/addons/web/static/src/js/widgets/debug_manager.js @@ -23,12 +23,12 @@ var DebugManager = Widget.extend({ template: "WebClient.DebugManager", events: { "click a[data-action]": "perform_callback", - "mouseover .o_debug_dropdowns > li:not(.open)": function(e) { + "mouseover .o_debug_dropdowns > li:not(.show)": function(e) { // Open other dropdowns on mouseover - var $opened = this.$('.o_debug_dropdowns > li.open'); + var $opened = this.$('.o_debug_dropdowns > li.show'); if($opened.length) { - $opened.removeClass('open'); - $(e.currentTarget).addClass('open').find('> a').focus(); + $opened.removeClass('show'); + $(e.currentTarget).addClass('show').find('> a').focus(); } }, }, diff --git a/addons/web/static/src/js/widgets/domain_selector.js b/addons/web/static/src/js/widgets/domain_selector.js index c5a561b1b77..dab0c97108b 100644 --- a/addons/web/static/src/js/widgets/domain_selector.js +++ b/addons/web/static/src/js/widgets/domain_selector.js @@ -161,7 +161,7 @@ var DomainNode = Widget.extend({ var DomainTree = DomainNode.extend({ template: "DomainTree", events: _.extend({}, DomainNode.prototype.events, { - "click .o_domain_tree_operator_selector > ul > li > a": "_onOperatorChange", + "click .o_domain_tree_operator_selector .dropdown-item": "_onOperatorChange", }), custom_events: { // If a domain child sends a request to add a child or remove one, call diff --git a/addons/web/static/src/js/widgets/dropdown_menu.js b/addons/web/static/src/js/widgets/dropdown_menu.js index 410d915dc9a..6f8f78a13d5 100644 --- a/addons/web/static/src/js/widgets/dropdown_menu.js +++ b/addons/web/static/src/js/widgets/dropdown_menu.js @@ -11,8 +11,8 @@ var QWeb = core.qweb; var DropdownMenu = Widget.extend({ template: 'web.DropdownMenu', events: { - 'click li.o_menu_item': '_onItemClick', - 'click li.o_item_option': '_onOptionClick', + 'click .o_menu_item': '_onItemClick', + 'click .o_item_option': '_onOptionClick', 'click span.o_trash_button': '_onTrashClick', 'hidden.bs.dropdown': '_onBootstrapClose', }, @@ -44,12 +44,12 @@ var DropdownMenu = Widget.extend({ this.dropdownCategory = dropdownHeader.category; this.dropdownTitle = dropdownHeader.title; this.dropdownIcon = dropdownHeader.icon; - this.dropdownSymbol = dropdownHeader.symbol || 'caret'; + this.dropdownSymbol = dropdownHeader.symbol || false; // this parameter fixes the menu style. By default, // the style used is the one used in the search view this.dropdownStyle = dropdownHeader.style || { el: {class: 'btn-group o_dropdown', attrs: {}}, - mainButton: {class: 'o_dropdown_toggler_btn btn btn-secondary dropdown-toggle'}, + mainButton: {class: 'o_dropdown_toggler_btn btn btn-secondary dropdown-toggle' + (this.dropdownSymbol ? ' o-no-caret' : '')}, }; this.items = items; _.each(this.items, this._prepareItem.bind(this)); @@ -105,8 +105,8 @@ var DropdownMenu = Widget.extend({ */ _renderMenuItems: function () { var newMenuItems = QWeb.render('DropdownMenu.MenuItems', {widget: this}); - this.$el.find('.o_menu_item,.divider[data-removable="1"]').remove(); - this.$('ul.o_dropdown_menu').prepend($(newMenuItems)); + this.$el.find('.o_menu_item, .dropdown-divider[data-removable="1"]').remove(); + this.$('.o_dropdown_menu').prepend($(newMenuItems)); }, /** * this function computes some default values for some of the item keys @@ -189,7 +189,7 @@ var DropdownMenu = Widget.extend({ * @param {jQueryEvent} event */ _onBootstrapClose: function () { - _.each(this.items, function(item) { + _.each(this.items, function (item) { item.isOpen = false; }); this._renderMenuItems(); diff --git a/addons/web/static/src/js/widgets/switch_company_menu.js b/addons/web/static/src/js/widgets/switch_company_menu.js index 01c224370d2..c9498950a04 100644 --- a/addons/web/static/src/js/widgets/switch_company_menu.js +++ b/addons/web/static/src/js/widgets/switch_company_menu.js @@ -18,7 +18,7 @@ var _t = core._t; var SwitchCompanyMenu = Widget.extend({ template: 'SwitchCompanyMenu', events: { - 'click .dropdown-menu li a[data-menu]': '_onClick', + 'click .dropdown-item[data-menu]': '_onClick', }, /** * @override @@ -53,8 +53,8 @@ var SwitchCompanyMenu = Widget.extend({ } else { a = '<span style="margin-right: 24px;"/>'; } - companiesList += '<li><a href="#" data-menu="company" data-company-id="' + - company[0] + '">' + a + company[1] + '</a></li>'; + companiesList += '<a href="#" class="dropdown-item" data-menu="company" data-company-id="' + + company[0] + '">' + a + company[1] + '</a>'; }); this.$('.dropdown-menu').html(companiesList); return this._super(); diff --git a/addons/web/static/src/scss/dropdown.scss b/addons/web/static/src/scss/dropdown.scss index 9a60d78d9d3..8287e098b32 100644 --- a/addons/web/static/src/scss/dropdown.scss +++ b/addons/web/static/src/scss/dropdown.scss @@ -5,7 +5,7 @@ .ui-autocomplete { // Copy style of bootstrap dropdown background-image: none; background-color: $dropdown-bg; - border: 1px solid $dropdown-border; + border: $dropdown-border-width solid $dropdown-border-color; font-size: $font-size-base; padding: 5px 0px; box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.176); @@ -41,7 +41,7 @@ .o_inline_dropdown { position: relative; - &> .dropdown-menu { + & > .dropdown-menu { top: 0; left: 100%; } @@ -52,9 +52,12 @@ } @mixin dropdown-menu-mixin { - .open .dropdown-menu > li { - position: relative; // to allow absolute positionning inside the li - > a { + .show .dropdown-menu { + > * { + position: relative; // to allow absolute positionning inside the items + } + + .dropdown-item { &:focus, &:active, &:focus:active { outline: none; } @@ -62,7 +65,7 @@ @extend %dropdown-li-a-padding; } - &.dropdown-header { + .dropdown-header { @extend %dropdown-li-a-padding; color: $o-main-text-color; diff --git a/addons/web/static/src/scss/dropdown_menu.scss b/addons/web/static/src/scss/dropdown_menu.scss index 8024783d3c2..8f5b0c1f00a 100644 --- a/addons/web/static/src/scss/dropdown_menu.scss +++ b/addons/web/static/src/scss/dropdown_menu.scss @@ -1,38 +1,23 @@ .o_dropdown_menu { - > li.divider:first-child { + > .dropdown-divider:first-child { display: none; } - max-height: calc(100vh - 125px); + max-height: calc(100vh - 125px); // FIXME overflow: auto; - .o_submenu_switcher { - float:right; - width: 25px; - text-align: center; - } - .o_trash_button { - float:right; - + .o_submenu_switcher { - margin-right: 6px; - } - } - ul { - list-style-type: none; - padding-left: 20px; - } - li.o_menu_item { + .o_menu_item { position: relative; - > a { + > .dropdown-item { color: $o-main-text-color; - padding-right: 25px; + &:hover { color: darken($o-main-text-color, 10%); } } &.selected { - > a { + > .dropdown-item { color: darken($o-main-text-color, 10%); font-weight: bold; &:before { @@ -43,7 +28,7 @@ } } } - li.divider:first-child { + .dropdown-divider:first-child { display: none; } .o_item_option { diff --git a/addons/web/static/src/scss/form_view.scss b/addons/web/static/src/scss/form_view.scss index f6537e8cd07..51c584c916e 100644 --- a/addons/web/static/src/scss/form_view.scss +++ b/addons/web/static/src/scss/form_view.scss @@ -274,7 +274,7 @@ padding: 5px 0 2px 0; min-width: 100px; - > li > .btn { + .dropdown-item.btn { min-width: 100%; margin-bottom: 3px; } diff --git a/addons/web/static/src/scss/kanban_view.scss b/addons/web/static/src/scss/kanban_view.scss index b377a93a0eb..bd595243d84 100644 --- a/addons/web/static/src/scss/kanban_view.scss +++ b/addons/web/static/src/scss/kanban_view.scss @@ -150,7 +150,7 @@ @include o-kanban-dropdown; margin: (-$o-kanban-inside-vgutter - 1px) (-$o-kanban-inside-hgutter - 1px) 0 0; } - &.open .dropdown-toggle { + &.show .dropdown-toggle { @include o-kanban-dropdown-open; } .dropdown-menu { @@ -159,7 +159,7 @@ } } - &:hover .o_dropdown_kanban, .o_dropdown_kanban.open { + &:hover .o_dropdown_kanban, .o_dropdown_kanban.show { visibility: visible; } @@ -342,7 +342,7 @@ margin-left: $o-kanban-inside-hgutter*2; } - &:hover .o_kanban_config, .o_kanban_config.open { + &:hover .o_kanban_config, .o_kanban_config.show { visibility: visible; margin-left: $o-kanban-inside-hgutter; } diff --git a/addons/web/static/src/scss/navbar.scss b/addons/web/static/src/scss/navbar.scss index 9a3f3d9a718..66a080cf1bd 100644 --- a/addons/web/static/src/scss/navbar.scss +++ b/addons/web/static/src/scss/navbar.scss @@ -86,7 +86,7 @@ width: $o-navbar-height; text-align: center; } - &.open > ul { + &.show > ul { padding: 0; > li { @@ -115,27 +115,23 @@ &.o_menu_systray { float: right; - .open .dropdown-menu { - left: auto; - right: 0; - } } } - .open .dropdown-menu { + .dropdown-menu.show { max-height: 90vh; // the dropdown should not overstep the viewport min-width: 100%; overflow: auto; margin-top: 0; @for $index from 3 through 5 { - > li.o_menu_header_lvl_#{$index}, > li .o_menu_entry_lvl_#{$index} { + .o_menu_header_lvl_#{$index}, .o_menu_entry_lvl_#{$index} { padding-left: $o-dropdown-hpadding + ($index - 2)*12px; } } } - .open .dropdown-toggle { + .show .dropdown-toggle { background-color: $o-navbar-inverse-link-hover-bg; } .o_user_menu { @@ -165,7 +161,7 @@ display: none; } - &.open .dropdown-menu { + .dropdown-menu.show { max-height: none; } } @@ -173,7 +169,7 @@ &.o_menu_sections { width: 100%; - > li.open .dropdown-menu { + .dropdown-menu.show { position: static; float: none; background-color: transparent; @@ -181,7 +177,7 @@ border: none; overflow: visible; - > li > a { + > .dropdown-item { background-color: transparent; color: inherit; } @@ -196,7 +192,7 @@ > li { display: inline-block; - &.open .dropdown-menu { + .dropdown-menu.show { @include o-position-absolute($o-navbar-height, 0, 0, 0); position: fixed; width: auto; @@ -225,10 +221,10 @@ } @include media-breakpoint-down(md) { - .o_switch_company_menu > .dropdown-menu { - padding-top: 0px; - li.bg-info { - padding: 10px; - } - } - } + .o_switch_company_menu > .dropdown-menu { + padding-top: 0px; + .bg-info { + padding: 10px; + } + } +} diff --git a/addons/web/static/src/scss/search_groupby_menu.scss b/addons/web/static/src/scss/search_groupby_menu.scss deleted file mode 100644 index 4092b4b5fb7..00000000000 --- a/addons/web/static/src/scss/search_groupby_menu.scss +++ /dev/null @@ -1,16 +0,0 @@ -// Group By -.o_group_by_menu { - @include o-selected-li; - - max-height: calc(100vh - 125px); - overflow: auto; - - .o_add_group { // add button - @include o-search-options-dropdown-custom-li; - } - - .o_submenu_switcher { - position: absolute; - right: 0px; - } -} diff --git a/addons/web/static/src/scss/search_view.scss b/addons/web/static/src/scss/search_view.scss index 0ad27f5c391..700c13f7e84 100644 --- a/addons/web/static/src/scss/search_view.scss +++ b/addons/web/static/src/scss/search_view.scss @@ -1,5 +1,4 @@ -@mixin o-search-options-dropdown-custom-li { - margin: 3px 25px; +@mixin o-search-options-dropdown-custom-item { width: auto; max-width: 250px; } @@ -116,7 +115,7 @@ color: darken($o-main-text-color, 10%); } } - &.open > a { + &.show > a { font-weight: bold; color: darken($o-main-text-color, 10%); } @@ -130,7 +129,7 @@ a:before { @include o-caret-right; @include o-position-absolute($top: 50%, $left: 10px); - margin-top: (-$caret-width-base); + margin-top: (-$caret-width); } } .o_open_menu { @@ -138,7 +137,7 @@ a:before { @include o-caret-down; @include o-position-absolute($top: 50%, $left: 10px); - margin-top: (-$caret-width-base); + margin-top: (-$caret-width); } } @@ -150,7 +149,7 @@ overflow: auto; .o_filter_condition { - @include o-search-options-dropdown-custom-li; + @include o-search-options-dropdown-custom-item; margin-bottom: 8px; .o_or_filter { // or between conditions display: none; // hidden for the first condition @@ -177,7 +176,7 @@ } .o_add_filter_menu { // apply and add buttons display: none; // Needed by the webclient - @include o-search-options-dropdown-custom-li; + @include o-search-options-dropdown-custom-item; } .o_submenu_switcher { position: absolute; @@ -196,7 +195,7 @@ max-height: calc(100vh - 125px); overflow: auto; - .divider {display: none;} // hide the divider by default (no favorite) + .dropdown-divider {display: none;} // hide the divider by default (no favorite) .o-searchview-custom-private, .o-searchview-custom-public { .o-remove-filter { @include o-position-absolute(50%, 12px); @@ -212,6 +211,6 @@ } .o_save_name { // save button display: none; // hidden by default - @include o-search-options-dropdown-custom-li; + @include o-search-options-dropdown-custom-item; } } diff --git a/addons/web/static/src/scss/ui.scss b/addons/web/static/src/scss/ui.scss index d88f21f83a1..e30a3d59d20 100644 --- a/addons/web/static/src/scss/ui.scss +++ b/addons/web/static/src/scss/ui.scss @@ -13,3 +13,9 @@ [aria-hidden="true"], [aria-hidden="1"] { display: none!important; } + +.dropdown-toggle.o-no-caret { + &::before, &::after { + content: normal; + } +} diff --git a/addons/web/static/src/scss/utils.scss b/addons/web/static/src/scss/utils.scss index 4b76f10b1d2..a01ba14f5a4 100644 --- a/addons/web/static/src/scss/utils.scss +++ b/addons/web/static/src/scss/utils.scss @@ -72,7 +72,7 @@ // ------------------------------------------------------------------ // Caret // ------------------------------------------------------------------ -@mixin o-caret-down($caret-width: $caret-width-base) { +@mixin o-caret-down($caret-width: $caret-width) { @include utils-caret-boilerplate; border-bottom: 0; border-left: $caret-width solid transparent; @@ -80,7 +80,7 @@ border-top: $caret-width solid; -moz-transform: scale(0.9999); // Smooth the caret on firefox } -@mixin o-caret-up($caret-width: $caret-width-base) { +@mixin o-caret-up($caret-width: $caret-width) { @include utils-caret-boilerplate; border-bottom: $caret-width solid; border-left: $caret-width solid transparent; @@ -88,7 +88,7 @@ border-top: 0; -moz-transform: scale(0.9999); // Smooth the caret on firefox } -@mixin o-caret-left($caret-width: $caret-width-base) { +@mixin o-caret-left($caret-width: $caret-width) { @include utils-caret-boilerplate; border-bottom: $caret-width solid transparent; border-left: 0; @@ -96,7 +96,7 @@ border-top: $caret-width solid transparent; -moz-transform: scale(0.9999); // Smooth the caret on firefox } -@mixin o-caret-right($caret-width: $caret-width-base) { +@mixin o-caret-right($caret-width: $caret-width) { @include utils-caret-boilerplate; border-bottom: $caret-width solid transparent; border-left: $caret-width solid; @@ -108,25 +108,22 @@ // ------------------------------------------------------------------ // Dropdowns // ------------------------------------------------------------------ -@mixin o-selected-li { - li { +@mixin o-selected-li { // FIXME use active ? + .dropdown-item { position: relative; - > a { - color: $o-main-text-color; - &:hover { - color: darken($o-main-text-color, 10%); - } + color: $o-main-text-color; + &:hover { + color: darken($o-main-text-color, 10%); } + &.selected { - > a { - color: darken($o-main-text-color, 10%); - font-weight: bold; - &:before { - font-family: FontAwesome; - position: absolute; - left: 6px; - content: "\f00c"; - } + color: darken($o-main-text-color, 10%); + font-weight: bold; + &:before { + font-family: FontAwesome; + position: absolute; + left: 6px; + content: "\f00c"; } } } diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 376aeb58e41..1eaa2e59b84 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -231,31 +231,31 @@ <a href="#" title="Open Developer Tools" aria-label="Open Developer Tools" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false" tabindex="-1"> <span class="fa fa-bug"/> </a> - <ul class="dropdown-menu o_debug_dropdown" role="menu"/> + <div class="dropdown-menu dropdown-menu-right o_debug_dropdown" role="menu"/> </li> </t> <t t-name="WebClient.DebugManager.Global"> - <li><a role="menuitem" href="#" data-action="perform_js_tests">Run JS Tests</a></li> - <li><a role="menuitem" href="#" data-action="perform_js_mobile_tests">Run JS Mobile Tests</a></li> - <li><a role="menuitem" href="#" data-action="select_view">Open View</a></li> + <a role="menuitem" href="#" data-action="perform_js_tests" class="dropdown-item">Run JS Tests</a> + <a role="menuitem" href="#" data-action="perform_js_mobile_tests" class="dropdown-item">Run JS Mobile Tests</a> + <a role="menuitem" href="#" data-action="select_view" class="dropdown-item">Open View</a> <t t-if="manager._events"> - <li class="divider" role="separator"/> - <li><a role="menuitem" href="#" data-action="show_timelines">Toggle Timelines</a></li> - <li><a role="menuitem" href="#" data-action="requests_clear">Clear Events</a></li> + <div class="dropdown-divider" role="separator"/> + <a role="menuitem" href="#" data-action="show_timelines" class="dropdown-item">Toggle Timelines</a> + <a role="menuitem" href="#" data-action="requests_clear" class="dropdown-item">Clear Events</a> </t> - <li class="divider o_debug_leave_section" role="separator"/> - <li><a role="menuitem" href="#" data-action="split_assets">Activate Assets Debugging</a></li> - <li><a role="menuitem" href="#" data-action="regenerateAssets">Regenerate Assets Bundles</a></li> - <li><a role="menuitem" href="#" data-action="leave_debug_mode">Leave the Developer Tools</a></li> + <div class="dropdown-divider o_debug_leave_section" role="separator"/> + <a role="menuitem" href="#" data-action="split_assets" class="dropdown-item">Activate Assets Debugging</a> + <a role="menuitem" href="#" data-action="regenerateAssets" class="dropdown-item">Regenerate Assets Bundles</a> + <a role="menuitem" href="#" data-action="leave_debug_mode" class="dropdown-item">Leave the Developer Tools</a> </t> <t t-name="WebClient.DebugManager.Action"> <t t-if="action"> - <li class="divider" role="separator"/> - <li><a role="menuitem" href="#" data-action="edit" t-att-data-model="action.type" t-att-data-id="action.id">Edit Action</a></li> + <div class="dropdown-divider" role="separator"/> + <a role="menuitem" href="#" data-action="edit" t-att-data-model="action.type" t-att-data-id="action.id" class="dropdown-item">Edit Action</a> <t t-if="action.res_model"> - <li><a role="menuitem" href="#" data-action="get_view_fields">View Fields</a></li> - <li><a role="menuitem" href="#" data-action="manage_filters">Manage Filters</a></li> - <li><a role="menuitem" href="#" data-action="translate">Technical Translation</a></li> + <a role="menuitem" href="#" data-action="get_view_fields" class="dropdown-item">View Fields</a> + <a role="menuitem" href="#" data-action="manage_filters" class="dropdown-item">Manage Filters</a> + <a role="menuitem" href="#" data-action="translate" class="dropdown-item">Technical Translation</a> </t> </t> </t> @@ -272,21 +272,19 @@ </t> <t t-name="WebClient.DebugManager.View"> <t t-if="view"> - <li role="separator" class="divider"/> + <div role="separator" class="dropdown-divider"/> <t t-if="view.type === 'form'"> - <li><a role="menuitem" href="#" data-action="set_defaults">Set Defaults</a></li> + <a role="menuitem" href="#" data-action="set_defaults" class="dropdown-item">Set Defaults</a> <t t-if="controller.getSelectedIds().length === 1"> - <li><a role="menuitem" href="#" data-action="get_metadata">View Metadata</a></li> + <a role="menuitem" href="#" data-action="get_metadata" class="dropdown-item">View Metadata</a> </t> </t> - <li><a role="menuitem" href="#" data-action="fvg">Fields View Get</a></li> + <a role="menuitem" href="#" data-action="fvg" class="dropdown-item">Fields View Get</a> <t t-if="can_edit"> - <li> - <a role="menuitem" href="#" data-action="edit" data-model="ir.ui.view" t-att-data-id="view.fieldsView.view_id"> + <a role="menuitem" href="#" data-action="edit" data-model="ir.ui.view" t-att-data-id="view.fieldsView.view_id" class="dropdown-item"> Edit View: <t t-esc="_.str.capitalize(view.type)"/> - </a> - </li> - <li t-if="searchview and searchview.$el.is(':visible')"><a role="menuitem" href="#" data-action="edit" data-model="ir.ui.view" t-att-data-id="action.searchFieldsView.view_id">Edit SearchView</a></li> + </a> + <a t-if="searchview and searchview.$el.is(':visible')" role="menuitem" href="#" data-action="edit" data-model="ir.ui.view" t-att-data-id="action.searchFieldsView.view_id" class="dropdown-item">Edit SearchView</a> </t> </t> </t> @@ -344,15 +342,15 @@ <div class="btn-group o_dropdown"> <button t-if="section.name != 'buttons'" class="o_dropdown_toggler_btn btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> <t t-if="section.name == 'files'" t-raw="widget.items[section.name].length || ''"/> - <t t-esc="section.label"/> <span class="caret"/> + <t t-esc="section.label"/> </button> <t t-if="section.name == 'buttons'" t-foreach="widget.items[section.name]" t-as="item" t-att-class="item.classname"> <a t-att-title="item.title or None" t-att-data-section="section.name" t-att-data-index="item_index" t-att-href="item.url or '#'" target="_blank"> <t t-raw="item.label"/> </a> </t> - <ul class="dropdown-menu" role="menu"> - <li role="menuitem" t-foreach="widget.items[section.name]" t-as="item" t-att-class="item.classname"> + <div class="dropdown-menu" role="menu"> + <t t-foreach="widget.items[section.name]" t-as="item"> <t t-if="section.name == 'files'"> <t t-set="item.title"> <b>Attachment : </b><br/> @@ -369,12 +367,12 @@ <t t-raw="item.write_uid[1]"/> <t t-esc="item.write_date_string"/> </t> </t> - <a t-att-title="item.title or None" t-att-data-section="section.name" t-att-data-index="item_index" t-att-href="item.url or '#'"> + <a t-attf-class="dropdown-item #{item.classname}" role="menuitem" t-att-title="item.title or None" t-att-data-section="section.name" t-att-data-index="item_index" t-att-href="item.url or '#'"> <t t-raw="item.label"/> <span t-if="section.name == 'files' and widget.options.editable and !item.callback" class="fa fa-trash-o o_sidebar_delete_attachment" t-att-data-id="item.id" title="Delete this attachment" role="img" aria-label="Delete this attachment"/> </a> - </li> - <li role="menuitem" t-if="section.name == 'files' and widget.options.editable" class="o_sidebar_add_attachment"> + </t> + <div role="menuitem" t-if="section.name == 'files' and widget.options.editable" class="dropdown-item o_sidebar_add_attachment"> <t t-call="HiddenInputFile"> <t t-set="fileupload_id" t-value="widget.fileuploadId"/> <t t-set="fileupload_action" t-translation="off">/web/binary/upload_attachment</t> @@ -384,8 +382,8 @@ <input type="hidden" name="session_id" t-att-value="widget.getSession().session_id" t-if="widget.getSession().override_session"/> <span>Add...</span> </t> - </li> - </ul> + </div> + </div> </div> </t> </t> @@ -511,15 +509,15 @@ <t t-name="GraphView.buttons"> <div class="btn-group" role="toolbar" aria-label="Main actions"> <button class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> - Measures <span class="caret"/> + Measures </button> - <ul class="dropdown-menu o_graph_measures_list" role="menu"> - <li t-foreach="measures" t-as="measure" t-att-data-field="measure[0]"> - <a role="menuitem" href="#"><t t-esc="measure[1].string"/><t t-if="measure[1].type === 'many2one'"> (count)</t></a> - </li> - <li role="separator" class="divider"></li> - <li data-field="__count__"><a role="menuitem" href="#">Count</a></li> - </ul> + <div class="dropdown-menu o_graph_measures_list" role="menu"> + <t t-foreach="measures" t-as="measure"> + <a role="menuitem" href="#" class="dropdown-item" t-att-data-field="measure[0]"><t t-esc="measure[1].string"/><t t-if="measure[1].type === 'many2one'"> (count)</t></a> + </t> + <div role="separator" class="dropdown-divider"/> + <a role="menuitem" href="#" class="dropdown-item" data-field="__count__">Count</a> + </div> </div> <div class="btn-group" role="toolbar" aria-label="Change graph"> <button class="btn btn-secondary fa fa-bar-chart-o o_graph_button" title="Bar Chart" aria-label="Bar Chart" data-mode="bar"/> @@ -540,15 +538,15 @@ <t t-name="PivotView.buttons"> <div class="btn-group" role="toolbar" aria-label="Main actions"> <button class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> - Measures <span class="caret"/> + Measures </button> - <ul class="dropdown-menu o_pivot_measures_list" role="menu"> - <li t-foreach="measures" t-as="measure" t-att-data-field="measure[0]"> - <a role="menuitem" href="#"><t t-esc="measure[1].string"/><t t-if="measure[1].type === 'many2one'"> (count)</t></a> - </li> - <li role="separator" class="divider"></li> - <li data-field="__count"><a role="menuitem" href="#">Count</a></li> - </ul> + <div class="dropdown-menu o_pivot_measures_list" role="menu"> + <t t-foreach="measures" t-as="measure"> + <a role="menuitem" href="#" class="dropdown-item" t-att-data-field="measure[0]"><t t-esc="measure[1].string"/><t t-if="measure[1].type === 'many2one'"> (count)</t></a> + </t> + <div role="separator" class="dropdown-divider"/> + <a role="menuitem" href="#" class="dropdown-item" data-field="__count">Count</a> + </div> </div> <div class="btn-group" role="toolbar" aria-label="Pivot settings"> <button class="btn btn-secondary fa fa-expand o_pivot_flip_button" title="Flip axis" aria-label="Flip axis"/> @@ -557,29 +555,27 @@ </div> </t> <t t-name="PivotView.FieldSelection"> - <ul class="dropdown-menu o_pivot_field_menu" role="menu"> + <div class="dropdown-menu o_pivot_field_menu" role="menu"> <t t-foreach="fields" t-as="field"> <t t-if="(field[1].type === 'date') || (field[1].type === 'datetime')"> - <li role="menuitem" aria-haspopup="true" t-att-data-field="field[0]" t-attf-class="o_inline_dropdown#{field[2] ? ' disabled' : ''}"> - <a href="#" class="o_pivot_field_selection"> + <div role="menuitem" aria-haspopup="true" class="o_inline_dropdown"> + <a href="#" t-att-data-field="field[0]" t-attf-class="dropdown-item o_pivot_field_selection#{field[2] ? ' disabled' : ''}"> <t t-esc="field[1].string"/> </a> - <ul class="dropdown-menu" role="menu"> - <li t-att-data-field="field[0]"><a role="menuitem" href="#" t-att-data-interval="'day'">Day</a></li> - <li t-att-data-field="field[0]"><a role="menuitem" href="#" t-att-data-interval="'week'">Week</a></li> - <li t-att-data-field="field[0]"><a role="menuitem" href="#" t-att-data-interval="'month'">Month</a></li> - <li t-att-data-field="field[0]"><a role="menuitem" href="#" t-att-data-interval="'quarter'">Quarter</a></li> - <li t-att-data-field="field[0]"><a role="menuitem" href="#" t-att-data-interval="'year'">Year</a></li> - </ul> - </li> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" href="#" class="dropdown-item" t-att-data-interval="'day'" t-att-data-field="field[0]">Day</a> + <a role="menuitem" href="#" class="dropdown-item" t-att-data-interval="'week'" t-att-data-field="field[0]">Week</a> + <a role="menuitem" href="#" class="dropdown-item" t-att-data-interval="'month'" t-att-data-field="field[0]">Month</a> + <a role="menuitem" href="#" class="dropdown-item" t-att-data-interval="'quarter'" t-att-data-field="field[0]">Quarter</a> + <a role="menuitem" href="#" class="dropdown-item" t-att-data-interval="'year'" t-att-data-field="field[0]">Year</a> + </div> + </div> </t> <t t-else=""> - <li t-att-data-field="field[0]" t-att-class="(field[2] ? 'disabled' : '')"> - <a role="menuitem" href="#"><t t-esc="field[1].string"/></a> - </li> + <a href="#" role="menuitem" t-att-data-field="field[0]" t-attf-class="dropdown-item#{field[2] ? ' disabled' : ''}"><t t-esc="field[1].string"/></a> </t> </t> - </ul> + </div> </t> <div t-name="PivotView.nodata"> <div class="o_view_nocontent" role="alert"> @@ -597,17 +593,16 @@ <t t-name="FormSelection"> <div class="btn-group o_selection" aria-atomic="true"> <a href="#" data-toggle="dropdown" aria-label="Dropdown menu" title="Dropdown menu"><span class="o_status"/></a> - <ul class="dropdown-menu state" role="menu"> - </ul> + <div class="dropdown-menu state" role="menu"/> </div> </t> <t t-name="FormSelection.items"> - <li t-foreach="states" t-as="rec" t-att-data-value="rec.name"> - <a role="menuitem" href="#"> + <t t-foreach="states" t-as="rec"> + <a role="menuitem" href="#" class="dropdown-item" t-att-data-value="rec.name"> <span t-att-class="'o_status ' + (rec.state_class && rec.state_class || '')"/> <t t-raw="rec.state_name"/> </a> - </li> + </t> </t> <t t-name="FieldDomain.content"> <div t-if="hasModel" class="o_field_domain_panel"> @@ -636,10 +631,10 @@ <t t-if="widget.operator === '|'">Any</t> <t t-if="widget.operator === '!'">None</t> </button> - <ul class="dropdown-menu" role="menu"> - <li><a role="menuitem" href="#" data-operator="&">All</a></li> - <li><a role="menuitem" href="#" data-operator="|">Any</a></li> - </ul> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" href="#" class="dropdown-item" data-operator="&">All</a> + <a role="menuitem" href="#" class="dropdown-item" data-operator="|">Any</a> + </div> </div> <strong t-else=""> <t t-if="widget.operator === '&'">ALL</t> @@ -901,12 +896,12 @@ </t> <t t-name="FieldStatus.content"> <t t-if="selection_folded.length"> - <button type="button" class="btn o_arrow_button btn-secondary dropdown-toggle" data-toggle="dropdown" aria-expanded="false">More <span class="caret"/></button> - <ul class="dropdown-menu o-status-more" role="menu"> - <li t-foreach="selection_folded" t-as="i"> + <button type="button" class="btn o_arrow_button btn-secondary dropdown-toggle" data-toggle="dropdown" aria-expanded="false">More</button> + <div class="dropdown-menu o-status-more" role="menu"> + <t t-foreach="selection_folded" t-as="i"> <t t-call="FieldStatus.content.button"/> - </li> - </ul> + </t> + </div> </t> <t t-foreach="selection_unfolded.reverse()" t-as="i"> <t t-call="FieldStatus.content.button"/> @@ -1069,71 +1064,67 @@ <t t-if="widget.items.length !== 0"> <t t-set="group" t-value="0"/> <t t-foreach="widget.items" t-as="item"> - <li t-if="group !== item.groupId" class="divider" data-removable="1"/> - <li t-att-class="'o_menu_item ' + (item.isActive ? 'selected ' : '')" + <div t-if="group !== item.groupId" class="dropdown-divider" data-removable="1"/> + <div t-attf-class="o_menu_item#{item.isActive ? ' selected ' : ''}" t-att-data-id="item.itemId"> - <a href="#"> + <a href="#" class="dropdown-item"> <t t-esc="item.description"/> <span t-if="item.isRemovable" t-att-data-id="item.itemId" class="o_trash_button" > <span class="fa fa-trash-o"></span> </span> <span t-if="item.hasOptions" t-att-data-id="item.itemId" class="o_submenu_switcher"> <span t-att-class="item.isOpen ? 'fa fa-caret-down' : 'fa fa-caret-right'"></span> </span> </a> - <ul t-if="item.hasOptions && item.isOpen"> + <ul t-if="item.hasOptions && item.isOpen" class="list-unstyled"> <t t-set="subgroup" t-value="0"/> <t t-foreach="_.values(item.options)" t-as="option"> - <li t-if="subgroup !== option.groupId" class="divider" data-removable="1"/> - <li t-att-class="'o_item_option ' + (item.currentOptionId === option.optionId ? 'selected': '')" + <li t-if="subgroup !== option.groupId" class="dropdown-divider" data-removable="1"/> + <li t-attf-class="o_item_option#{item.currentOptionId === option.optionId ? ' selected': ''}" t-att-data-item_id="item.itemId" t-att-data-option_id="option.optionId"> - <a href="#"><t t-esc="option.description"/></a> + <a href="#" class="dropdown-item pl-5"><t t-esc="option.description"/></a> </li> <t t-set="subgroup" t-value="option.groupId"/> </t> </ul> - </li> + </div> <t t-set="group" t-value="item.groupId"/> </t> </t> </t> -<div t-name="web.DropdownMenu" t-att-class="widget.dropdownStyle.el.class" t-att="widget.dropdownStyle.el.attrs" > +<div t-name="web.DropdownMenu" t-att-class="widget.dropdownStyle.el.class" t-att="widget.dropdownStyle.el.attrs"> <button t-att-class="widget.dropdownStyle.mainButton.class" data-toggle="dropdown" aria-expanded="false" tabindex="-1"> - <span t-att-class="widget.dropdownIcon"/> <t t-esc="widget.dropdownTitle"/> <span t-att-class="widget.dropdownSymbol"/> + <span t-att-class="widget.dropdownIcon"/> <t t-esc="widget.dropdownTitle"/> <span t-if="widget.dropdownSymbol" t-att-class="widget.dropdownSymbol"/> </button> - <ul class="dropdown-menu o_dropdown_menu" role="menu"> + <div class="dropdown-menu o_dropdown_menu" role="menu"> <t t-call="DropdownMenu.MenuItems"/> - </ul> + </div> </div> <t t-name="GroupbyMenuGenerator"> - <li t-if="Object.keys(widget.presentedFields).length !== 0 && widget.items.length !== 0" class="o_generator_menu divider"/> - <li t-if="Object.keys(widget.presentedFields).length !== 0" class="o_generator_menu o_add_custom_group "> - <a href="#">Add Custom Group</a> - </li> - <li t-if="widget.generatorMenuIsOpen" class="o_generator_menu"> - <select class="o_input o_group_selector o_add_group"> + <div t-if="Object.keys(widget.presentedFields).length !== 0 && widget.items.length !== 0" class="dropdown-divider o_generator_menu"/> + <button t-if="Object.keys(widget.presentedFields).length !== 0" type="button" class="dropdown-item o_generator_menu o_add_custom_group">Add Custom Group</button> + <div t-if="widget.generatorMenuIsOpen" class="dropdown-item-text o_generator_menu"> + <select class="w-auto o_input o_group_selector o_add_group"> <t t-foreach="widget.presentedFields" t-as="field"> <option t-att-value="field.name"><t t-esc="field.string"/></option> </t> </select> - </li> - <li t-if="widget.generatorMenuIsOpen" class="o_generator_menu"> + </div> + <div t-if="widget.generatorMenuIsOpen" class="dropdown-item-text o_generator_menu"> <button type="button" class="btn btn-primary o_apply_group o_add_group" tabindex="-1">Apply</button> - </li> + </div> </t> <t t-name="FiltersMenuGenerator"> - <li class="divider"/> - <li t-if="Object.keys(widget.fields).length !== 0" class="o_add_custom_filter o_closed_menu"> - <a href="#">Add Custom Filter</a> - </li> - <li class="o_add_filter_menu"> + <div class="dropdown-divider"/> + <button t-if="Object.keys(widget.fields).length !== 0" type="button" class="dropdown-item o_add_custom_filter o_closed_menu">Add Custom Filter</button> + <div class="dropdown-item-text o_add_filter_menu"> <button class="btn btn-primary o_apply_filter" type="button">Apply</button> <button class="btn btn-secondary o_add_condition" type="button"> <span class="fa fa-plus-circle"/> Add a condition </button> - </li> + </div> </t> @@ -1173,15 +1164,20 @@ <t t-esc="widget.model.get('label') + (widget.optionLabel ? (': ' + widget.optionLabel) : '')"/> </span> <t t-name="SearchView.autocomplete"> - <ul class="dropdown-menu o_searchview_autocomplete" role="menu"></ul> + <div class="dropdown-menu o_searchview_autocomplete" role="menu"/> </t> <t t-name="SearchView.filters"> - <li t-foreach="widget.filters" t-as="filter" t-if="!filter.visible || filter.visible()" - t-att-title="filter.attrs.string ? filter.attrs.help : undefined" - t-att-data-index="filter_index"> - <a role="menuitem" href="#"><t t-esc="filter.attrs.string or filter.attrs.help or filter.attrs.name or 'Ω'"/></a> - </li> + <t t-foreach="widget.filters" t-as="filter"> + <a t-if="!filter.visible || filter.visible()" + href="#" + class="dropdown-item" + t-att-title="filter.attrs.string ? filter.attrs.help : undefined" + t-att-data-index="filter_index" + role="menuitem"> + <t t-esc="filter.attrs.string or filter.attrs.help or filter.attrs.name or 'Ω'"/> + </a> + </t> </t> <t t-name="SearchView.field"> <label t-att-class="'oe_label' + (attrs.help ? '_help' : '')" @@ -1243,7 +1239,7 @@ </div> </t> <t t-name="SearchView.extended_search.proposition"> - <li role="menuitem" class="o_filter_condition"> + <div role="menuitem" class="dropdown-item-text o_filter_condition"> <span class="o_or_filter">or</span> <span> <select class="o_input o_searchview_extended_prop_field"> @@ -1258,7 +1254,7 @@ </span> <select class="o_input o_searchview_extended_prop_op"/> <span class="o_searchview_extended_prop_value"/> - </li> + </div> </t> <t t-name="SearchView.extended_search.proposition.float"> <input class="o_input" @@ -1276,28 +1272,26 @@ </t> <div t-name="SearchView.FavoriteMenu" class="btn-group o_dropdown"> - <button class="o_dropdown_toggler_btn btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-expanded="false" tabindex="-1" aria-label="Favorites" title="Favorites"> - <span class="fa fa-star"/> Favorites <span t-attf-class="#{widget.isMobile ? 'fa fa-chevron-right pull-right mt4' : 'caret'}"/> + <button t-attf-class="o_dropdown_toggler_btn btn btn-secondary dropdown-toggle#{widget.isMobile ? ' o-no-caret' : ''}" data-toggle="dropdown" aria-expanded="false" tabindex="-1" aria-label="Favorites" title="Favorites"> + <span class="fa fa-star"/> Favorites <span t-if="widget.isMobile" class="fa fa-chevron-right pull-right mt4"/> </button> - <ul class="dropdown-menu o_favorites_menu" role="menu"> - <li class="divider user_filter"/> - <li class="divider shared_filter"/> - <li class="o_save_search o_closed_menu"> - <a role="menuitem" href="#">Save current search</a> - </li> - <li role="menuitem" class="o_save_name"> - <input type="text"></input> - </li> - <li role="menuitem" class="o_save_name"> + <div class="dropdown-menu o_favorites_menu" role="menu"> + <div class="dropdown-divider user_filter"/> + <div class="dropdown-divider shared_filter"/> + <a role="menuitem" href="#" class="dropdown-item o_save_search o_closed_menu">Save current search</a> + <div role="menuitem" class="dropdown-item-text o_save_name"> + <input type="text" class="o_input"></input> + </div> + <div role="menuitem" class="dropdown-item-text o_save_name"> <span><div class="o_checkbox"><input type="checkbox"/><span/></div> Use by default</span> - </li> - <li role="menuitem" class="o_save_name"> + </div> + <div role="menuitem" class="dropdown-item-text o_save_name"> <span><div class="o_checkbox"><input type="checkbox"/><span/></div> Share with all users </span><span class="fa fa-users" role="img" aria-label="Users" title="Users"/> - </li> - <li class="o_save_name"> + </div> + <div class="dropdown-item-text o_save_name"> <button role="menuitem" type="button" class="btn btn-primary">Save</button> - </li> - </ul> + </div> + </div> </div> <div t-name="ExportDialog" class="o_export"> @@ -1460,27 +1454,27 @@ <img class="img-circle oe_topbar_avatar" t-att-src="_s + '/web/static/src/img/user_menu_avatar.png'" alt="Avatar"/> <span class="oe_topbar_name"/> </a> - <ul class="dropdown-menu" role="menu"> + <div class="dropdown-menu dropdown-menu-right" role="menu"> <t t-call="UserMenu.Actions"/> - </ul> + </div> </li> </t> <t t-name="UserMenu.Actions"> - <li><a role="menuitem" href="#" data-menu="documentation">Documentation</a></li> - <li><a role="menuitem" href="#" data-menu="support">Support</a></li> - <li role="separator" class="divider"/> - <li><a role="menuitem" href="#" data-menu="settings">Preferences</a></li> - <li><a role="menuitem" href="#" data-menu="account">My Odoo.com account</a></li> - <li><a role="menuitem" href="#" data-menu="logout">Log out</a></li> + <a role="menuitem" href="#" data-menu="documentation" class="dropdown-item">Documentation</a> + <a role="menuitem" href="#" data-menu="support" class="dropdown-item">Support</a> + <div role="separator" class="dropdown-divider"/> + <a role="menuitem" href="#" data-menu="settings" class="dropdown-item">Preferences</a> + <a role="menuitem" href="#" data-menu="account" class="dropdown-item">My Odoo.com account</a> + <a role="menuitem" href="#" data-menu="logout" class="dropdown-item">Log out</a> </t> <t t-name="SwitchCompanyMenu"> <li class="o_switch_company_menu"> <a class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false" href="#" aria-label="Dropdown menu" title="Dropdown menu"> - <span t-attf-class="#{widget.isMobile ? 'fa fa-building-o' : 'oe_topbar_name'}"/> <span class="caret"/> + <span t-attf-class="#{widget.isMobile ? 'fa fa-building-o' : 'oe_topbar_name'}"/> </a> - <ul class="dropdown-menu" role="menu"/> + <div class="dropdown-menu dropdown-menu-right" role="menu"/> </li> </t> diff --git a/addons/web/static/src/xml/kanban.xml b/addons/web/static/src/xml/kanban.xml index a6d5ecc4ff4..4fc71cd6074 100644 --- a/addons/web/static/src/xml/kanban.xml +++ b/addons/web/static/src/xml/kanban.xml @@ -16,18 +16,18 @@ <span t-attf-id="#kanban_header_#{widget.id or widget.db_id}" class="o_column_title"><t t-esc="widget.title"/></span> <span class="o_column_unfold"><i class="fa fa-arrows-h" role="img" aria-label="Unfold" title="Unfold"/></span> <span class="o_kanban_config dropdown"> - <a class="dropdown-toggle" data-toggle="dropdown" href="#"><i class="fa fa-gear" role="img" aria-label="Settings" title="Settings"/></a> - <ul class="dropdown-menu" role="menu"> - <li><a role="menuitem" class="o_kanban_toggle_fold" href="#">Fold</a></li> + <a class="dropdown-toggle o-no-caret" data-toggle="dropdown" href="#"><i class="fa fa-gear" role="img" aria-label="Settings" title="Settings"/></a> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" class="dropdown-item o_kanban_toggle_fold" href="#">Fold</a> <t t-if="widget.grouped_by_m2o"> - <li t-if="widget.editable and widget.id"><a role="menuitem" class="o_column_edit" href="#">Edit Stage</a></li> - <li t-if="widget.deletable and widget.id"><a role="menuitem" class="o_column_delete" href="#">Delete</a></li> + <a t-if="widget.editable and widget.id" role="menuitem" class="dropdown-item o_column_edit" href="#">Edit Stage</a> + <a t-if="widget.deletable and widget.id" role="menuitem" class="dropdown-item o_column_delete" href="#">Delete</a> </t> <t t-if="widget.has_active_field"> - <li><a class="o_column_archive_records" href="#">Archive All</a></li> - <li><a class="o_column_unarchive_records" href="#">Unarchive All</a></li> + <a href="#" class="dropdown-item o_column_archive_records">Archive All</a> + <a href="#" class="dropdown-item o_column_unarchive_records">Unarchive All</a> </t> - </ul> + </div> </span> <span t-if="widget.quick_create" class="o_kanban_quick_add"><i class="fa fa-plus" role="img" aria-label="Quick add" title="Quick add"/></span> </div> diff --git a/addons/web/static/tests/fields/basic_fields_tests.js b/addons/web/static/tests/fields/basic_fields_tests.js index ffb0f6198d5..a2224193bab 100644 --- a/addons/web/static/tests/fields/basic_fields_tests.js +++ b/addons/web/static/tests/fields/basic_fields_tests.js @@ -3698,19 +3698,19 @@ QUnit.module('basic_fields', { "should have one red status since selection is the second, blocked state"); assert.strictEqual(form.$('.o_field_widget.o_selection > a span.o_status.o_status_green').length, 0, "should not have one green status since selection is the second, blocked state"); - assert.strictEqual(form.$('ul.dropdown-menu.state:visible').length, 0, + assert.strictEqual(form.$('.dropdown-menu.state:visible').length, 0, "there should not be a dropdown"); // Click on the status button to make the dropdown appear form.$('.o_field_widget.o_selection .o_status').first().click(); - assert.strictEqual(form.$('ul.dropdown-menu.state:visible').length, 1, + assert.strictEqual(form.$('.dropdown-menu.state:visible').length, 1, "there should be a dropdown"); - assert.strictEqual(form.$('ul.dropdown-menu.state:visible li').length, 2, + assert.strictEqual(form.$('.dropdown-menu.state:visible .dropdown-item').length, 2, "there should be two options in the dropdown"); // Click on the first option, "Normal" - form.$('ul.dropdown-menu.state:visible li').first().click(); - assert.strictEqual(form.$('ul.dropdown-menu.state:visible').length, 0, + form.$('.dropdown-menu.state:visible .dropdown-item').first().click(); + assert.strictEqual(form.$('.dropdown-menu.state:visible').length, 0, "there should not be a dropdown anymore"); assert.strictEqual(form.$('.o_field_widget.o_selection > a span.o_status.o_status_red').length, 0, "should not have one red status since selection is the first, normal state"); @@ -3721,7 +3721,7 @@ QUnit.module('basic_fields', { // switch to edit mode and check the result form.$buttons.find('.o_form_button_edit').click(); - assert.strictEqual(form.$('ul.dropdown-menu.state:visible').length, 0, + assert.strictEqual(form.$('.dropdown-menu.state:visible').length, 0, "there should still not be a dropdown"); assert.strictEqual(form.$('.o_field_widget.o_selection > a span.o_status.o_status_red').length, 0, "should still not have one red status since selection is the first, normal state"); @@ -3732,14 +3732,14 @@ QUnit.module('basic_fields', { // Click on the status button to make the dropdown appear form.$('.o_field_widget.o_selection .o_status').first().click(); - assert.strictEqual(form.$('ul.dropdown-menu.state:visible').length, 1, + assert.strictEqual(form.$('.dropdown-menu.state:visible').length, 1, "there should be a dropdown"); - assert.strictEqual(form.$('ul.dropdown-menu.state:visible li').length, 2, + assert.strictEqual(form.$('.dropdown-menu.state:visible .dropdown-item').length, 2, "there should be two options in the dropdown"); // Click on the last option, "Done" - form.$('ul.dropdown-menu.state:visible li').last().click(); - assert.strictEqual(form.$('ul.dropdown-menu.state:visible').length, 0, + form.$('.dropdown-menu.state:visible .dropdown-item').last().click(); + assert.strictEqual(form.$('.dropdown-menu.state:visible').length, 0, "there should not be a dropdown anymore"); assert.strictEqual(form.$('.o_field_widget.o_selection > a span.o_status.o_status_red').length, 0, "should not have one red status since selection is the third, done state"); @@ -3748,7 +3748,7 @@ QUnit.module('basic_fields', { // save form.$buttons.find('.o_form_button_save').click(); - assert.strictEqual(form.$('ul.dropdown-menu.state:visible').length, 0, + assert.strictEqual(form.$('.dropdown-menu.state:visible').length, 0, "there should still not be a dropdown anymore"); assert.strictEqual(form.$('.o_field_widget.o_selection > a span.o_status.o_status_red').length, 0, "should still not have one red status since selection is the third, done state"); @@ -3777,7 +3777,7 @@ QUnit.module('basic_fields', { "should have one red status"); assert.strictEqual(list.$('.o_state_selection_cell .o_selection > a span.o_status.o_status_green').length, 1, "should have one green status"); - assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 0, + assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 0, "there should not be a dropdown"); // Click on the status button to make the dropdown appear @@ -3785,20 +3785,20 @@ QUnit.module('basic_fields', { list.$('.o_state_selection_cell .o_selection > a span.o_status').first().click(); assert.ok(!$cell.parent().hasClass('o_selected_row'), 'should not be in edit mode since we clicked on the state selection widget'); - assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 1, + assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 1, "there should be a dropdown"); - assert.strictEqual(list.$('ul.dropdown-menu.state:visible li').length, 2, + assert.strictEqual(list.$('.dropdown-menu.state:visible .dropdown-item').length, 2, "there should be two options in the dropdown"); // Click on the first option, "Normal" - list.$('ul.dropdown-menu.state:visible li').first().click(); + list.$('.dropdown-menu.state:visible .dropdown-item').first().click(); assert.strictEqual(list.$('.o_state_selection_cell .o_selection > a span.o_status').length, 5, "should still have five status selection widgets"); assert.strictEqual(list.$('.o_state_selection_cell .o_selection > a span.o_status.o_status_red').length, 0, "should now have no red status"); assert.strictEqual(list.$('.o_state_selection_cell .o_selection > a span.o_status.o_status_green').length, 1, "should still have one green status"); - assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 0, + assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 0, "there should not be a dropdown"); // switch to edit mode and check the result @@ -3812,21 +3812,21 @@ QUnit.module('basic_fields', { "should now have no red status"); assert.strictEqual(list.$('.o_state_selection_cell .o_selection > a span.o_status.o_status_green').length, 1, "should still have one green status"); - assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 0, + assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 0, "there should not be a dropdown"); // Click on the status button to make the dropdown appear list.$('.o_state_selection_cell .o_selection > a span.o_status').first().click(); - assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 1, + assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 1, "there should be a dropdown"); - assert.strictEqual(list.$('ul.dropdown-menu.state:visible li').length, 2, + assert.strictEqual(list.$('.dropdown-menu.state:visible .dropdown-item').length, 2, "there should be two options in the dropdown"); // Click on another row var $firstCell = list.$('tbody td.o_state_selection_cell').first(); var $lastCell = list.$('tbody td.o_state_selection_cell').last(); $lastCell.click(); - assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 0, + assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 0, "there should not be a dropdown anymore"); assert.ok(!$firstCell.parent().hasClass('o_selected_row'), 'first row should not be in edit mode anymore'); @@ -3835,14 +3835,14 @@ QUnit.module('basic_fields', { // Click on the last status button to make the dropdown appear list.$('.o_state_selection_cell .o_selection > a span.o_status').last().click(); - assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 1, + assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 1, "there should be a dropdown"); - assert.strictEqual(list.$('ul.dropdown-menu.state:visible li').length, 2, + assert.strictEqual(list.$('.dropdown-menu.state:visible .dropdown-item').length, 2, "there should be two options in the dropdown"); // Click on the last option, "Done" - list.$('ul.dropdown-menu.state:visible li').last().click(); - assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 0, + list.$('.dropdown-menu.state:visible .dropdown-item').last().click(); + assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 0, "there should not be a dropdown anymore"); assert.strictEqual(list.$('.o_state_selection_cell .o_selection > a span.o_status').length, 5, "should still have five status selection widgets"); @@ -3850,7 +3850,7 @@ QUnit.module('basic_fields', { "should still have no red status"); assert.strictEqual(list.$('.o_state_selection_cell .o_selection > a span.o_status.o_status_green').length, 2, "should now have two green status"); - assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 0, + assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 0, "there should not be a dropdown"); // save @@ -3861,7 +3861,7 @@ QUnit.module('basic_fields', { "should have no red status"); assert.strictEqual(list.$('.o_state_selection_cell .o_selection > a span.o_status.o_status_green').length, 2, "should have two green status"); - assert.strictEqual(list.$('ul.dropdown-menu.state:visible').length, 0, + assert.strictEqual(list.$('.dropdown-menu.state:visible').length, 0, "there should not be a dropdown"); list.destroy(); diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js index 8c91b0f4d54..17c22617744 100644 --- a/addons/web/static/tests/fields/relational_fields_tests.js +++ b/addons/web/static/tests/fields/relational_fields_tests.js @@ -429,7 +429,7 @@ QUnit.module('relational_fields', { $('button:contains(Filters)').click(); $('.o_add_custom_filter:visible').click(); // Add a custom filter, datetime field is selected - assert.strictEqual($('li.o_filter_condition select.o_searchview_extended_prop_field').val(), 'datetime', + assert.strictEqual($('.o_filter_condition select.o_searchview_extended_prop_field').val(), 'datetime', "datetime field should be selected"); $('.o_apply_filter').click(); diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js index 232a6d59f30..dc80d6440b3 100644 --- a/addons/web/static/tests/views/form_tests.js +++ b/addons/web/static/tests/views/form_tests.js @@ -5003,8 +5003,8 @@ QUnit.module('Views', { } assert.strictEqual($actions.length, 3, "there should be 3 actions"); - var $customAction = $('.o_web_client .o_control_panel .btn-group .dropdown-menu li a')[2]; - assert.strictEqual($customAction.text.trim(), 'Action partner', + var $customAction = $('.o_web_client .o_control_panel .btn-group .dropdown-menu:last .dropdown-item:nth(2)'); + assert.strictEqual($customAction.text().trim(), 'Action partner', "the custom action should have 'Action partner' as name"); testUtils.intercept(form, 'do_action', function (event) { var context = event.data.action.context.__contexts[1]; diff --git a/addons/web/static/tests/views/graph_tests.js b/addons/web/static/tests/views/graph_tests.js index 60e6680993c..1ed9e799a4a 100644 --- a/addons/web/static/tests/views/graph_tests.js +++ b/addons/web/static/tests/views/graph_tests.js @@ -175,9 +175,9 @@ QUnit.module('Views', { return concurrency.delay(0).then(function () { assert.ok(graph.$('text.nv-legend-text:contains(Count)').length, "should have used the correct measure"); - assert.ok(graph.$buttons.find('li[data-field="foo"]').length, + assert.ok(graph.$buttons.find('.dropdown-item[data-field="foo"]').length, "should have foo in the list of measures"); - graph.$buttons.find('li[data-field="foo"] a').click(); + graph.$buttons.find('.dropdown-item[data-field="foo"]').click(); return concurrency.delay(0); }).then(function () { @@ -268,7 +268,7 @@ QUnit.module('Views', { graph_intervalMapping: {}, }, "context should be correct"); - graph.$buttons.find('li[data-field="foo"] a').click(); // change measure + graph.$buttons.find('.dropdown-item[data-field="foo"]').click(); // change measure return concurrency.delay(0); }).then(function () { @@ -552,7 +552,7 @@ QUnit.module('Views', { return concurrency.delay(0).then(function () { // need to set the measure this way because it cannot be set in the // arch. - graph.$buttons.find('li[data-field="product_id"] a').click(); + graph.$buttons.find('.dropdown-item[data-field="product_id"]').click(); assert.strictEqual(graph.model.chart.data[0].value, 1, "should have first datapoint with value 1"); @@ -639,9 +639,9 @@ QUnit.module('Views', { '</graph>', }) - assert.strictEqual(graph.$buttons.find('.o_graph_measures_list li:first').data('field'), 'bouh', + assert.strictEqual(graph.$buttons.find('.o_graph_measures_list .dropdown-item:first').data('field'), 'bouh', "Bouh should be the first measure"); - assert.strictEqual(graph.$buttons.find('.o_graph_measures_list li:last').data('field'), '__count__', + assert.strictEqual(graph.$buttons.find('.o_graph_measures_list .dropdown-item:last').data('field'), '__count__', "Count should be the last measure"); graph.destroy(); diff --git a/addons/web/static/tests/views/kanban_tests.js b/addons/web/static/tests/views/kanban_tests.js index 5d18d03c553..c80e0916d21 100644 --- a/addons/web/static/tests/views/kanban_tests.js +++ b/addons/web/static/tests/views/kanban_tests.js @@ -738,7 +738,7 @@ QUnit.module('Views', { // Select state in kanban kanban.$('.o_status').first().click(); - kanban.$('.o_selection ul:first li:first').click(); + kanban.$('.o_selection .dropdown-item:first').click(); assert.ok(kanban.$('.o_status').first().hasClass('o_status_green'), "Kanban state should be done (Green)"); kanban.destroy(); @@ -2789,10 +2789,10 @@ QUnit.module('Views', { '<t t-name="kanban-box">' + '<div color="color">' + '<div class="o_dropdown_kanban dropdown">' + - '<a class="dropdown-toggle btn" data-toggle="dropdown" href="#">' + + '<a class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#">' + '<span class="fa fa-bars fa-lg"/>' + '</a>' + - '<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">' + + '<ul class="dropdown-menu" role="menu">' + '<li>' + '<ul class="oe_kanban_colorpicker"/>' + '</li>' + diff --git a/addons/web/static/tests/views/list_tests.js b/addons/web/static/tests/views/list_tests.js index 1ea69e9320b..b9732164332 100644 --- a/addons/web/static/tests/views/list_tests.js +++ b/addons/web/static/tests/views/list_tests.js @@ -2347,8 +2347,8 @@ QUnit.module('Views', { var $actions = $('.o_web_client .o_control_panel .btn-group .dropdown-menu')[1].children; assert.strictEqual($actions.length, 3, "there should be 3 actions"); - var $customAction = $('.o_web_client .o_control_panel .btn-group .dropdown-menu li a')[2]; - assert.strictEqual($customAction.text.trim(), 'Action event', + var $customAction = $('.o_web_client .o_control_panel .btn-group .dropdown-item:nth(2)'); + assert.strictEqual($customAction.text().trim(), 'Action event', "the custom action should have 'Action event' as name"); list.destroy(); diff --git a/addons/web/static/tests/views/pivot_tests.js b/addons/web/static/tests/views/pivot_tests.js index 138b620c4e0..6e034a19a79 100644 --- a/addons/web/static/tests/views/pivot_tests.js +++ b/addons/web/static/tests/views/pivot_tests.js @@ -259,7 +259,7 @@ QUnit.module('Views', { } }); - var $countMeasure = pivot.$buttons.find('li[data-field=__count]'); + var $countMeasure = pivot.$buttons.find('.dropdown-item[data-field=__count]:first'); assert.ok($countMeasure.hasClass('selected'), "The count measure should be activated"); pivot.destroy(); }); @@ -344,14 +344,15 @@ QUnit.module('Views', { // click on closed header to open dropdown pivot.$('tbody .o_pivot_header_cell_closed').click(); - assert.strictEqual(pivot.$('ul.o_pivot_field_menu > li[data-field="date"]').length, 1, + assert.strictEqual(pivot.$('.o_pivot_field_menu .dropdown-item[data-field="date"]:first').length, 1, "should have the date field as proposition"); - assert.strictEqual(pivot.$('.o_field_selection li[data-field="product_id"]').length, 1, + assert.strictEqual(pivot.$('.o_field_selection .dropdown-item[data-field="product_id"]:first').length, 1, "should have the product_id field as proposition"); - assert.strictEqual(pivot.$('.o_field_selection li[data-field="non_stored_m2o"]').length, 0, + assert.strictEqual(pivot.$('.o_field_selection .dropdown-item[data-field="non_stored_m2o"]:first').length, 0, "should not have the non_stored_m2o field as proposition"); - pivot.$('ul.o_pivot_field_menu > li[data-field="date"] a').click(); + + pivot.$('.o_pivot_field_menu .dropdown-item[data-field="date"]:first').click(); assert.strictEqual(pivot.$('tbody tr').length, 4, "should have 4 rows: one for header, 3 for data"); @@ -376,7 +377,7 @@ QUnit.module('Views', { // open dropdown to zoom into first row pivot.$('tbody .o_pivot_header_cell_closed').first().click(); // click on date by day - pivot.$('ul.o_pivot_field_menu > li[data-field="date"] a[data-interval="day"]').click(); + pivot.$('.o_pivot_field_menu .dropdown-item[data-field="date"][data-interval="day"]').click(); // open dropdown to zoom into second row pivot.$('tbody td.o_pivot_header_cell_closed:eq(1)').first().click(); @@ -437,22 +438,22 @@ QUnit.module('Views', { assert.strictEqual(pivot.$('.o_pivot_cell_value').length, 3, "should have 3 cells: 1 for the open header, and 2 for data"); - assert.ok(!pivot.$buttons.find('li[data-field=__count]').hasClass('selected'), + assert.ok(!pivot.$buttons.find('.dropdown-item[data-field=__count]:first').hasClass('selected'), "the __count measure should not be selected"); rpcCount = 0; - pivot.$buttons.find('li[data-field=__count] a').click(); + pivot.$buttons.find('.dropdown-item[data-field=__count]:first').click(); - assert.ok(pivot.$buttons.find('li[data-field=__count]').hasClass('selected'), + assert.ok(pivot.$buttons.find('.dropdown-item[data-field=__count]:first').hasClass('selected'), "the __count measure should be selected"); assert.strictEqual(pivot.$('.o_pivot_cell_value').length, 6, "should have 6 cells: 2 for the open header, and 4 for data"); assert.strictEqual(rpcCount, 2, "should have done 2 rpcs to reload data"); - pivot.$buttons.find('li[data-field=__count] a').click(); + pivot.$buttons.find('.dropdown-item[data-field=__count]:first').click(); - assert.ok(!pivot.$buttons.find('li[data-field=__count]').hasClass('selected'), + assert.ok(!pivot.$buttons.find('.dropdown-item[data-field=__count]:first').hasClass('selected'), "the __count measure should not be selected"); assert.strictEqual(pivot.$('.o_pivot_cell_value').length, 3, "should have 3 cells: 1 for the open header, and 2 for data"); @@ -477,7 +478,7 @@ QUnit.module('Views', { assert.strictEqual(pivot.$('table').length, 1, "should have a table in DOM"); - pivot.$buttons.find('li[data-field=__count] a').click(); + pivot.$buttons.find('.dropdown-item[data-field=__count]:first').click(); assert.strictEqual(pivot.$('.o_view_nocontent').length, 1, "should have a no_content_helper"); @@ -553,7 +554,7 @@ QUnit.module('Views', { // tries to open a field selection menu, to make sure it was not // removed from the dom. pivot.$('.o_pivot_header_cell_closed').first().click(); - assert.strictEqual(pivot.$('ul.o_pivot_field_menu').length, 1, + assert.strictEqual(pivot.$('.o_pivot_field_menu').length, 1, "the field selector menu exists"); pivot.destroy(); }); @@ -816,7 +817,7 @@ QUnit.module('Views', { // expand header on field customer pivot.$('thead .o_pivot_header_cell_closed:nth(1)').click(); - pivot.$('ul.o_pivot_field_menu > li[data-field="customer"] a').click(); + pivot.$('.o_pivot_field_menu .dropdown-item[data-field="customer"]:first').click(); assert.deepEqual(pivot.getContext(), { pivot_column_groupby: ['date:day', 'customer'], pivot_measures: ['foo'], @@ -825,7 +826,7 @@ QUnit.module('Views', { // expand row on field product_id pivot.$('tbody .o_pivot_header_cell_closed').first().click(); - pivot.$('ul.o_pivot_field_menu > li[data-field="product_id"] a').click(); + pivot.$('.o_pivot_field_menu .dropdown-item[data-field="product_id"]:first').click(); assert.deepEqual(pivot.getContext(), { pivot_column_groupby: ['date:day', 'customer'], pivot_measures: ['foo'], @@ -982,7 +983,7 @@ QUnit.module('Views', { }, }); - var $countMeasure = pivot.$buttons.find('li[data-field=__count]'); + var $countMeasure = pivot.$buttons.find('.dropdown-item[data-field=__count]:first'); assert.ok($countMeasure.hasClass('selected'), "The count measure should be activated"); pivot.destroy(); @@ -1056,7 +1057,7 @@ QUnit.module('Views', { }); pivot.$('tbody .o_pivot_header_cell_closed').first().click(); // click on date by month - pivot.$('ul.o_pivot_field_menu > li[data-field="date"] a[data-interval="month"]').click(); + pivot.$('.o_pivot_field_menu .dropdown-item[data-field="date"][data-interval="month"]').click(); assert.strictEqual(pivot.$('.o_pivot_cell_value').text(), '2211', 'should have loaded the proper data'); @@ -1078,7 +1079,7 @@ QUnit.module('Views', { }, }); - pivot.$buttons.find('li[data-field=product_id] a').click(); + pivot.$buttons.find('.dropdown-item[data-field=product_id]:first').click(); assert.strictEqual(pivot.$('.o_pivot_cell_value').text(), '421131', 'should have loaded the proper data'); pivot.destroy(); @@ -1098,7 +1099,7 @@ QUnit.module('Views', { pivot.$('tbody .o_pivot_header_cell_closed').first().click(); - pivot.$('ul.o_pivot_field_menu > li[data-field="product_id"] a').click(); + pivot.$('.o_pivot_field_menu .dropdown-item[data-field="product_id"]:first').click(); assert.strictEqual(pivot.$('.o_pivot_cell_value').text(), '211', 'should have loaded the proper data'); @@ -1119,11 +1120,11 @@ QUnit.module('Views', { // Set a column groupby pivot.$('thead .o_pivot_header_cell_closed').click(); - pivot.$('.o_field_selection li[data-field=customer] a').click(); + pivot.$('.o_field_selection .dropdown-item[data-field=customer]:first').click(); // Set a Row groupby pivot.$('tbody .o_pivot_header_cell_closed').click(); - pivot.$('.o_pivot_field_menu li[data-field=product_id] a').click(); + pivot.$('.o_pivot_field_menu .dropdown-item[data-field=product_id]:first').click(); // Set a domain pivot.update({domain: [['product_id', '=', 41]]}); @@ -1195,9 +1196,9 @@ QUnit.module('Views', { '</pivot>', }) - assert.strictEqual(pivot.$buttons.find('.o_pivot_measures_list li:first').data('field'), 'bouh', + assert.strictEqual(pivot.$buttons.find('.o_pivot_measures_list .dropdown-item:first').data('field'), 'bouh', "Bouh should be the first measure"); - assert.strictEqual(pivot.$buttons.find('.o_pivot_measures_list li:last').data('field'), '__count', + assert.strictEqual(pivot.$buttons.find('.o_pivot_measures_list .dropdown-item:last').data('field'), '__count', "Count should be the last measure"); pivot.destroy(); diff --git a/addons/web/static/tests/views/search_filters_menu_tests.js b/addons/web/static/tests/views/search_filters_menu_tests.js index e6430527de7..70d57c1fd32 100644 --- a/addons/web/static/tests/views/search_filters_menu_tests.js +++ b/addons/web/static/tests/views/search_filters_menu_tests.js @@ -37,11 +37,11 @@ QUnit.module('FiltersMenu', { var filterMenu = createFiltersMenu([], this.fields); filterMenu.$('span.fa-filter').click(); - assert.strictEqual(filterMenu.$('.divider').length, 1); - assert.ok(!filterMenu.$('.divider').is(':visible')); - assert.strictEqual(filterMenu.$('li').length, 3, - 'should have 3 li: a hidden divider, a add custom filter item, a apply button + add condition button'); - assert.strictEqual(filterMenu.$('li.o_add_custom_filter.o_closed_menu').length, 1); + assert.strictEqual(filterMenu.$('.dropdown-divider').length, 1); + assert.ok(!filterMenu.$('.dropdown-divider').is(':visible')); + assert.strictEqual(filterMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 3, + 'should have 3 elements: a hidden divider, a add custom filter item, a apply button + add condition button'); + assert.strictEqual(filterMenu.$('.o_add_custom_filter.o_closed_menu').length, 1); filterMenu.destroy(); }); @@ -49,9 +49,9 @@ QUnit.module('FiltersMenu', { assert.expect(2); var filterMenu = createFiltersMenu(this.filters, this.fields); - assert.strictEqual(filterMenu.$('li').length, 5, - 'should have 4 li: a hidden, separator, a filter, a separator, a add custom filter item, a apply button + add condition button'); - assert.strictEqual(filterMenu.$('li.o_add_custom_filter.o_closed_menu').length, 1); + assert.strictEqual(filterMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 5, + 'should have 4 elements: a hidden, separator, a filter, a separator, a add custom filter item, a apply button + add condition button'); + assert.strictEqual(filterMenu.$('.o_add_custom_filter.o_closed_menu').length, 1); filterMenu.destroy(); }); @@ -62,11 +62,11 @@ QUnit.module('FiltersMenu', { // open menu dropdown filterMenu.$('span.fa-filter').click(); // open add custom filter submenu - filterMenu.$('li.o_add_custom_filter').click(); - assert.ok(filterMenu.$('li.o_add_custom_filter').hasClass('o_open_menu')); - assert.ok(filterMenu.$('li.o_add_filter_menu').is(':visible')); - assert.strictEqual(filterMenu.$('li').length, 4, - 'should have 3 li: a hidden divider, a add custom filter item, a proposition, a apply button + add condition button'); + filterMenu.$('.o_add_custom_filter').click(); + assert.ok(filterMenu.$('.o_add_custom_filter').hasClass('o_open_menu')); + assert.ok(filterMenu.$('.o_add_filter_menu').is(':visible')); + assert.strictEqual(filterMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 4, + 'should have 3 elements: a hidden divider, a add custom filter item, a proposition, a apply button + add condition button'); filterMenu.destroy(); }); @@ -77,15 +77,15 @@ QUnit.module('FiltersMenu', { var filterMenu = createFiltersMenu([], this.fields); // open menu dropdown and custom filter submenu filterMenu.$('span.fa-filter').click(); - filterMenu.$('li.o_add_custom_filter').click(); + filterMenu.$('.o_add_custom_filter').click(); // remove the current unique proposition filterMenu.$('.o_searchview_extended_delete_prop').click(); assert.ok(filterMenu.$('.o_apply_filter').attr('disabled')); - assert.strictEqual(filterMenu.$('li').length, 3, - 'should have 3 li: a hidden separator, a add custom filter item, a apply button + add condition button'); + assert.strictEqual(filterMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 3, + 'should have 3 elements: a hidden separator, a add custom filter item, a apply button + add condition button'); filterMenu.destroy(); }); @@ -97,7 +97,7 @@ QUnit.module('FiltersMenu', { // open menu dropdown and custom filter submenu, remove existing prop filterMenu.$('span.fa-filter').click(); - filterMenu.$('li.o_add_custom_filter').click(); + filterMenu.$('.o_add_custom_filter').click(); filterMenu.$('.o_searchview_extended_delete_prop').click(); // read a proposition @@ -116,14 +116,14 @@ QUnit.module('FiltersMenu', { // open menu dropdown and custom filter submenu, remove existing prop filterMenu.$('span.fa-filter').click(); - filterMenu.$('li.o_add_custom_filter').click(); + filterMenu.$('.o_add_custom_filter').click(); // click on apply to activate filter filterMenu.$('.o_apply_filter').click(); assert.ok(filterMenu.$('.o_add_custom_filter').hasClass('o_closed_menu')); assert.strictEqual(filterMenu.$('.o_filter_condition').length, 0); - assert.strictEqual(filterMenu.$('.divider:visible').length, 1, + assert.strictEqual(filterMenu.$('.dropdown-divider:visible').length, 1, 'there should be a separator between filters and add custom filter menu'); filterMenu.destroy(); diff --git a/addons/web/static/tests/views/search_groupby_menu_tests.js b/addons/web/static/tests/views/search_groupby_menu_tests.js index 8dff7a581fe..d11b8ed0dbe 100644 --- a/addons/web/static/tests/views/search_groupby_menu_tests.js +++ b/addons/web/static/tests/views/search_groupby_menu_tests.js @@ -35,8 +35,8 @@ QUnit.module('GroupByMenu', { var groupByMenu = createGroupByMenu(this.groupbys, this.fields); groupByMenu.$('button:first').click(); - assert.strictEqual(groupByMenu.$('li').length, 2, 'should have 2 li'); - assert.strictEqual(groupByMenu.$('li:nth-child(2)').text().trim(), 'some group by', + assert.strictEqual(groupByMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 2, 'should have 2 elements'); + assert.strictEqual(groupByMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').eq(1).text().trim(), 'some group by', 'should have proper filter name'); groupByMenu.destroy(); }); @@ -46,7 +46,7 @@ QUnit.module('GroupByMenu', { var groupByMenu = createGroupByMenu([], {}); groupByMenu.$('button:first').click(); - assert.strictEqual(groupByMenu.$('li').length, 0, 'should have 0 li'); + assert.strictEqual(groupByMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 0, 'should have 0 element'); groupByMenu.destroy(); }); @@ -58,7 +58,7 @@ QUnit.module('GroupByMenu', { {fieldname: {sortable: true, string: 'Super Date', type: 'date', isDate: true}} ); groupByMenu.$('button:first').click(); - assert.strictEqual(groupByMenu.$('li').length, 1, 'should have 1 li'); + assert.strictEqual(groupByMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 1, 'should have 1 element'); groupByMenu.destroy(); }); @@ -69,7 +69,7 @@ QUnit.module('GroupByMenu', { groupByMenu.$('button:first').click(); var selector = groupByMenu.$('select.o_group_selector'); assert.ok(!selector.is(":visible"), 'should be invisible'); - groupByMenu.$('.o_add_custom_group a').click(); + groupByMenu.$('.o_add_custom_group').click(); selector = groupByMenu.$('select.o_group_selector'); assert.ok(selector.is(":visible"), 'should be visible'); groupByMenu.destroy(); @@ -85,11 +85,11 @@ QUnit.module('GroupByMenu', { } ); groupByMenu.$('button:first').click(); - groupByMenu.$('li.o_add_custom_group a').click(); + groupByMenu.$('.o_add_custom_group').click(); assert.strictEqual(groupByMenu.$('select').val(), 'fieldName', 'the select value should be "fieldName"'); groupByMenu.$('button.o_apply_group').click(); - assert.strictEqual(groupByMenu.$('li.o_menu_item.selected').length, 1, 'there should be a groupby selected'); + assert.strictEqual(groupByMenu.$('.o_menu_item.selected').length, 1, 'there should be a groupby selected'); groupByMenu.destroy(); }); @@ -107,7 +107,7 @@ QUnit.module('GroupByMenu', { var groupByMenu = createGroupByMenu(this.groupbys, this.fields, { intercepts: { - menu_item_toggled: function(ev) { + menu_item_toggled: function (ev) { assert.strictEqual(ev.data.itemId, 'green'); assert.strictEqual(ev.data.isActive, true); }, @@ -143,7 +143,7 @@ QUnit.module('GroupByMenu', { var groupByMenu = createGroupByMenu(this.groupbys, {fieldname: {sortable: true, string: 'Super Date', type: 'date', isDate: true}} ); - groupByMenu.$el.click(function(event) { + groupByMenu.$el.click(function (event) { // we do not want a click to get out and change the url, for example throw new Error('No click should get out of the groupby menu'); }); diff --git a/addons/web/static/tests/views/search_view_tests.js b/addons/web/static/tests/views/search_view_tests.js index 990686da97a..88c5416398e 100644 --- a/addons/web/static/tests/views/search_view_tests.js +++ b/addons/web/static/tests/views/search_view_tests.js @@ -170,7 +170,7 @@ QUnit.module('Search View', { actionManager.doAction(1); $('span.fa-bars').prev().click(); - $('li.o_menu_item a').click(); + $('.o_menu_item a').click(); assert.strictEqual($('.o_searchview .o_searchview_facet .o_facet_values span').text().trim(), 'candle', 'should have a facet with candle name'); actionManager.destroy(); @@ -187,7 +187,7 @@ QUnit.module('Search View', { actionManager.doAction(1); $('span.fa-bars').prev().click(); - $('li.o_menu_item a').click(); + $('.o_menu_item a').click(); assert.strictEqual($('.o_searchview .o_searchview_facet .o_facet_values span').text().trim(), 'candle', 'should have a facet with candle name'); $('.o_facet_remove:first').click(); @@ -304,7 +304,7 @@ QUnit.module('Search View', { // // no groupby is applied assert.strictEqual($('div.o_facet_values span').length, 0); // // open 'Add custom Groupby' menu - $('.o_group_by_menu .o_add_custom_group a').click(); + $('.o_group_by_menu .o_add_custom_group').click(); // // click on 'Apply' button $('.o_group_by_menu .o_generator_menu button').click(); // // data should be grouped by the field 'Birthday' using the interval 'month' @@ -364,7 +364,7 @@ QUnit.module('Search View', { actionManager.doAction(1); $('span.fa-filter').click(); - $('li.o_add_custom_filter').click(); + $('.o_add_custom_filter').click(); $('.o_apply_filter').click(); assert.strictEqual($('.o_searchview .o_searchview_facet .o_facet_values span').text().trim(), 'ID is \"0\"', 'should have a facet with candle name'); @@ -382,9 +382,9 @@ QUnit.module('Search View', { actionManager.doAction(1); $('span.fa-filter').click(); - $('li.o_add_custom_filter').click(); + $('.o_add_custom_filter').click(); $('.o_apply_filter').click(); - $('li.o_menu_item').click(); + $('.o_menu_item').click(); assert.strictEqual($('.o_searchview .o_searchview_facet .o_facet_values span').length, 0, 'no facet should be in the search view'); actionManager.destroy(); @@ -455,20 +455,20 @@ QUnit.module('Search View', { // open menu 'Filter' $('.o_search_options .fa-filter').click(); // open menu options - $('li.o_menu_item').click(); - $('li.o_menu_item .o_item_option[data-option_id="today"]').click(); - $('li.o_menu_item .o_item_option[data-option_id="this_week"]').click(); - $('li.o_menu_item .o_item_option[data-option_id="this_month"]').click(); - $('li.o_menu_item .o_item_option[data-option_id="this_quarter"]').click(); - $('li.o_menu_item .o_item_option[data-option_id="this_year"]').click(); - $('li.o_menu_item .o_item_option[data-option_id="yesterday"]').click(); - $('li.o_menu_item .o_item_option[data-option_id="last_week"]').click(); - $('li.o_menu_item .o_item_option[data-option_id="last_month"]').click(); - $('li.o_menu_item .o_item_option[data-option_id="last_quarter"]').click(); - $('li.o_menu_item .o_item_option[data-option_id="last_year"]').click(); - $('li.o_menu_item .o_item_option[data-option_id="last_7_days"]').click(); - $('li.o_menu_item .o_item_option[data-option_id="last_30_days"]').click(); - $('li.o_menu_item .o_item_option[data-option_id="last_365_days"]').click(); + $('.o_menu_item').click(); + $('.o_menu_item .o_item_option[data-option_id="today"]').click(); + $('.o_menu_item .o_item_option[data-option_id="this_week"]').click(); + $('.o_menu_item .o_item_option[data-option_id="this_month"]').click(); + $('.o_menu_item .o_item_option[data-option_id="this_quarter"]').click(); + $('.o_menu_item .o_item_option[data-option_id="this_year"]').click(); + $('.o_menu_item .o_item_option[data-option_id="yesterday"]').click(); + $('.o_menu_item .o_item_option[data-option_id="last_week"]').click(); + $('.o_menu_item .o_item_option[data-option_id="last_month"]').click(); + $('.o_menu_item .o_item_option[data-option_id="last_quarter"]').click(); + $('.o_menu_item .o_item_option[data-option_id="last_year"]').click(); + $('.o_menu_item .o_item_option[data-option_id="last_7_days"]').click(); + $('.o_menu_item .o_item_option[data-option_id="last_30_days"]').click(); + $('.o_menu_item .o_item_option[data-option_id="last_365_days"]').click(); actionManager.destroy(); window.Date = RealDate; @@ -498,7 +498,7 @@ QUnit.module('Search View', { actionManager.doAction(6); $('span.fa-filter').click(); - $('.o_filters_menu li.o_menu_item a').click(); + $('.o_filters_menu .o_menu_item a').click(); $('.o_item_option:first').click(); $('span.fa-star').click(); $('.o_favorites_menu .o_save_search a').click(); diff --git a/addons/web/static/tests/widgets/dropdown_menu_tests.js b/addons/web/static/tests/widgets/dropdown_menu_tests.js index 0669b92c87f..b378a94ee58 100644 --- a/addons/web/static/tests/widgets/dropdown_menu_tests.js +++ b/addons/web/static/tests/widgets/dropdown_menu_tests.js @@ -44,9 +44,9 @@ QUnit.module('Web', { assert.expect(2); var dropdownMenu = createDropdownMenu(this.dropdownHeader, this.items); - assert.strictEqual(dropdownMenu.$('li').length, 4, 'should have 4 li counting the dividers'); - assert.strictEqual(dropdownMenu.$('li:nth-child(2)').text().trim(), 'Some Item', - 'first li should have "Some Item" description'); + assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 4, 'should have 4 elements counting the dividers'); + assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').eq(1).text().trim(), 'Some Item', + 'first element should have "Some Item" description'); dropdownMenu.destroy(); }); @@ -57,7 +57,7 @@ QUnit.module('Web', { var dropdownMenu = createDropdownMenu(this.dropdownHeader, this.items, { intercepts: { - menu_item_toggled: function(ev) { + menu_item_toggled: function (ev) { eventNumber++; assert.strictEqual(ev.data.itemId, 1); if (eventNumber === 1) { @@ -86,7 +86,7 @@ QUnit.module('Web', { assert.expect(0); var dropdownMenu = createDropdownMenu(this.dropdownHeader, this.items); - dropdownMenu.$el.click(function() { + dropdownMenu.$el.click(function () { // we do not want a click to get out and change the url, for example throw new Error('No click should get out of the dropdown menu'); }); @@ -103,13 +103,13 @@ QUnit.module('Web', { var dropdownMenu = createDropdownMenu(this.dropdownHeader, this.items); // open dropdown dropdownMenu.$('button:first').click(); - assert.strictEqual(dropdownMenu.$('li').length, 4); + assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 4); // open options menu dropdownMenu.$('span.fa-caret-right').click(); - assert.strictEqual(dropdownMenu.$('li').length, 7); + assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 7); // close options menu dropdownMenu.$('span.fa-caret-down').click(); - assert.strictEqual(dropdownMenu.$('li').length, 4); + assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 4); dropdownMenu.destroy(); }); @@ -123,10 +123,10 @@ QUnit.module('Web', { dropdownMenu.$('button:first').click(); // open options menu dropdownMenu.$('span.fa-caret-right').click(); - assert.strictEqual(dropdownMenu.$('li').length, 7); + assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 7); dropdownMenu.$('button:first').click(); dropdownMenu.$('button:first').click(); - assert.strictEqual(dropdownMenu.$('li').length, 4); + assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 4); dropdownMenu.destroy(); }); @@ -140,7 +140,7 @@ QUnit.module('Web', { var dropdownMenu = createDropdownMenu(this.dropdownHeader, this.items, { intercepts: { - menu_item_toggled: function(ev) { + menu_item_toggled: function (ev) { eventNumber++; if (eventNumber === 1) { assert.strictEqual(ev.data.itemId, 1); @@ -152,7 +152,7 @@ QUnit.module('Web', { assert.strictEqual(ev.data.optionId, false); } }, - item_option_changed: function(ev) { + item_option_changed: function (ev) { if (eventNumber === 1) { assert.strictEqual(ev.data.itemId, 1); assert.strictEqual(ev.data.isActive, true); @@ -165,20 +165,20 @@ QUnit.module('Web', { dropdownMenu.$('button:first').click(); // open options menu dropdownMenu.$('span.fa-caret-right').click(); - assert.strictEqual(dropdownMenu.$('li').length, 7); + assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 7); // Don't forget there is a hidden li.divider element at first place among children assert.ok(!dropdownMenu.$('.o_menu_item:nth-child(2)').hasClass('selected')); assert.ok(!dropdownMenu.$('.o_item_option:nth-child(2)').hasClass('selected')); assert.ok(!dropdownMenu.$('.o_item_option:nth-child(3)').hasClass('selected')); - dropdownMenu.$('li.o_item_option:first').click(); + dropdownMenu.$('.o_item_option:first').click(); assert.ok(dropdownMenu.$('.o_menu_item:nth-child(2)').hasClass('selected')); assert.ok(dropdownMenu.$('.o_item_option:nth-child(2)').hasClass('selected')); assert.ok(!dropdownMenu.$('.o_item_option:nth-child(3)').hasClass('selected')); - dropdownMenu.$('li.o_item_option:nth-child(3)').click(); + dropdownMenu.$('.o_item_option:nth-child(3)').click(); assert.ok(dropdownMenu.$('.o_menu_item:nth-child(2)').hasClass('selected')); assert.ok(!dropdownMenu.$('.o_item_option:nth-child(2)').hasClass('selected')); assert.ok(dropdownMenu.$('.o_item_option:nth-child(3)').hasClass('selected')); - dropdownMenu.$('li.o_item_option:nth-child(3)').click(); + dropdownMenu.$('.o_item_option:nth-child(3)').click(); assert.ok(!dropdownMenu.$('.o_menu_item:nth-child(2)').hasClass('selected')); assert.ok(!dropdownMenu.$('.o_item_option:nth-child(2)').hasClass('selected')); assert.ok(!dropdownMenu.$('.o_item_option:nth-child(3)').hasClass('selected')); @@ -190,15 +190,15 @@ QUnit.module('Web', { var dropdownMenu = createDropdownMenu(this.dropdownHeader, this.items, { intercepts: { - menu_item_deleted: function(ev) { + menu_item_deleted: function (ev) { assert.strictEqual(ev.data.itemId, 2); }, }, }); dropdownMenu.$('button:first').click(); - assert.strictEqual(dropdownMenu.$('li').length, 4); + assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 4); dropdownMenu.$('span.o_trash_button').click(); - assert.strictEqual(dropdownMenu.$('li').length, 2); + assert.strictEqual(dropdownMenu.$('.dropdown-divider, .dropdown-item, .dropdown-item-text').length, 2); dropdownMenu.destroy(); }); }); diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml index b05e7e05bf6..1224accd6cb 100644 --- a/addons/web/views/webclient_templates.xml +++ b/addons/web/views/webclient_templates.xml @@ -162,7 +162,6 @@ <link rel="stylesheet" type="text/scss" href="/web/static/src/scss/web_calendar.scss"/> <link rel="stylesheet" type="text/scss" href="/web/static/src/scss/search_view.scss"/> <link rel="stylesheet" type="text/scss" href="/web/static/src/scss/search_view_mobile.scss"/> - <link rel="stylesheet" type="text/scss" href="/web/static/src/scss/search_groupby_menu.scss"/> <link rel="stylesheet" type="text/scss" href="/web/static/src/scss/dropdown_menu.scss"/> <link rel="stylesheet" type="text/scss" href="/web/static/src/scss/search_view_extra.scss"/> <link rel="stylesheet" type="text/scss" href="/web/static/src/scss/data_export.scss"/> @@ -399,8 +398,8 @@ <t t-call="web.menu_link"/> </li> <li id="menu_more_container" class="dropdown" style="display: none;"> - <a role="menuitem" aria-haspopup="true" href="#" class="dropdown-toggle" data-toggle="dropdown" id="more_menu_button">More <b class="caret"></b></a> - <ul id="menu_more" class="dropdown-menu" role="menu"></ul> + <a role="menuitem" aria-haspopup="true" href="#" class="dropdown-toggle" data-toggle="dropdown" id="more_menu_button">More</a> + <div id="menu_more" class="dropdown-menu" role="menu"/> </li> </ul> diff --git a/addons/web_editor/static/src/js/editor/rte.summernote.js b/addons/web_editor/static/src/js/editor/rte.summernote.js index cd482a18d7c..fa993dff99a 100644 --- a/addons/web_editor/static/src/js/editor/rte.summernote.js +++ b/addons/web_editor/static/src/js/editor/rte.summernote.js @@ -142,7 +142,7 @@ renderer.tplPopovers = function (lang, options) { })).appendTo($resizefa); } var $colorfa = $airPopover.find('.note-color').clone(); - $colorfa.find("ul.dropdown-menu").css('min-width', '172px'); + $colorfa.find(".dropdown-menu").css('min-width', '172px'); $resizefa.after($colorfa); // show dialog box and delete diff --git a/addons/web_editor/static/src/js/editor/snippets.editor.js b/addons/web_editor/static/src/js/editor/snippets.editor.js index 97bd73cb832..e3a8803619a 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -199,7 +199,7 @@ var SnippetEditor = Widget.extend({ // Attach own and parent options on the current overlay var $style_button = this.$el.find('.oe_options'); - var $ul = $style_button.find('ul:first'); + var $ul = $style_button.find('.dropdown-menu:first'); var $headers = $ul.find('.dropdown-header:data(editor)'); _.each($headers, (function (el) { var $el = $(el); @@ -218,7 +218,7 @@ var SnippetEditor = Widget.extend({ }).bind(this)); // Activate the overlay - $style_button.toggleClass('d-none', $ul.children(':not(.o_main_header):not(.divider):not(.d-none)').length === 0); + $style_button.toggleClass('d-none', $ul.children(':not(.o_main_header):not(.dropdown-divider):not(.d-none)').length === 0); this.cover(); this.$el.toggleClass('oe_active', !!focus); @@ -262,13 +262,13 @@ var SnippetEditor = Widget.extend({ _initializeOptions: function () { var self = this; var $styles = this.$el.find('.oe_options'); - var $ul = $styles.find('ul:first'); + var $ul = $styles.find('.dropdown-menu:first'); this.styles = {}; this.selectorSiblings = []; this.selectorChildren = []; var i = 0; - $ul.append($('<li/>', {class: 'dropdown-header o_main_header', text: this._getName()}).data('editor', this)); + $ul.append($('<div/>', {class: 'dropdown-header o_main_header', text: this._getName()}).data('editor', this)); var defs = _.map(this.templateOptions, function (val, option_id) { if (!val.selector.is(self.$target)) { return; @@ -277,7 +277,7 @@ var SnippetEditor = Widget.extend({ if (val['drop-in']) self.selectorChildren.push(val['drop-in']); var optionName = val.option; - var $el = val.$el.children('li').clone(true).addClass('snippet-option-' + optionName); + var $el = val.$el.children().clone(true).addClass('snippet-option-' + optionName); var option = new (options.registry[optionName] || options.Class)( self, val.base_target ? self.$target.find(val.base_target).eq(0) : self.$target, @@ -288,7 +288,7 @@ var SnippetEditor = Widget.extend({ option.__order = i++; return option.attachTo($el); }); - $ul.append($('<li/>', {class: 'divider'})); + $ul.append($('<div/>', {class: 'dropdown-divider'})); var $parents = this.$target.parents(); _.each($parents, function (parent) { @@ -296,7 +296,7 @@ var SnippetEditor = Widget.extend({ if (parentEditor) { for (var styleName in parentEditor.styles) { if (!parentEditor.styles[styleName].preventChildPropagation) { - $ul.append($('<li/>', {class: 'dropdown-header o_parent_editor_header', text: parentEditor._getName()}).data('editor', parentEditor)); + $ul.append($('<div/>', {class: 'dropdown-header o_parent_editor_header', text: parentEditor._getName()}).data('editor', parentEditor)); break; } } diff --git a/addons/web_editor/static/src/js/editor/snippets.options.js b/addons/web_editor/static/src/js/editor/snippets.options.js index 54e92b60028..463d2acf08e 100644 --- a/addons/web_editor/static/src/js/editor/snippets.options.js +++ b/addons/web_editor/static/src/js/editor/snippets.options.js @@ -17,10 +17,10 @@ var _t = core._t; */ var SnippetOption = Widget.extend({ events: { - 'mouseenter a': '_onLinkEnter', - 'click a': '_onLinkClick', + 'mouseenter': '_onLinkEnter', + 'click': '_onLinkClick', 'mouseleave': '_onMouseleave', - 'mouseleave ul': '_onMouseleave', + 'mouseleave .dropdown-menu': '_onMouseleave', }, /** * When editing a snippet, its options are shown alongside the ones of its @@ -30,7 +30,7 @@ var SnippetOption = Widget.extend({ preventChildPropagation: false, /** - * The option `$el` is supposed to be the associated <li/> element in the + * The option `$el` is supposed to be the associated DOM element in the * options dropdown. The option controls another DOM element: the snippet it * customizes, which can be found at `$target`. Access to the whole edition * overlay is possible with `$overlay` (this is not recommended though). @@ -115,18 +115,18 @@ var SnippetOption = Widget.extend({ /** * Default option method which allows to select one and only one class in * the option classes set and set it on the associated snippet. The common - * case is having a subdropdown with each <li/> having a `data-select-class` + * case is having a subdropdown with each item having a `data-select-class` * value allowing to choose the associated class. * * @param {boolean|string} previewMode * - truthy if the option is enabled for preview or if leaving it (in * that second case, the value is 'reset') * - false if the option should be activated for good - * @param {*} value - the class to activate ($li.data('selectClass')) - * @param {jQuery} $li - the related DOMElement option + * @param {*} value - the class to activate ($opt.data('selectClass')) + * @param {jQuery} $opt - the related DOMElement option */ - selectClass: function (previewMode, value, $li) { - var $group = $li && $li.closest('.dropdown-submenu'); + selectClass: function (previewMode, value, $opt) { + var $group = $opt && $opt.closest('.dropdown-submenu'); if (!$group || !$group.length) { $group = this.$el; } @@ -141,12 +141,12 @@ var SnippetOption = Widget.extend({ /** * Default option method which allows to select one or multiple classes in * the option classes set and set it on the associated snippet. The common - * case is having a subdropdown with each <li/> having a `data-toggle-class` + * case is having a subdropdown with each item having a `data-toggle-class` * value allowing to toggle the associated class. * * @see this.selectClass */ - toggleClass: function (previewMode, value, $li) { + toggleClass: function (previewMode, value, $opt) { var $lis = this.$el.find('[data-toggle-class]').addBack('[data-toggle-class]'); var classes = $lis.map(function () {return $(this).data('toggleClass');}).get().join(' '); var activeClasses = $lis.filter('.active, :has(.active)').map(function () {return $(this).data('toggleClass');}).get().join(' '); @@ -163,7 +163,7 @@ var SnippetOption = Widget.extend({ /** * Override the helper method to search inside the $target element instead - * of the dropdown <li/> element. + * of the dropdown item element. * * @override */ @@ -225,13 +225,13 @@ var SnippetOption = Widget.extend({ * - truthy if the option is enabled for preview or if leaving it (in * that second case, the value is 'reset') * - false if the option should be activated for good - * @param {jQuery} $li - the related DOMElement option + * @param {jQuery} $opt - the related DOMElement option */ - _select: function (previewMode, $li) { + _select: function (previewMode, $opt) { var self = this; // Options can say they respond to strong choice - if (previewMode && ($li.data('noPreview') || $li.parent().data('noPreview'))) { + if (previewMode && ($opt.data('noPreview') || $opt.parent().data('noPreview'))) { return; } // If it is not preview mode, the user selected the option for good @@ -243,7 +243,7 @@ var SnippetOption = Widget.extend({ // Search for methods (data-...) (i.e. data-toggle-class) on the // selected (sub)option and its parents - var el = $li[0]; + var el = $opt[0]; var methods = []; do { methods.push([el, el.dataset]); @@ -302,20 +302,25 @@ var SnippetOption = Widget.extend({ * @param {Event} ev */ _onLinkEnter: function (ev) { - var $li = $(ev.currentTarget).parent(); - if ($li.is('.dropdown-submenu')) { - var $menu = $li.children('.dropdown-menu'); + var $opt = $(ev.target); + if (!$opt.hasClass('dropdown-item')) { + return; + } + + var $dsmenu = $opt.parent('.dropdown-submenu'); + if ($dsmenu.length) { + var $menu = $dsmenu.children('.dropdown-menu'); // FIXME if ($menu.length) { - var menuRightPosition = $li.offset().left + $li.outerWidth() + $menu.outerWidth(); + var menuRightPosition = $dsmenu.offset().left + $dsmenu.outerWidth() + $menu.outerWidth(); $menu.toggleClass('o_open_to_left', menuRightPosition > $(window).outerWidth()); } } - if (!$li.is(':hasData')) { + if (!$opt.is(':hasData')) { return; } this.__click = false; - this._select(true, $li); + this._select(true, $opt); this.$target.trigger('snippet-option-preview', [this]); }, /** @@ -325,13 +330,14 @@ var SnippetOption = Widget.extend({ * @param {Event} ev */ _onLinkClick: function (ev) { - var $li = $(ev.currentTarget).parent(':hasData'); - if (!$li.length) { + var $opt = $(ev.target); + if (!$opt.hasClass('dropdown-item') || !$opt.is(':hasData')) { return; } + ev.preventDefault(); this.__click = true; - this._select(false, $li); + this._select(false, $opt); this.$target.trigger('snippet-option-change', [this]); }, /** @@ -678,7 +684,7 @@ registry.colorpicker = SnippetOption.extend({ $toggles.parent().empty().append($clpicker); } - this.$el.find('li').append($pt); + this.$el.find('.dropdown-menu').append($pt); } var classes = []; @@ -781,7 +787,7 @@ registry.background = SnippetOption.extend({ * * @see this.selectClass for parameters */ - background: function (previewMode, value, $li) { + background: function (previewMode, value, $opt) { if (previewMode === 'reset' && value === undefined) { // No background has been selected and we want to reset back to the // original custom image @@ -800,16 +806,16 @@ registry.background = SnippetOption.extend({ /** * @override */ - selectClass: function (previewMode, value, $li) { - this.background(previewMode, '', $li); - this._super(previewMode, value ? (value + ' oe_img_bg') : value, $li); + selectClass: function (previewMode, value, $opt) { + this.background(previewMode, '', $opt); + this._super(previewMode, value ? (value + ' oe_img_bg') : value, $opt); }, /** * Opens a media dialog to add a custom background image. * * @see this.selectClass for parameters */ - chooseImage: function (previewMode, value, $li) { + chooseImage: function (previewMode, value, $opt) { // Put fake image in the DOM, edit it and use it as background-image var $image = $('<img/>', {class: 'd-none', src: value}).appendTo(this.$target); @@ -881,7 +887,7 @@ registry.background = SnippetOption.extend({ this._super.apply(this, arguments); var src = this._getSrcFromCssValue(); - this.$el.find('li[data-background]') + this.$el.find('[data-background]') .removeClass('active') .filter(function () { var bgOption = $(this).data('background'); @@ -889,7 +895,7 @@ registry.background = SnippetOption.extend({ }) .addClass('active'); - this.$el.find('li[data-choose-image]').toggleClass('active', this.$target.hasClass('oe_custom_bg')); + this.$el.find('[data-choose-image]').toggleClass('active', this.$target.hasClass('oe_custom_bg')); }, /** * Sets the given value as custom background image. @@ -938,7 +944,7 @@ registry.background_position = SnippetOption.extend({ * * @see this.selectClass for parameters */ - backgroundPosition: function (previewMode, value, $li) { + backgroundPosition: function (previewMode, value, $opt) { var self = this; this.previous_state = [this.$target.attr('class'), this.$target.css('background-size'), this.$target.css('background-position')]; diff --git a/addons/web_editor/static/src/js/editor/summernote.js b/addons/web_editor/static/src/js/editor/summernote.js index 657a8bbac8c..784aab3493e 100644 --- a/addons/web_editor/static/src/js/editor/summernote.js +++ b/addons/web_editor/static/src/js/editor/summernote.js @@ -958,15 +958,15 @@ range.WrappedRange.prototype.isContentEditable = function () { renderer.tplButtonInfo.fontsize = function (lang, options) { var items = options.fontSizes.reduce(function (memo, v) { - return memo + '<li><a data-event="fontSize" href="#" data-value="' + v + '">' + + return memo + '<a data-event="fontSize" href="#" class="dropdown-item" data-value="' + v + '">' + '<i class="fa fa-check"></i> ' + v + - '</a></li>'; + '</a>'; }, ''); var sLabel = '<span class="note-current-fontsize">11</span>'; return renderer.getTemplate().button(sLabel, { title: lang.font.size, - dropdown: '<ul class="dropdown-menu">' + items + '</ul>' + dropdown: '<div class="dropdown-menu">' + items + '</div>' }); }; diff --git a/addons/web_editor/static/src/js/tours/rte.js b/addons/web_editor/static/src/js/tours/rte.js index 82c31da5259..0a4ae0b32c3 100644 --- a/addons/web_editor/static/src/js/tours/rte.js +++ b/addons/web_editor/static/src/js/tours/rte.js @@ -67,7 +67,7 @@ tour.register('rte', { trigger: ".note-color button.dropdown-toggle", }, { content: "change text color", - trigger: ".btn-group.open button[data-event=foreColor]:first", + trigger: ".btn-group.show button[data-event=foreColor]:first", }, { content: "change selection to change text bg-color again", trigger: '#editable_area > section .row > div:first h1 font:eq(2)', diff --git a/addons/web_editor/static/src/scss/web_editor.ui.scss b/addons/web_editor/static/src/scss/web_editor.ui.scss index e82ad579fe8..bb5cddcffe1 100644 --- a/addons/web_editor/static/src/scss/web_editor.ui.scss +++ b/addons/web_editor/static/src/scss/web_editor.ui.scss @@ -409,7 +409,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] { } } // Open menu - &.open .btn { + &.show .btn { background-color: $o-we-color-light; &:before, &:after { width: 9px; @@ -430,43 +430,21 @@ html[lang] > body.editor_enable [data-oe-translation-state] { border: 1px solid $o-we-color-dark; border-radius: 0; background-color: $o-we-color-light; - a { + + .dropdown-item { + position: relative; color: $o-we-color-text-light; font-weight: normal; font-size: 12px; padding: 5px 35px 5px 20px; - } - > li { - position: relative; &:hover { background-color: fade-out($o-we-color-dark, 0.5); - > a { - color: white; - background: transparent; - cursor: pointer; - } - > .dropdown-menu { - display: block; - left: 100%; - top: 0; - - &.o_open_to_left { - left: auto; - right: 100%; - } - } - } - &.dropdown-submenu:before { - @include o-position-absolute($top: 10px, $right: 10px); - @include o-caret-right(3px); - border-left-color: $o-we-color-text-light; - } - &.divider { - background-color: $o-we-color-divider; - margin: 0 8px; + color: white; + background: transparent; + cursor: pointer; } - &.active > a { + &.active { color: white; background-color: fade-out($o-we-color-dark, 0.5); &:before { @@ -476,53 +454,73 @@ html[lang] > body.editor_enable [data-oe-translation-state] { color: $o-brand-optional; } } - &.dropdown-header { - color: white; - font-weight: bold; - font-size: 12px; - margin-top: 2px; - &:hover { - background-color: initial; - } + > i { + width: 16px; + margin-right: 8px; + } + } - &.o_main_header { - padding-left: 8px; - } - &.o_parent_editor_header { - color: wheat; - font-weight: 400; - font-size: 10px; - margin: 7px 0 4px 4px; - &::before { - content: "\f148"; - @include o-position-absolute($top: 2px, $left: 8px); - font-family: FontAwesome; - transform: scaleX(-1); - } - ~ li:not(.dropdown-header) { - a { - font-size: 11px; - padding: 4px 35px 4px 20px; - opacity: 0.8; - &:hover { - opacity: 1; - } - } - } - } + .dropdown-submenu { + position: relative; + + &::before { + @include o-position-absolute($top: 10px, $right: 10px); + @include o-caret-right(3px); + border-left-color: $o-we-color-text-light; } - &.separator { + &:hover > .dropdown-menu { display: block; - margin: 4px 35px 4px 20px; - height: 1px; - background: rgba($o-we-color-text-light, 0.1); + left: 100%; + top: 0; + + &.o_open_to_left { + left: auto; + right: 100%; + } } + } - > a > i { - width: 16px; - margin-right: 8px; + .dropdown-divider { + display: block; + height: 1px; + background: rgba($o-we-color-text-light, 0.1); + margin: 0 8px; + } + + .dropdown-header { + color: white; + font-weight: bold; + font-size: 12px; + margin-top: 2px; + + &:hover { + background-color: initial; + } + + &.o_main_header { + padding-left: 8px; + } + &.o_parent_editor_header { + color: wheat; + font-weight: 400; + font-size: 10px; + margin: 7px 0 4px 4px; + &::before { + content: "\f148"; + @include o-position-absolute($top: 2px, $left: 8px); + font-family: FontAwesome; + transform: scaleX(-1); + } + ~ .dropdown-item { + font-size: 11px; + padding: 4px 35px 4px 20px; + opacity: 0.8; + &:hover { + opacity: 1; + } + } } } } @@ -749,7 +747,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] { > .btn-group { margin-top: -2px; - &.open, .btn-group.open { + &.show, .btn-group.show { .dropdown-toggle { border-top: 2px solid white; background-color: $o-we-color-darker; @@ -767,7 +765,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] { border-radius: 0; background-color: $o-we-color-darker; color: $o-we-color-text-normal; - > li > a { + .dropdown-item { width: 100%; color: $o-we-color-text-light; @@ -831,7 +829,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] { .note-popover .popover, .note-editor { .dropdown-menu { - > li > a { + .dropdown-item { > i { visibility: hidden; } diff --git a/addons/web_editor/static/src/xml/ace.xml b/addons/web_editor/static/src/xml/ace.xml index 257ce6af707..800a0ef2ced 100644 --- a/addons/web_editor/static/src/xml/ace.xml +++ b/addons/web_editor/static/src/xml/ace.xml @@ -6,10 +6,10 @@ <div class="form-inline o_ace_view_editor_title"> <div class="btn-group o_ace_type_switcher"> <button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown">XML (HTML)</button> - <ul class="dropdown-menu" role="menu"> - <li><a role="menuitem" href="#" class="o_ace_type_switcher_choice" data-type="xml">XML (HTML)</a></li> - <li><a role="menuitem" href="#" class="o_ace_type_switcher_choice" data-type="scss">SCSS (CSS)</a></li> - </ul> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" href="#" class="dropdown-item o_ace_type_switcher_choice" data-type="xml">XML (HTML)</a> + <a role="menuitem" href="#" class="dropdown-item o_ace_type_switcher_choice" data-type="scss">SCSS (CSS)</a> + </div> </div> <select id="ace-view-list" class="o_res_list"/> <select id="ace-scss-list" class="o_res_list d-none"/> diff --git a/addons/web_editor/static/src/xml/editor.xml b/addons/web_editor/static/src/xml/editor.xml index 1928572fc0d..96f126391cd 100644 --- a/addons/web_editor/static/src/xml/editor.xml +++ b/addons/web_editor/static/src/xml/editor.xml @@ -95,14 +95,11 @@ <div class="btn-group"> <button class="btn btn-primary o_upload_image_button" type="button">Upload an image</button> <button class="btn btn-primary dropdown-toggle" data-toggle="dropdown" type="button"> - <span class="caret"/> <span class="sr-only">Alternate Upload</span> </button> - <ul class="dropdown-menu" role="menu"> - <li> - <a role="menuitem" class="o_upload_image_button_no_optimization">Upload image without optimization</a> - </li> - </ul> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" class="dropdown-item o_upload_image_button_no_optimization">Upload image without optimization</a> + </div> </div> </div> <div> diff --git a/addons/web_editor/static/src/xml/snippets.xml b/addons/web_editor/static/src/xml/snippets.xml index 586b920edf0..a0c35288b93 100644 --- a/addons/web_editor/static/src/xml/snippets.xml +++ b/addons/web_editor/static/src/xml/snippets.xml @@ -13,7 +13,7 @@ <a role="button" href="#" class="btn btn-secondary oe_snippet_parent" title="Select Parent Container" aria-label="Select Parent Container"><i class="fa fa-lg fa-level-up"/></a> <div class="dropdown oe_options d-none btn-group"> <a role="button" href="#" data-toggle="dropdown" class="btn btn-primary" title="Customize">Customize</a> - <ul class="dropdown-menu" role="menu"/> + <div class="dropdown-menu" role="menu"/> </div> <a role="button" href="#" class="btn btn-secondary oe_snippet_move" title="Drag to Move" aria-label="Drag to Move"><i class="fa fa-arrows ml4 mr4"></i></a> <a role="button" href="#" class="btn btn-secondary oe_snippet_clone" title="Duplicate Container" aria-label="Duplicate Container"><i class="fa fa-files-o ml4 mr4"></i></a> @@ -41,9 +41,9 @@ <t t-name="web_editor.many2one.button"> <div class="btn-group"> <a role="button" href="#" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" data-hover="dropdown" title="Search Contact" aria-label="Search Contact"><i class="fa fa-search"></i></a> - <ul class="dropdown-menu contact_menu" role="menu"> - <li><a role="menuitem"><input href="#" type="email" placeholder="Search"/></a></li> - </ul> + <div class="dropdown-menu contact_menu" role="menu"> + <a role="menuitem" class="dropdown-item"><input href="#" type="email" placeholder="Search"/></a> + </div> </div> </t> diff --git a/addons/web_tour/static/src/xml/debug_manager.xml b/addons/web_tour/static/src/xml/debug_manager.xml index 6077723cf27..4fb8a8d6570 100644 --- a/addons/web_tour/static/src/xml/debug_manager.xml +++ b/addons/web_tour/static/src/xml/debug_manager.xml @@ -2,14 +2,10 @@ <templates id="template" xml:space="preserve"> <t t-extend="WebClient.DebugManager.Global"> - <t t-jquery="li > a[data-action='select_view']" t-operation="after"> + <t t-jquery="a[data-action='select_view']" t-operation="after"> <t t-if="manager._is_admin"> - <li t-if="manager.consume_tours_enabled"> - <a href="#" data-action="consume_tours">Disable Tours</a> - </li> - <li> - <a href="#" data-action="start_tour">Start Tour</a> - </li> + <a t-if="manager.consume_tours_enabled" href="#" class="dropdown-item" data-action="consume_tours">Disable Tours</a> + <a href="#" class="dropdown-item" data-action="start_tour">Start Tour</a> </t> </t> </t> diff --git a/addons/website/static/src/js/content/menu.js b/addons/website/static/src/js/content/menu.js index 5f8c337802f..9a5f393c0f6 100644 --- a/addons/website/static/src/js/content/menu.js +++ b/addons/website/static/src/js/content/menu.js @@ -66,7 +66,7 @@ sAnimation.registry.affixMenu = sAnimation.Class.extend({ this.$headerClone.toggleClass('affixed', wOffset > (hOffset + 300)); // Reset opened menus - this.$dropdowns.removeClass('open'); + this.$dropdowns.removeClass('show'); this.$navbarCollapses.removeClass('in').attr('aria-expanded', false); }, }); diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js index 977edd2db96..0c3d02bffb8 100644 --- a/addons/website/static/src/js/editor/snippets.options.js +++ b/addons/website/static/src/js/editor/snippets.options.js @@ -248,8 +248,8 @@ options.registry.carousel = options.Class.extend({ * @override */ _setActive: function () { - this.$el.find('li[data-interval]').removeClass('active') - .filter('li[data-interval=' + this.$target.attr('data-interval') + ']').addClass('active'); + this.$el.find('[data-interval]').removeClass('active') + .filter('[data-interval=' + this.$target.attr('data-interval') + ']').addClass('active'); }, /** * Rebinds carousel events on indicators. @@ -340,7 +340,7 @@ options.registry.layout_column = options.Class.extend({ * * @see this.selectClass for parameters */ - selectCount: function (previewMode, value, $li) { + selectCount: function (previewMode, value, $opt) { this._updateColumnCount(value - this.$target.children().length); }, @@ -402,8 +402,8 @@ options.registry.layout_column = options.Class.extend({ */ _setActive: function () { this._super.apply(this, arguments); - this.$el.find('li[data-select-count]').removeClass('active') - .filter('li[data-select-count=' + this.$target.children().length + ']').addClass('active'); + this.$el.find('[data-select-count]').removeClass('active') + .filter('[data-select-count=' + this.$target.children().length + ']').addClass('active'); }, }); @@ -968,7 +968,7 @@ options.registry.gallery = options.Class.extend({ * * @see this.selectClass for parameters */ - mode: function (previewMode, value, $li) { + mode: function (previewMode, value, $opt) { this.$target.css('height', ''); this[value](); this.$target @@ -1017,7 +1017,7 @@ options.registry.gallery = options.Class.extend({ * Displays the images with a "slideshow" layout. */ slideshow: function () { - var imgStyle = this.$el.find('li.active[data-styling]').data('styling') || ''; + var imgStyle = this.$el.find('.active[data-styling]').data('styling') || ''; var urls = _.map(this._getImages(), function (img) { return $(img).attr('src'); }); @@ -1050,8 +1050,8 @@ options.registry.gallery = options.Class.extend({ * @see this.selectClass for parameters */ styling: function (previewMode, value) { - var classes = _.map(this.$el.find('li[data-styling]'), function (li) { - return $(li).data('styling'); + var classes = _.map(this.$el.find('[data-styling]'), function (el) { + return $(el).data('styling'); }).join(' '); this.$('img').removeClass(classes).addClass(value); }, @@ -1163,8 +1163,8 @@ options.registry.gallery = options.Class.extend({ .removeClass('active') .filter('[data-styling="' + classes.join('"], [data-styling="') + '"]').addClass('active'); - this.$el.find('li[data-interval]').removeClass('active') - .filter('li[data-interval='+this.$target.find('.carousel:first').attr('data-interval')+']') + this.$el.find('[data-interval]').removeClass('active') + .filter('[data-interval='+this.$target.find('.carousel:first').attr('data-interval')+']') .addClass('active'); var interval = this.$target.find('.carousel:first').attr('data-interval'); diff --git a/addons/website/static/src/js/menu/customize.js b/addons/website/static/src/js/menu/customize.js index 2d525ac903e..0eac78cc90f 100644 --- a/addons/website/static/src/js/menu/customize.js +++ b/addons/website/static/src/js/menu/customize.js @@ -12,22 +12,21 @@ var qweb = core.qweb; var CustomizeMenu = Widget.extend({ xmlDependencies: ['/web_editor/static/src/xml/editor.xml'], events: { - 'click > ul a[data-view-id]': '_onCustomizeOptionClick', + 'show.bs.dropdown': '_onDropdownShow', + 'click .dropdown-item[data-view-id]': '_onCustomizeOptionClick', }, /** * @override */ start: function () { - var viewName = $(document.documentElement).data('view-xmlid'); - if (!viewName) { + this.viewName = $(document.documentElement).data('view-xmlid'); + if (!this.viewName) { _.defer(this.destroy.bind(this)); } - if (this.$el.is('.open')) { - this._loadCustomizeOptions(viewName); - } else { - this.$el.one('mousedown', '> a.dropdown-toggle', this._loadCustomizeOptions.bind(this, viewName)); + if (this.$el.is('.show')) { + this._loadCustomizeOptions(); } }, @@ -61,15 +60,19 @@ var CustomizeMenu = Widget.extend({ * the current page and shows them as switchable elements in the menu. * * @private - * @param {string} viewName - xml id * @return {Deferred} */ - _loadCustomizeOptions: function (viewName) { - var $menu = this.$el.children('ul'); + _loadCustomizeOptions: function () { + if (this.__customizeOptionsLoaded) { + return $.when(); + } + this.__customizeOptionsLoaded = true; + + var $menu = this.$el.children('.dropdown-menu'); return this._rpc({ route: '/website/get_switchable_related_views', params: { - key: viewName, + key: this.viewName, }, }).then(function (result) { var currentGroup = ''; @@ -78,11 +81,10 @@ var CustomizeMenu = Widget.extend({ currentGroup = item.inherit_id[1]; $menu.append('<li class="dropdown-header">' + currentGroup + '</li>'); } - var $li = $('<li/>', {role: 'presentation'}) - .append($('<a/>', {href: '#', 'data-view-id': item.id, role: 'menuitem'}) - .append(qweb.render('web_editor.components.switch', {id: 'switch-' + item.id, label: item.name}))); - $li.find('input').prop('checked', !!item.active); - $menu.append($li); + var $a = $('<a/>', {href: '#', class: 'dropdown-item', 'data-view-id': item.id, role: 'menuitem'}) + .append(qweb.render('web_editor.components.switch', {id: 'switch-' + item.id, label: item.name})); + $a.find('input').prop('checked', !!item.active); + $menu.append($a); }); }); }, @@ -103,6 +105,12 @@ var CustomizeMenu = Widget.extend({ var viewID = parseInt($(ev.currentTarget).data('view-id'), 10); this._doCustomize(viewID); }, + /** + * @private + */ + _onDropdownShow: function () { + this._loadCustomizeOptions(); + }, }); var AceEditorMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({ diff --git a/addons/website/static/src/js/menu/navbar.js b/addons/website/static/src/js/menu/navbar.js index 9a25d50c3ed..ed8cf1ffa31 100644 --- a/addons/website/static/src/js/menu/navbar.js +++ b/addons/website/static/src/js/menu/navbar.js @@ -11,7 +11,7 @@ var websiteNavbarRegistry = new rootWidget.RootWidgetRegistry(); var WebsiteNavbar = rootWidget.RootWidget.extend({ events: _.extend({}, rootWidget.RootWidget.prototype.events || {}, { 'click [data-action]': '_onActionMenuClick', - 'mouseover > ul > li.dropdown:not(.open)': '_onMenuHovered', + 'mouseover > ul > li.dropdown:not(.show)': '_onMenuHovered', 'click .o_mobile_menu_toggle': '_onMobileMenuToggleClick', }), custom_events: _.extend({}, rootWidget.RootWidget.prototype.custom_events || {}, { @@ -121,10 +121,10 @@ var WebsiteNavbar = rootWidget.RootWidget.extend({ * @param {Event} ev */ _onMenuHovered: function (ev) { - var $opened = this.$('> ul > li.dropdown.open'); + var $opened = this.$('> ul > li.dropdown.show'); if ($opened.length) { - $opened.removeClass('open'); - $(ev.currentTarget).find('.dropdown-toggle').mousedown().focus().mouseup().click(); + $opened.find('.dropdown-toggle').dropdown('toggle'); + $(ev.currentTarget).find('.dropdown-toggle').dropdown('toggle'); } }, /** diff --git a/addons/website/static/src/scss/website.scss b/addons/website/static/src/scss/website.scss index ecc9babb274..9100155d9f6 100644 --- a/addons/website/static/src/scss/website.scss +++ b/addons/website/static/src/scss/website.scss @@ -518,7 +518,7 @@ div.carousel { top: $o-navbar-height; } -.navbar .o_extra_menu_items.open > ul { +.navbar .o_extra_menu_items.show > ul { > li { + li { border-top: 1px solid $gray-lighter; diff --git a/addons/website/views/snippets.xml b/addons/website/views/snippets.xml index 929233dea9d..e1d9efb767d 100644 --- a/addons/website/views/snippets.xml +++ b/addons/website/views/snippets.xml @@ -764,128 +764,119 @@ <t t-call="web_editor.snippet_options"/> <div data-js='gallery' data-selector=".o_gallery"> - <li data-add-images="true" data-no-preview="true"><a href="#"><i class="fa fa-plus-circle"/>Add images</a></li> - <li data-remove-all-images="true" data-no-preview="true"><a href="#"><i class="fa fa-trash"/>Remove all images</a></li> - <li class="separator"/> - <li class="dropdown-submenu"> - <a tabindex="-2" href="#"><i class="fa fa-magic"/>Mode</a> - <ul class="dropdown-menu" role="menu"> - <li data-mode="nomode"><a role="menuitem" href="#">Float</a></li> - <li data-mode="masonry"><a role="menuitem" href="#">Masonry</a></li> - <li data-mode="grid"><a role="menuitem" href="#">Grid</a></li> - <li data-mode="slideshow"><a role="menuitem" href="#">Slideshow</a></li> - </ul> - </li> - <li class="dropdown-submenu"> - <a tabindex="-2" href="#"><i class="fa fa-clock-o"/>Slideshow speed</a> - <ul class="dropdown-menu" role="menu"> - <li data-interval="1000"><a role="menuitem" href="#">1s</a></li> - <li data-interval="2000"><a role="menuitem" href="#">2s</a></li> - <li data-interval="3000"><a role="menuitem" href="#">3s</a></li> - <li data-interval="5000"><a role="menuitem" href="#">5s</a></li> - <li data-interval="10000"><a role="menuitem" href="#">10s</a></li> - <li data-interval="0"><a role="menuitem" href="#">Disable autoplay</a></li> - </ul> - </li> - <li class="dropdown-submenu"> - <a tabindex="-2" href="#"><i class="fa fa-th"/>Columns</a> - <ul class="dropdown-menu" role="menu"> - <li data-columns="1"><a role="menuitem" href="#">1</a></li> - <li data-columns="2"><a role="menuitem" href="#">2</a></li> - <li data-columns="3"><a role="menuitem" href="#">3</a></li> - <li data-columns="4"><a role="menuitem" href="#">4</a></li> - <li data-columns="6"><a role="menuitem" href="#">6</a></li> - <li data-columns="12"><a role="menuitem" href="#">12</a></li> - </ul> - </li> - <li class="dropdown-submenu"> - <a tabindex="-2" href="#"><i class="fa fa-arrows-h"/>Images spacing</a> - - <ul class="dropdown-menu" role="menu"> - <li data-select-class="o_spc-none"><a role="menuitem" href="#">None</a></li> - <li data-select-class="o_spc-small"><a role="menuitem" href="#">Small</a></li> - <li data-select-class="o_spc-medium"><a role="menuitem" href="#">Medium</a></li> - <li data-select-class="o_spc-big"><a role="menuitem" href="#">Big</a></li> - </ul> - </li> - <li class="dropdown-submenu"> - <a tabindex="-2" href="#"><i class="fa fa-paint-brush"/>Styling</a> - <ul class="dropdown-menu" role="menu"> - <li data-styling=""><a role="menuitem" href="#">Square</a></li> - <li data-styling="img-rounded"><a role="menuitem" href="#">Rounded corners</a></li> - <li data-styling="img-thumbnail"><a role="menuitem" href="#">Thumbnails</a></li> - <li data-styling="img-circle"><a role="menuitem" href="#">Circle</a></li> - <li data-styling="shadow"><a role="menuitem" href="#">Shadows</a></li> - </ul> - </li> - <li class="separator"/> + <a href="#" class="dropdown-item" data-add-images="true" data-no-preview="true"><i class="fa fa-plus-circle"/>Add images</a> + <a href="#" class="dropdown-item" data-remove-all-images="true" data-no-preview="true"><i class="fa fa-trash"/>Remove all images</a> + <div class="dropdown-divider"/> + <div class="dropdown-submenu"> + <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-magic"/>Mode</a> + <div class="dropdown-menu" role="menu"> + <a href="#" class="dropdown-item" role="menuitem" data-mode="nomode">Float</a> + <a href="#" class="dropdown-item" role="menuitem" data-mode="masonry">Masonry</a> + <a href="#" class="dropdown-item" role="menuitem" data-mode="grid">Grid</a> + <a href="#" class="dropdown-item" role="menuitem" data-mode="slideshow">Slideshow</a> + </div> + </div> + <div class="dropdown-submenu"> + <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-clock-o"/>Slideshow speed</a> + <div class="dropdown-menu" role="menu"> + <a href="#" class="dropdown-item" role="menuitem" data-interval="1000">1s</a> + <a href="#" class="dropdown-item" role="menuitem" data-interval="2000">2s</a> + <a href="#" class="dropdown-item" role="menuitem" data-interval="3000">3s</a> + <a href="#" class="dropdown-item" role="menuitem" data-interval="5000">5s</a> + <a href="#" class="dropdown-item" role="menuitem" data-interval="10000">10s</a> + <a href="#" class="dropdown-item" role="menuitem" data-interval="0">Disable autoplay</a> + </div> + </div> + <div class="dropdown-submenu"> + <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-th"/>Columns</a> + <div class="dropdown-menu" role="menu"> + <a href="#" class="dropdown-item" role="menuitem" data-columns="1">1</a> + <a href="#" class="dropdown-item" role="menuitem" data-columns="2">2</a> + <a href="#" class="dropdown-item" role="menuitem" data-columns="3">3</a> + <a href="#" class="dropdown-item" role="menuitem" data-columns="4">4</a> + <a href="#" class="dropdown-item" role="menuitem" data-columns="6">6</a> + <a href="#" class="dropdown-item" role="menuitem" data-columns="12">12</a> + </div> + </div> + <div class="dropdown-submenu"> + <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-arrows-h"/>Images spacing</a> + <div class="dropdown-menu" role="menu"> + <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_spc-none">None</a> + <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_spc-small">Small</a> + <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_spc-medium">Medium</a> + <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_spc-big">Big</a> + </div> + </div> + <div class="dropdown-submenu"> + <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-paint-brush"/>Styling</a> + <div class="dropdown-menu" role="menu"> + <a href="#" class="dropdown-item" role="menuitem" data-styling="">Square</a> + <a href="#" class="dropdown-item" role="menuitem" data-styling="img-rounded">Rounded corners</a> + <a href="#" class="dropdown-item" role="menuitem" data-styling="img-thumbnail">Thumbnails</a> + <a href="#" class="dropdown-item" role="menuitem" data-styling="img-circle">Circle</a> + <a href="#" class="dropdown-item" role="menuitem" data-styling="shadow">Shadows</a> + </div> + </div> + <div class="dropdown-divider"/> </div> <div data-js="background" data-selector="section, :not(.o_gallery > .container) > .carousel, .parallax, .s_banner .carousel-content"> - <li data-choose-image="true" data-no-preview="true"> - <a tabindex="-1" href="#"><i class="fa fa-picture-o"/>Choose Background Image</a> - </li> + <a tabindex="-1" href="#" class="dropdown-item" data-choose-image="true" data-no-preview="true"><i class="fa fa-picture-o"/>Choose Background Image</a> </div> <div data-js="background_position" data-selector="section, :not(.o_gallery > .container) > .carousel, .s_banner .carousel-content"> - <li class="background_position_li" data-background-position="true" data-no-preview="true"> - <a tabindex="-1" href="#"><i class="fa fa-arrows"/>Background Image Sizing</a> - </li> + <a tabindex="-1" href="#" class="dropdown-item background_position_li" data-background-position="true" data-no-preview="true"><i class="fa fa-arrows"/>Background Image Sizing</a> </div> <div data-js="colorpicker" data-selector="section, :not(.o_gallery > .container) > .carousel" data-exclude=".parallax"> - <li class="dropdown-submenu"> - <a tabindex="-1" href="#"><i class="fa fa-eyedropper"/>Background Color</a> - <ul class="dropdown-menu" role="menu"> - <li></li> - </ul> - </li> + <div class="dropdown-submenu"> + <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-eyedropper"/>Background Color</a> + <div class="dropdown-menu" role="menu"/> + </div> </div> <div data-js="colorpicker" data-selector=".s_text_block_image_fw .row > div, .s_banner .carousel-content" data-palette-exclude="grayscale" data-palette-default="transparent_grayscale" data-palette-title="Overlay Color"> - <li class="dropdown-submenu"> - <a tabindex="-1" href="#"><i class="fa fa-eyedropper"/>Overlay color</a> - <ul class="dropdown-menu" role="menu"> - <li></li> - </ul> - </li> + <div class="dropdown-submenu"> + <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-eyedropper"/>Overlay color</a> + <div class="dropdown-menu" role="menu"/> + </div> </div> <div data-js='gallery_img' data-selector=".o_gallery img"> - <li class="dropdown-submenu"> - <a tabindex="-2" href="#"><i class="fa fa-refresh"/>Re-order</a> - <ul class="dropdown-menu" role="menu" data-no-preview="true"> - <li data-position="first"><a role="menuitem" href="#">Move to first</a></li> - <li data-position="prev"><a role="menuitem" href="#">Move to previous</a></li> - <li data-position="next"><a role="menuitem" href="#">Move to next</a></li> - <li data-position="last"><a role="menuitem" href="#">Move to last</a></li> - </ul> - </li> + <div class="dropdown-submenu"> + <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-refresh"/>Re-order</a> + <div class="dropdown-menu" role="menu" data-no-preview="true"> + <a href="#" class="dropdown-item" role="menuitem" data-position="first">Move to first</a> + <a href="#" class="dropdown-item" role="menuitem" data-position="prev">Move to previous</a> + <a href="#" class="dropdown-item" role="menuitem" data-position="next">Move to next</a> + <a href="#" class="dropdown-item" role="menuitem" data-position="last">Move to last</a> + </div> + </div> </div> <div data-js='carousel' data-selector=":not(.o_gallery > .container) > .carousel"> - <li class="divider"></li> - <li class="dropdown-submenu"> - <a tabindex="-2" href="#"><i class="fa fa-clock-o"/>Slideshow speed</a> - <ul class="dropdown-menu" role="menu"> - <li data-interval="1000"><a role="menuitem" href="#">1s</a></li> - <li data-interval="2000"><a role="menuitem" href="#">2s</a></li> - <li data-interval="3000"><a role="menuitem" href="#">3s</a></li> - <li data-interval="5000"><a role="menuitem" href="#">5s</a></li> - <li data-interval="10000"><a role="menuitem" href="#">10s</a></li> - <li data-interval="0"><a role="menuitem" href="#">Disable autoplay</a></li> - </ul> - </li> - <li data-add-slide="true" data-no-preview="true"><a href="#"><i class="fa fa-plus-circle"/>Add Slide</a></li> - <li data-remove-slide="true" data-no-preview="true"><a href="#" ><i class="fa fa-trash-o"/>Remove Slide</a></li> + <div class="dropdown-divider"/> + <div class="dropdown-submenu"> + <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-clock-o"/>Slideshow speed</a> + <div class="dropdown-menu" role="menu"> + <a href="#" class="dropdown-item" role="menuitem" data-interval="1000">1s</a> + <a href="#" class="dropdown-item" role="menuitem" data-interval="2000">2s</a> + <a href="#" class="dropdown-item" role="menuitem" data-interval="3000">3s</a> + <a href="#" class="dropdown-item" role="menuitem" data-interval="5000">5s</a> + <a href="#" class="dropdown-item" role="menuitem" data-interval="10000">10s</a> + <a href="#" class="dropdown-item" role="menuitem" data-interval="0">Disable autoplay</a> + </div> + </div> + <a href="#" class="dropdown-item" data-add-slide="true" data-no-preview="true"><i class="fa fa-plus-circle"/>Add Slide</a> + <a href="#" class="dropdown-item" data-remove-slide="true" data-no-preview="true"><i class="fa fa-trash-o"/>Remove Slide</a> </div> <div data-selector="section, :not(.o_gallery > .container) > .carousel, .parallax" @@ -899,17 +890,17 @@ data-selector="section" data-target="> * > .row" data-exclude=".s_text_block_image_fw, .s_company_team, .s_big_picture"> - <li class="dropdown-submenu"> - <a tabindex="-2" href="#"><i class="fa fa-columns"/>Number of columns</a> - <ul class="dropdown-menu" role="menu" data-no-preview="true"> - <li data-select-count="1"><a role="menuitem" href="#">1</a></li> - <li data-select-count="2"><a role="menuitem" href="#">2</a></li> - <li data-select-count="3"><a role="menuitem" href="#">3</a></li> - <li data-select-count="4"><a role="menuitem" href="#">4</a></li> - <li data-select-count="5"><a role="menuitem" href="#">5</a></li> - <li data-select-count="6"><a role="menuitem" href="#">6</a></li> - </ul> - </li> + <div class="dropdown-submenu"> + <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-columns"/>Number of columns</a> + <div class="dropdown-menu" role="menu" data-no-preview="true"> + <a href="#" class="dropdown-item" role="menuitem" data-select-count="1">1</a> + <a href="#" class="dropdown-item" role="menuitem" data-select-count="2">2</a> + <a href="#" class="dropdown-item" role="menuitem" data-select-count="3">3</a> + <a href="#" class="dropdown-item" role="menuitem" data-select-count="4">4</a> + <a href="#" class="dropdown-item" role="menuitem" data-select-count="5">5</a> + <a href="#" class="dropdown-item" role="menuitem" data-select-count="6">6</a> + </div> + </div> </div> <div data-js="sizing_x" @@ -929,53 +920,51 @@ </div> <div data-selector=".o_image_floating"> - <li class="dropdown-submenu"> - <a tabindex="-2" href="#"><i class="fa fa-expand"/>Margin</a> - <ul class="dropdown-menu" role="menu"> - <li data-select-class="o_margin_xl"><a role="menuitem" href="#">Extra-Large</a></li> - <li data-select-class="o_margin_l"><a role="menuitem" href="#">Large</a></li> - <li data-select-class="o_margin_m"><a role="menuitem" href="#">Medium</a></li> - <li data-select-class="o_margin_s"><a role="menuitem" href="#">Small</a></li> - <li data-select-class=""><a role="menuitem" href="#">None</a></li> - </ul> - </li> + <div class="dropdown-submenu"> + <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-expand"/>Margin</a> + <div class="dropdown-menu" role="menu"> + <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_margin_xl">Extra-Large</a> + <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_margin_l">Large</a> + <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_margin_m">Medium</a> + <a href="#" class="dropdown-item" role="menuitem" data-select-class="o_margin_s">Small</a> + <a href="#" class="dropdown-item" role="menuitem" data-select-class="">None</a> + </div> + </div> </div> <div data-selector=".o_image_floating"> - <li class="dropdown-submenu"> - <a tabindex="-2" href="#"><i class="fa fa-magnet"/>Float</a> - <ul class="dropdown-menu" role="menu" data-no-preview="true"> - <li data-select-class="pull-left"><a role="menuitem" href="#">Left</a></li> - <li data-select-class="pull-right"><a role="menuitem" href="#">Right</a></li> - </ul> - </li> + <div class="dropdown-submenu"> + <a tabindex="-2" href="#" class="dropdown-item"><i class="fa fa-magnet"/>Float</a> + <div class="dropdown-menu" role="menu" data-no-preview="true"> + <a href="#" class="dropdown-item" role="menuitem" data-select-class="pull-left">Left</a> + <a href="#" class="dropdown-item" role="menuitem" data-select-class="pull-right">Right</a> + </div> + </div> </div> <div data-js="parallax" data-selector=".parallax"> - <li class="dropdown-submenu"> - <a tabindex="-1" href="#"><i class="fa fa-clock-o"/>Scroll Speed</a> - <ul class="dropdown-menu" role="menu" name="parallax-scroll"> - <li data-scroll="0"><a role="menuitem" href="#">No-scroll</a></li> - <li class="separator" role="separator"/> - <li data-scroll="1"><a role="menuitem" href="#">Fixed</a></li> - <li class="separator" role="separator"/> - <li data-scroll="0.6"><a role="menuitem" href="#">Very Slow</a></li> - <li data-scroll="1.2"><a role="menuitem" href="#">Slow</a></li> - <li data-scroll="1.6"><a role="menuitem" href="#">Fast</a></li> - <li data-scroll="2"><a role="menuitem" href="#">Very Fast</a></li> - </ul> - </li> + <div class="dropdown-submenu"> + <a tabindex="-1" href="#" class="dropdown-item"><i class="fa fa-clock-o"/>Scroll Speed</a> + <div class="dropdown-menu" role="menu" name="parallax-scroll"> + <a href="#" class="dropdown-item" role="menuitem" data-scroll="0">No-scroll</a> + <div class="dropdown-divider" role="separator"/> + <a href="#" class="dropdown-item" role="menuitem" data-scroll="1">Fixed</a> + <div class="dropdown-divider" role="separator"/> + <a href="#" class="dropdown-item" role="menuitem" data-scroll="0.6">Very Slow</a> + <a href="#" class="dropdown-item" role="menuitem" data-scroll="1.2">Slow</a> + <a href="#" class="dropdown-item" role="menuitem" data-scroll="1.6">Fast</a> + <a href="#" class="dropdown-item" role="menuitem" data-scroll="2">Very Fast</a> + </div> + </div> </div> <div data-js='ul' data-selector=":not(li) > ul:has(ul,ol), :not(li) > ol:has(ul,ol)"> - <li data-toggle-class="o_ul_folded"><a href="#">Folded list</a></li> + <a href="#" class="dropdown-item" data-toggle-class="o_ul_folded">Folded list</a> </div> <div data-js="facebookPage" data-selector=".o_facebook_page"> - <li data-fb-page-options="true" data-no-preview="true"> - <a href="#"><i class="fa fa-facebook"/>Options</a> - </li> + <a href="#" class="dropdown-item" data-fb-page-options="true" data-no-preview="true"><i class="fa fa-facebook"/>Options</a> </div> <div data-js='collapse' diff --git a/addons/website/views/website_navbar_templates.xml b/addons/website/views/website_navbar_templates.xml index 89edb16a756..a96dcecf68f 100644 --- a/addons/website/views/website_navbar_templates.xml +++ b/addons/website/views/website_navbar_templates.xml @@ -9,20 +9,26 @@ <nav groups="base.group_user" t-if="website and menu_data" id="oe_main_menu_navbar" class="o_main_navbar"> <ul id="oe_applications"> <li class="dropdown active"> - <a class="dropdown full" data-toggle="dropdown" href="#"> - <i class="fa fa-th-large"/> WEBSITE <b class="caret"/> + <a class="dropdown-toggle full" data-toggle="dropdown" href="#"> + <i class="fa fa-th-large"/> WEBSITE </a> - <ul class="dropdown-menu" role="menu"> - <li t-as="menu" t-foreach="menu_data['children']"> - <t t-set="debug_param" t-value="'?&debug=' if debug else ''"/> - <a role="menuitem" t-att-class="'oe_menu_toggler' if menu.get('children') else 'oe_menu_leaf'" t-att-data-action-id="menu['action'] and menu['action'].split(',')[1] or None" t-att-data-action-model="menu['action'] and menu['action'].split(',')[0] or None" t-att-data-menu="menu['id']" t-att-data-menu-xmlid="menu.get('xmlid')" t-att-href="'/web%s#menu_id=%s&action=%s' % (debug_param, menu['id'], menu['action'] and menu['action'].split(',')[1] or '')"> + <div class="dropdown-menu" role="menu"> + <t t-set="debug_param" t-value="'?&debug=' if debug else ''"/> + <t t-as="menu" t-foreach="menu_data['children']"> + <a role="menuitem" + t-attf-class="dropdown-item #{'oe_menu_toggler' if menu.get('children') else 'oe_menu_leaf'}" + t-att-data-action-id="menu['action'] and menu['action'].split(',')[1] or None" + t-att-data-action-model="menu['action'] and menu['action'].split(',')[0] or None" + t-att-data-menu="menu['id']" + t-att-data-menu-xmlid="menu.get('xmlid')" + t-att-href="'/web%s#menu_id=%s&action=%s' % (debug_param, menu['id'], menu['action'] and menu['action'].split(',')[1] or '')"> <i t-attf-class="fa #{menu.get('icon')} fa-lg fa-fw" t-if="menu.get('icon')" role="img" aria-label="Menu" title="Menu"/> <span class="oe_menu_text"> <t t-esc="menu['name']"/> </span> </a> - </li> - </ul> + </t> + </div> </li> </ul> @@ -31,30 +37,30 @@ <ul class="o_menu_sections" groups="website.group_website_designer"> <!-- Content --> <li t-if="editable" class="dropdown" id="content-menu"> - <a id="content-menu-button" class="dropdown-toggle waves" data-toggle="dropdown" href="#">Content</a> - <ul class="dropdown-menu" role="menu"> - <li><a role="menuitem" data-action="edit_menu" href="#" title="Edit Top Menu">Edit Menu</a></li> - <li><a role="menuitem" href="/website/pages" title="Manage Your Website Pages">Manage Pages</a></li> - <li t-if="deletable" role="separator" class="divider"></li> - <li t-if="deletable"><a role="menuitem" href="#" data-action="page_properties">Page Properties</a></li> - </ul> + <a id="content-menu-button" class="dropdown-toggle o-no-caret waves" data-toggle="dropdown" href="#">Content</a> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" data-action="edit_menu" href="#" title="Edit Top Menu" class="dropdown-item">Edit Menu</a> + <a role="menuitem" href="/website/pages" title="Manage Your Website Pages" class="dropdown-item">Manage Pages</a> + <div t-if="deletable" role="separator" class="dropdown-divider"/> + <a role="menuitem" href="#" data-action="page_properties" class="dropdown-item" t-if="deletable">Page Properties</a> + </div> </li> <!-- Customize --> <li class="dropdown" id="customize-menu"> - <a class="dropdown-toggle waves" data-toggle="dropdown" href="#">Customize</a> - <ul class="dropdown-menu" role="menu"> - <li id="theme_customize"><a role="menuitem" href="#" data-action="customize_theme">Customize Theme</a></li> - <li id="html_editor"><a role="menuitem" href="#" data-action="ace">HTML/CSS Editor</a></li> - <li id="install_apps"><a role="menuitem" href="/web#action=website.action_website_configuration">Settings</a></li> - <li class="divider" role="separator"/> - </ul> + <a class="dropdown-toggle o-no-caret waves" data-toggle="dropdown" href="#">Customize</a> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" href="#" data-action="customize_theme" class="dropdown-item" id="theme_customize">Customize Theme</a> + <a role="menuitem" href="#" data-action="ace" class="dropdown-item" id="html_editor">HTML/CSS Editor</a> + <a role="menuitem" href="/web#action=website.action_website_configuration" class="dropdown-item" id="install_apps">Settings</a> + <div role="separator" class="dropdown-divider"/> + </div> </li> <!-- Promote --> <li class="dropdown" id="promote-menu"> - <a class="dropdown-toggle waves" data-toggle="dropdown" href="#">Promote</a> - <ul class="dropdown-menu oe_promote_menu" role="menu"> - <li><a role="menuitem" data-action="promote-current-page" href="#" title="Promote page on the web">Optimize SEO</a></li> - </ul> + <a class="dropdown-toggle o-no-caret waves" data-toggle="dropdown" href="#">Promote</a> + <div class="dropdown-menu oe_promote_menu" role="menu"> + <a role="menuitem" data-action="promote-current-page" href="#" title="Promote page on the web" class="dropdown-item">Optimize SEO</a> + </div> </li> </ul> @@ -85,15 +91,12 @@ </li> <li t-if="'website_published' in main_object.fields_get() and main_object._name != 'website.page'"> <a role="button" class="btn btn-primary btn-xs dropdown-toggle css_edit_dynamic" data-toggle="dropdown"> - <span class="caret"></span> <span class="sr-only">Toggle Dropdown</span> </a> - <ul class="dropdown-menu" role="menu"> - <li id="edit-in-backend"> - <a role="menuitem" style="text-align: left;" t-attf-href="/web#return_label=Website&view_type=form&model=#{main_object._name}&id=#{main_object.id}&action=#{action}" - class="btn btn-link btn-xs" title='Edit in backend'>Edit in backend</a> - </li> - </ul> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" style="text-align: left;" t-attf-href="/web#return_label=Website&view_type=form&model=#{main_object._name}&id=#{main_object.id}&action=#{action}" + class="dropdown-item btn btn-link btn-xs" title='Edit in backend' id="edit-in-backend">Edit in backend</a> + </div> </li> <li t-if="translatable"> <a data-action="translate" href="#">TRANSLATE</a> diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml index 37f85a2e161..44018c26a39 100644 --- a/addons/website/views/website_templates.xml +++ b/addons/website/views/website_templates.xml @@ -79,13 +79,13 @@ (submenu.clean_url() and request.httprequest.path == submenu.clean_url())) and 'active' }"> <a class="dropdown-toggle" data-toggle="dropdown" href="#"> - <span t-field="submenu.name"/> <span class="caret" t-ignore="true"></span> + <span t-field="submenu.name"/> </a> - <ul class="dropdown-menu" role="menu"> + <div class="dropdown-menu" role="menu"> <t t-foreach="submenu.child_id" t-as="submenu"> <t t-call="website.submenu"/> </t> - </ul> + </div> </li> </template> @@ -314,15 +314,16 @@ <span t-esc="list(filter(lambda lg : lg[0] == lang, languages))[0][1].split('/').pop()"/> <span class="caret ml4"/> </button> - <ul class="dropdown-menu" role="menu"> - <li t-foreach="languages" t-as="lg"> + <div class="dropdown-menu" role="menu"> + <t t-foreach="languages" t-as="lg"> <a t-att-href="url_for(request.httprequest.path + '?' + keep_query(), lang=lg[0])" + class="dropdown-item js_change_lang" t-att-data-default-lang="(editable or translatable) and 'true' if website and lg[0] == website.default_lang_code else None" - t-att-data-lang="lg[0]" class="js_change_lang"> + t-att-data-lang="lg[0]"> <t t-esc="lg[1].split('/').pop()"/> </a> - </li> - </ul> + </t> + </div> </div> </li> <li groups="website.group_website_publisher"> @@ -341,16 +342,12 @@ <div t-attf-class="btn-group #{btn_class} js_publish_management #{object.website_published and 'css_published' or 'css_unpublished'}" t-att-data-id="object.id" t-att-data-object="object._name" t-att-data-controller="publish_controller"> <button class="btn btn-danger js_publish_btn">Unpublished</button> <button class="btn btn-success js_publish_btn">Published</button> - <button type="button" t-attf-class="btn btn-secondary dropdown-toggle" t-att-id="'dopprod-%s' % object.id" data-toggle="dropdown"> - <span class="caret"></span> - </button> - <ul class="dropdown-menu" role="menu" t-att-aria-labelledby="'dopprod-%s' % object.id"> + <button type="button" t-attf-class="btn btn-secondary dropdown-toggle dropdown-toggle-split" t-att-id="'dopprod-%s' % object.id" data-toggle="dropdown"/> + <div class="dropdown-menu" role="menu" t-att-aria-labelledby="'dopprod-%s' % object.id"> <t t-raw="0"/> - <li t-if="publish_edit"> - <a role="menuitem" t-attf-href="/web#return_label=Website&view_type=form&model=#{object._name}&id=#{object.id}&action=#{action}" - title='Edit in backend'>Edit</a> - </li> - </ul> + <a role="menuitem" t-attf-href="/web#return_label=Website&view_type=form&model=#{object._name}&id=#{object.id}&action=#{action}" + title='Edit in backend' class="dropdown-item" t-if="publish_edit">Edit</a> + </div> </div> </div> </template> @@ -879,18 +876,19 @@ Sitemap: <t t-esc="url_root"/>sitemap.xml <t t-call="website.website_search_box"/> </form> <div t-if="searchbar_sortings" class="dropdown pull-right mt8 mr8"> - <button class="btn btn-secondary" type="button" data-toggle="dropdown"> + <button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown"> <span class="fa fa-sort fa-lg" role="img" aria-label="Sort" title="Sort"/> <span class="d-none d-xl-inline" t-esc="searchbar_sortings[sortby].get('label', 'Newest')"/> - <span class="caret" role="img" aria-label="Dropdown menu" title="Dropdown menu"></span> </button> - <ul class="dropdown-menu" role="menu" aria-labelledby="portal_searchbar_sortby"> - <li t-foreach="searchbar_sortings" t-as="option" t-attf-class="#{sortby == option and 'active'}"> - <a role="menuitem" t-att-href="request.httprequest.path + '?' + keep_query('*', sortby=option)"> + <div class="dropdown-menu" aria-labelledby="portal_searchbar_sortby" role="menu"> + <t t-foreach="searchbar_sortings" t-as="option"> + <a role="menuitem" + t-att-href="request.httprequest.path + '?' + keep_query('*', sortby=option)" + t-attf-class="dropdown-item#{sortby == option and ' active' or ''}"> <span t-esc="searchbar_sortings[option].get('label')"/> </a> - </li> - </ul> + </t> + </div> </div> <h3 class="mt16">Manage Your Pages</h3> <t t-if="not pages"> diff --git a/addons/website_blog/views/snippets.xml b/addons/website_blog/views/snippets.xml index eee8bccc9b2..6366b9c5458 100644 --- a/addons/website_blog/views/snippets.xml +++ b/addons/website_blog/views/snippets.xml @@ -3,36 +3,36 @@ <template id="website_blog" inherit_id="website.snippets" name="Snippet Blog"> <xpath expr="//div[@id='snippet_options']" position="inside"> <div data-js="blog_cover" data-selector=".website_blog .o_blog_cover_container" data-no-check="true"> - <li data-change="true" data-no-preview="true"><a href="#">Change Cover</a></li> - <li data-clear="true" data-no-preview="true"><a href="#" >No Cover</a></li> + <a href="#" class="dropdown-item" data-change="true" data-no-preview="true">Change Cover</a> + <a href="#" class="dropdown-item" data-clear="true" data-no-preview="true">No Cover</a> <li class="dropdown-submenu"> <a href="#">Size</a> - <ul class="dropdown-menu" role="menu"> - <li data-select-class="cover container-fluid cover_full"><a role="menuitem" href="#">Full Screen</a></li> - <li data-select-class="cover container-fluid cover_narrow"><a role="menuitem" href="#">Mid screen</a></li> - <li data-select-class="cover container cover_narrow"><a role="menuitem" href="#">Narrow</a></li> - </ul> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" href="#" class="dropdown-item" data-select-class="cover container-fluid cover_full">Full Screen</a> + <a role="menuitem" href="#" class="dropdown-item" data-select-class="cover container-fluid cover_narrow">Mid screen</a> + <a role="menuitem" href="#" class="dropdown-item" data-select-class="cover container cover_narrow">Narrow</a> + </div> </li> <li class="dropdown-submenu"> <a href="#">Filter Intensity</a> - <ul class="dropdown-menu" role="menu"> - <li data-filter_value="0.0"><a role="menuitem" href="#">None</a></li> - <li data-filter_value="0.2"><a role="menuitem" href="#">Low</a></li> - <li data-filter_value="0.4"><a role="menuitem" href="#">Medium</a></li> - <li data-filter_value="0.6"><a role="menuitem" href="#">High</a></li> - </ul> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" href="#" class="dropdown-item" data-filter_value="0.0">None</a> + <a role="menuitem" href="#" class="dropdown-item" data-filter_value="0.2">Low</a> + <a role="menuitem" href="#" class="dropdown-item" data-filter_value="0.4">Medium</a> + <a role="menuitem" href="#" class="dropdown-item" data-filter_value="0.6">High</a> + </div> </li> <li class="dropdown-submenu"> <a href="#">Filter Color</a> - <ul class="dropdown-menu" role="menu"> - <li data-filter_color="oe_black"><a role="menuitem" href="#">Black</a></li> - <li data-filter_color="oe_none"><a role="menuitem" href="#">White</a></li> - <li data-filter_color="oe_blue"><a role="menuitem" href="#">Blue</a></li> - <li data-filter_color="oe_yellow"><a role="menuitem" href="#">Yellow</a></li> - <li data-filter_color="oe_red"><a role="menuitem" href="#">Red</a></li> - <li data-filter_color="oe_purple"><a role="menuitem" href="#">Purple</a></li> - <li data-filter_color="oe_green"><a role="menuitem" href="#">Green</a></li> - </ul> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" href="#" class="dropdown-item" data-filter_color="oe_black">Black</a> + <a role="menuitem" href="#" class="dropdown-item" data-filter_color="oe_none">White</a> + <a role="menuitem" href="#" class="dropdown-item" data-filter_color="oe_blue">Blue</a> + <a role="menuitem" href="#" class="dropdown-item" data-filter_color="oe_yellow">Yellow</a> + <a role="menuitem" href="#" class="dropdown-item" data-filter_color="oe_red">Red</a> + <a role="menuitem" href="#" class="dropdown-item" data-filter_color="oe_purple">Purple</a> + <a role="menuitem" href="#" class="dropdown-item" data-filter_color="oe_green">Green</a> + </div> </li> </div> </xpath> diff --git a/addons/website_blog/views/website_blog_templates.xml b/addons/website_blog/views/website_blog_templates.xml index b1ebc6cfc8a..1aa02994a5a 100644 --- a/addons/website_blog/views/website_blog_templates.xml +++ b/addons/website_blog/views/website_blog_templates.xml @@ -213,14 +213,14 @@ <!-- Blog Post Complete --> <template id="blog_edit_options" inherit_id="website.user_navbar" name="Edit Blog Options"> - <xpath expr="//li[@id='edit-in-backend']" position="after"> - <li groups="website.group_website_designer" t-if="main_object._name == 'blog.post'"> + <xpath expr="//a[@id='edit-in-backend']" position="after"> + <t groups="website.group_website_designer" t-if="main_object._name == 'blog.post'"> <form class="duplicate d-none" action="/blog/post_duplicate" method="POST"> <input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/> <input name="blog_post_id" t-att-value="blog_post.id if blog_post else None"/> </form> - <a href="#" class="duplicate" onclick="$(this).prev('form').submit()">Duplicate</a> - </li> + <a href="#" class="duplicate dropdown-item" onclick="$(this).prev('form').submit()">Duplicate</a> + </t> </xpath> </template> <template id="blog_post_complete" name="Blog Post"> diff --git a/addons/website_event_track/views/event_track_views.xml b/addons/website_event_track/views/event_track_views.xml index efdeb374d04..d0ce53a11e8 100644 --- a/addons/website_event_track/views/event_track_views.xml +++ b/addons/website_event_track/views/event_track_views.xml @@ -18,15 +18,15 @@ <div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click"> <div class="o_dropdown_kanban dropdown" groups="base.group_user"> - <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> + <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> <span class="fa fa-ellipsis-v"/> </a> - <ul class="dropdown-menu" role="menu"> - <li><a role="menuitem" t-att-href="record.website_url.value">View Track</a></li> - <t t-if="widget.editable"><li><a role="menuitem" type="edit">Edit Track</a></li></t> - <t t-if="widget.deletable"><li><a role="menuitem" type="delete">Delete</a></li></t> - <li role="menuitem" aria-haspopup="true"><ul role="menu" class="oe_kanban_colorpicker" data-field="color"/></li> - </ul> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" t-att-href="record.website_url.value" class="dropdown-item">View Track</a> + <t t-if="widget.editable"><a role="menuitem" type="edit" class="dropdown-item">Edit Track</a></t> + <t t-if="widget.deletable"><a role="menuitem" type="delete" class="dropdown-item">Delete</a></t> + <ul class="oe_kanban_colorpicker" data-field="color"/> + </div> </div> <div class="oe_kanban_content"> <div class="o_kanban_record_top"> diff --git a/addons/website_forum/views/website_forum.xml b/addons/website_forum/views/website_forum.xml index a2a109ea9f4..200e26bb1d1 100644 --- a/addons/website_forum/views/website_forum.xml +++ b/addons/website_forum/views/website_forum.xml @@ -90,10 +90,10 @@ <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown"> <i class="fa fa-cog" role="img" aria-label="Dropdown menu" title="Dropdown menu"/> </button> - <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1"> - <li><a role="menuitem" tabindex="-1" t-attf-href="/forum/#{slug(forum)}/edit_welcome_message?enable_editor=1">Design Welcome Message</a></li> - <li><a role="menuitem" tabindex="-1" t-attf-href="/web#id=#{forum.id}&view_type=form&model=forum.forum">Forum Settings</a></li> - </ul> + <div class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1"> + <a role="menuitem" tabindex="-1" t-attf-href="/forum/#{slug(forum)}/edit_welcome_message?enable_editor=1" class="dropdown-item">Design Welcome Message</a> + <a role="menuitem" tabindex="-1" t-attf-href="/web#id=#{forum.id}&view_type=form&model=forum.forum" class="dropdown-item">Forum Settings</a> + </div> </span> </form> </li> @@ -137,14 +137,13 @@ </a> <t t-if="multi_type"> <button type="button" class="btn btn-primary btn-lg col-sm-2 dropdown-toggle" data-toggle="dropdown"> - <span class="caret"></span> <span class="sr-only">Select Post</span> </button> - <ul class="dropdown-menu" role="menu"> - <li t-if="forum.allow_question"><a role="menuitem" t-attf-href="/forum/#{slug(forum)}/ask?post_type=question">Ask a Question</a></li> - <li t-if="forum.allow_link"><a role="menuitem" t-attf-href="/forum/#{slug(forum)}/ask?post_type=link">Submit a Link</a></li> - <li t-if="forum.allow_discussion"><a role="menuitem" t-attf-href="/forum/#{slug(forum)}/ask?post_type=discussion">New Discussion</a></li> - </ul> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" t-attf-href="/forum/#{slug(forum)}/ask?post_type=question" class="dropdown-item" t-if="forum.allow_question">Ask a Question</a> + <a role="menuitem" t-attf-href="/forum/#{slug(forum)}/ask?post_type=link" class="dropdown-item" t-if="forum.allow_link">Submit a Link</a> + <a role="menuitem" t-attf-href="/forum/#{slug(forum)}/ask?post_type=discussion" class="dropdown-item" t-if="forum.allow_discussion">New Discussion</a> + </div> </t> </div> <div class="panel panel-default"> @@ -418,40 +417,21 @@ <t t-if="sorting == 'create_date desc'"> by newest</t> <t t-if="sorting == 'child_count desc'"> by most answered</t> <t t-if="sorting == 'vote_count desc'"> by most voted</t> - <b class="caret"/> </a> - <ul class="dropdown-menu" role="menu"> - <li role="separator" class="dropdown-header">Filter on</li> - <li t-att-class="filters == 'all' and 'active' or None "> - <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', filters='all')">All</a> - </li> - <li t-att-class="filters == 'unanswered' and 'active' or None "> - <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', filters='unanswered')">Unanswered</a> - </li> - <li t-if="uid" t-att-class="filters == 'followed' and 'active' or None "> - <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', filters='followed')">Followed</a> - </li> - <li role="separator" t-if="tag" class="dropdown-header">Tags</li> - <li t-if="tag" t-att-class="tag and 'active' or None "> - <a role="menuitem" href=""><t t-esc="tag.name"/></a> - </li> - <li role="separator" class="dropdown-header">Sort by</li> - <li t-att-class="sorting == 'relevancy desc' and 'active' or None "> - <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='relevancy desc')">Relevance</a> - </li> - <li t-att-class="sorting == 'write_date desc' and 'active' or None "> - <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='write_date desc')">Last activity date</a> - </li> - <li t-att-class="sorting == 'create_date desc' and 'active' or None "> - <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='create_date desc')">Newest</a> - </li> - <li t-att-class="sorting == 'child_count desc' and 'active' or None "> - <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='child_count desc')">Most answered</a> - </li> - <li t-att-class="sorting == 'vote_count desc' and 'active' or None "> - <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='vote_count desc')">Most voted</a> - </li> - </ul> + <div class="dropdown-menu" role="menu"> + <div role="separator" class="dropdown-header">Filter on</div> + <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', filters='all')" t-attf-class="dropdown-item#{filters == 'all' and ' active' or ''}">All</a> + <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', filters='unanswered')" t-attf-class="dropdown-item#{filters == 'unanswered' and ' active' or ''}">Unanswered</a> + <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', filters='followed')" t-if="uid" t-attf-class="dropdown-item#{filters == 'followed' and ' active' or ''}">Followed</a> + <div role="separator" t-if="tag" class="dropdown-header">Tags</div> + <a role="menuitem" href="" t-if="tag" t-attf-class="dropdown-item#{tag and ' active' or None}"><t t-esc="tag.name"/></a> + <div role="separator" class="dropdown-header">Sort by</div> + <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='relevancy desc')" t-attf-class="dropdown-item#{sorting == 'relevancy desc' and ' active' or ''}">Relevance</a> + <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='write_date desc')" t-attf-class="dropdown-item#{sorting == 'write_date desc' and ' active' or ''}">Last activity date</a> + <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='create_date desc')" t-attf-class="dropdown-item#{sorting == 'create_date desc' and ' active' or ''}">Newest</a> + <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='child_count desc')" t-attf-class="dropdown-item#{sorting == 'child_count desc' and ' active' or ''}">Most answered</a> + <a role="menuitem" t-att-href="url_for('') + '?' + keep_query( 'search', 'filters', sorting='vote_count desc')" t-attf-class="dropdown-item#{sorting == 'vote_count desc' and ' active' or ''}">Most voted</a> + </div> </small> </h2> <div t-foreach="question_ids" t-as="question" class="mb16"> @@ -1220,19 +1200,12 @@ <t t-if="queue_type == 'validation'"> Pending</t> <t t-if="queue_type == 'flagged'"> Flagged</t> <t t-if="queue_type == 'offensive'"> Offensive</t> - <b class="caret"/> </a> - <ul class="dropdown-menu" role="menu"> - <li t-att-class="queue_type == 'validation' and 'active' or None "> - <a role="menuitem" data-type='validation' t-attf-href="/forum/#{slug(forum)}/validation_queue">Pending</a> - </li> - <li t-att-class="queue_type == 'flagged' and 'active' or None "> - <a role="menuitem" data-type='flagged' t-attf-href="/forum/#{slug(forum)}/flagged_queue">Flagged</a> - </li> - <li t-if="uid" t-att-class="queue_type == 'offensive' and 'active' or None "> - <a role="menuitem" data-type='offensive' t-attf-href="/forum/#{slug(forum)}/offensive_posts">Offensive</a> - </li> - </ul> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" data-type='validation' t-attf-href="/forum/#{slug(forum)}/validation_queue" t-attf-class="dropdown-item#{queue_type == 'validation' and ' active' or ''}">Pending</a> + <a role="menuitem" data-type='flagged' t-attf-href="/forum/#{slug(forum)}/flagged_queue" t-attf-class="dropdown-item#{queue_type == 'flagged' and ' active' or ''}">Flagged</a> + <a role="menuitem" data-type='offensive' t-attf-href="/forum/#{slug(forum)}/offensive_posts" t-if="uid" t-attf-class="dropdown-item#{queue_type == 'offensive' and ' active' or ''}">Offensive</a> + </div> </span> </h2> <div class="text-center" t-if="count_posts == 0"> diff --git a/addons/website_forum_doc/views/doc.xml b/addons/website_forum_doc/views/doc.xml index eca1b5811ae..a0a2f037269 100644 --- a/addons/website_forum_doc/views/doc.xml +++ b/addons/website_forum_doc/views/doc.xml @@ -37,14 +37,14 @@ <t t-name="kanban-box"> <div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click"> <div class="o_dropdown_kanban dropdown" groups="base.group_user"> - <a role="button" class="dropdown-toggle btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> + <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> <span class="fa fa-ellipsis-v"/> </a> - <ul class="dropdown-menu" role="menu"> - <li t-if="widget.editable"><a type="edit" role="menuitem">Edit Post</a></li> - <li t-if="widget.deletable"><a type="delete" role="menuitem">Delete</a></li> - <li role="menuitem" aria-haspopup="true"><ul role="menu" class="oe_kanban_colorpicker" data-field="color"/></li> - </ul> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" type="edit" class="dropdown-item" t-if="widget.editable">Edit Post</a> + <a role="menuitem" type="delete" class="dropdown-item" t-if="widget.deletable">Delete</a> + <ul class="oe_kanban_colorpicker" data-field="color"/> + </div> </div> <div class="o_kanban_record_top"> <b class="o_kanban_record_title"><field name="name"/></b> diff --git a/addons/website_hr_recruitment/views/website_hr_recuitment_snippets.xml b/addons/website_hr_recruitment/views/website_hr_recuitment_snippets.xml index 6480e2b5a16..fda2c310a32 100644 --- a/addons/website_hr_recruitment/views/website_hr_recuitment_snippets.xml +++ b/addons/website_hr_recruitment/views/website_hr_recuitment_snippets.xml @@ -34,25 +34,25 @@ <div data-js='s_hr_rating_option_type' data-selector=".s_hr_rating" data-drop-in="[class^='col-']"> <li class="dropdown-submenu"> <a tabindex="-1" href="#">Rating type</a> - <ul class="dropdown-menu" role="menu"> - <li data-select_class="s_hr_rating_stars"><a role="menuitem" href="#"><i class="fa fa-star"/> Stars</a></li> - <li data-select_class="s_hr_rating_bolts"><a role="menuitem" href="#"><i class="fa fa-bolt"/> Bolts</a></li> - <li data-select_class="s_hr_rating_hearts"><a role="menuitem" href="#"><i class="fa fa-heart"/> Hearts</a></li> - <li data-select_class="s_hr_rating_bar"><a role="menuitem" href="#"><i class="fa fa-tasks"/> Bar</a></li> - </ul> + <div class="dropdown-menu" role="menu"> + <a href="#" class="dropdown-item" data-select_class="s_hr_rating_stars" role="menuitem"><i class="fa fa-star"/> Stars</a> + <a href="#" class="dropdown-item" data-select_class="s_hr_rating_bolts" role="menuitem"><i class="fa fa-bolt"/> Bolts</a> + <a href="#" class="dropdown-item" data-select_class="s_hr_rating_hearts" role="menuitem"><i class="fa fa-heart"/> Hearts</a> + <a href="#" class="dropdown-item" data-select_class="s_hr_rating_bar" role="menuitem"><i class="fa fa-tasks"/> Bar</a> + </div> </li> </div> <div data-js='s_hr_rating_option_value' data-selector=".s_hr_rating"> <li class="dropdown-submenu"> <a tabindex="-1" href="#">Rating value</a> - <ul class="dropdown-menu" role="menu"> - <li data-select_class=""><a role="menuitem" href="#">0</a></li> - <li data-select_class="s_hr_rating_1"><a role="menuitem" href="#">1/5</a></li> - <li data-select_class="s_hr_rating_2"><a role="menuitem" href="#">2/5</a></li> - <li data-select_class="s_hr_rating_3"><a role="menuitem" href="#">3/5</a></li> - <li data-select_class="s_hr_rating_4"><a role="menuitem" href="#">4/5</a></li> - <li data-select_class="s_hr_rating_5"><a role="menuitem" href="#">5/5</a></li> - </ul> + <div class="dropdown-menu" role="menu"> + <a href="#" class="dropdown-item" role="menuitem" data-select_class="">0</a> + <a href="#" class="dropdown-item" role="menuitem" data-select_class="s_hr_rating_1">1/5</a> + <a href="#" class="dropdown-item" role="menuitem" data-select_class="s_hr_rating_2">2/5</a> + <a href="#" class="dropdown-item" role="menuitem" data-select_class="s_hr_rating_3">3/5</a> + <a href="#" class="dropdown-item" role="menuitem" data-select_class="s_hr_rating_4">4/5</a> + <a href="#" class="dropdown-item" role="menuitem" data-select_class="s_hr_rating_5">5/5</a> + </div> </li> </div> </xpath> diff --git a/addons/website_links/views/website_links_template.xml b/addons/website_links/views/website_links_template.xml index 2e1525a3280..3c7b329db56 100644 --- a/addons/website_links/views/website_links_template.xml +++ b/addons/website_links/views/website_links_template.xml @@ -11,12 +11,10 @@ </template> <template id="share_page_menu" inherit_id="website.user_navbar"> - <xpath expr="//li/a[@data-action='promote-current-page']/.." position="after"> - <li> - <a href="/r" id="o_website_links_share_page"> - <span title="Track this page to count clicks">Track this Page</span> - </a> - </li> + <xpath expr="//a[@data-action='promote-current-page']" position="after"> + <a href="/r" id="o_website_links_share_page" class="dropdown-item"> + <span title="Track this page to count clicks">Track this Page</span> + </a> </xpath> </template> diff --git a/addons/website_sale/static/src/js/website_sale_tour_shop.js b/addons/website_sale/static/src/js/website_sale_tour_shop.js index 72beb5999d8..d166367d23d 100644 --- a/addons/website_sale/static/src/js/website_sale_tour_shop.js +++ b/addons/website_sale/static/src/js/website_sale_tour_shop.js @@ -63,7 +63,7 @@ odoo.define("website_sale.tour_shop", function (require) { content: _t("Click on this button so your customers can see it."), position: "bottom", }, { - trigger: ".o_main_navbar .o_menu_toggle, #oe_applications .dropdown.full", + trigger: ".o_main_navbar .o_menu_toggle, #oe_applications .dropdown-toggle", content: _t("Let's now take a look at your administration dashboard to get your eCommerce website ready in no time."), position: "bottom", }, { diff --git a/addons/website_sale/static/src/js/website_sale_tracking.js b/addons/website_sale/static/src/js/website_sale_tracking.js index 52d65a468fc..fb7a095cce6 100644 --- a/addons/website_sale/static/src/js/website_sale_tracking.js +++ b/addons/website_sale/static/src/js/website_sale_tracking.js @@ -26,7 +26,7 @@ $(document).ready(function () { }); $(".oe_website_sale form[action='/shop/confirm_order'] a.a-submit").on('click', function(o) { - if ($("#top_menu > li > a[href='/web/login']").length){ + if ($("#top_menu [href='/web/login']").length){ vpv("/stats/ecom/customer_signup"); } vpv("/stats/ecom/order_checkout"); diff --git a/addons/website_sale/views/snippets.xml b/addons/website_sale/views/snippets.xml index f19ba2f051a..1fb5f776501 100644 --- a/addons/website_sale/views/snippets.xml +++ b/addons/website_sale/views/snippets.xml @@ -9,30 +9,30 @@ <li class='dropdown-submenu'> <a tabindex="-1" href="#">Size</a> - <ul class="dropdown-menu" role="menu" name="size"> - <li><a role="menuitem" href="#"> + <div class="dropdown-menu" role="menu" name="size"> + <a href="#" role="menuitem" class="dropdown-item"> <table> <tr><td class="selected"></td><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td><td></td></tr> </table> - </a></li> - </ul> + </a> + </div> </li> <li class='dropdown-submenu' role="menuitem" aria-haspopup="true"> <a tabindex="-1" href="#">Styles</a> - <ul class="dropdown-menu" role="menu" name="style"> - </ul> + <div class="dropdown-menu" role="menu" name="style"> + </div> </li> <li class='dropdown-submenu' role="menuitem" aria-haspopup="true"> <a tabindex="-1" href="#">Promote</a> - <ul class="dropdown-menu" role="menu" data-no-preview="true"> - <li data-go_to="top"><a role="menuitem">Push to top</a></li> - <li data-go_to="up"><a role="menuitem">Push up</a></li> - <li data-go_to="down"><a role="menuitem">Push down</a></li> - <li data-go_to="bottom"><a role="menuitem">Push to bottom</a></li> - </ul> + <div class="dropdown-menu" role="menu" data-no-preview="true"> + <a href="#" class="dropdown-item" role="menuitem" data-go_to="top">Push to top</a> + <a href="#" class="dropdown-item" role="menuitem" data-go_to="up">Push up</a> + <a href="#" class="dropdown-item" role="menuitem" data-go_to="down">Push down</a> + <a href="#" class="dropdown-item" role="menuitem" data-go_to="bottom">Push to bottom</a> + </div> </li> </div> </xpath> diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml index d3e703af08d..d8c3b3442ab 100644 --- a/addons/website_sale/views/templates.xml +++ b/addons/website_sale/views/templates.xml @@ -159,15 +159,14 @@ <t t-set="curr_pl" t-value="website.get_current_pricelist()" /> <a role="button" href="#" class="dropdown-toggle btn btn-secondary" data-toggle="dropdown"> <t t-esc="curr_pl and curr_pl.name or ' - '" /> - <span class="caret"></span> </a> - <ul class="dropdown-menu" role="menu"> - <li t-foreach="website_sale_pricelists" t-as="pl"> - <a role="menuitem" t-att-href="'/shop/change_pricelist/%s' % pl.id"> + <div class="dropdown-menu" role="menu"> + <t t-foreach="website_sale_pricelists" t-as="pl"> + <a role="menuitem" t-att-href="'/shop/change_pricelist/%s' % pl.id" class="dropdown-item"> <span class="switcher_pricelist" t-att-data-pl_id="pl.id" t-esc="pl.name" /> </a> - </li> - </ul> + </t> + </div> </div> </template> @@ -253,16 +252,15 @@ </t> <t t-else='1'> <span>Sort by</span> - <span class="caret"></span> </t> </a> - <ul class="dropdown-menu" role="menu"> - <li t-foreach="website_sale_sortable" t-as="sortby"> - <a role="menuitem" t-att-href="keep('/shop', order=sortby[1])"> + <div class="dropdown-menu" role="menu"> + <t t-foreach="website_sale_sortable" t-as="sortby"> + <a role="menuitem" t-att-href="keep('/shop', order=sortby[1])" class="dropdown-item"> <span t-raw="sortby[0]"/> </a> - </li> - </ul> + </t> + </div> </div> </xpath> </template> diff --git a/addons/website_sale_digital/views/website_sale_digital.xml b/addons/website_sale_digital/views/website_sale_digital.xml index 92415355916..cf6e541cd7f 100644 --- a/addons/website_sale_digital/views/website_sale_digital.xml +++ b/addons/website_sale_digital/views/website_sale_digital.xml @@ -6,13 +6,13 @@ <t t-if="attachments"> <span class="dropdown"> <button class="btn btn-xs btn-secondary dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown"> - Downloads <span class="caret"></span> + Downloads </button> - <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1"> + <div class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1"> <t t-foreach="attachments" t-as="a"> - <li><a role="menuitem" tabindex="-1" t-att-href="'/my/download?attachment_id=%i' % a['id']"><t t-esc="a['name']"/></a></li> + <a role="menuitem" tabindex="-1" t-att-href="'/my/download?attachment_id=%i' % a['id']" class="dropdown-item"><t t-esc="a['name']"/></a> </t> - </ul> + </div> </span> </t> </xpath> diff --git a/addons/website_sale_link_tracker/static/src/xml/website_sale_dashboard_utm_chart.xml b/addons/website_sale_link_tracker/static/src/xml/website_sale_dashboard_utm_chart.xml index 73fa0bc3019..e9e9bc88e99 100644 --- a/addons/website_sale_link_tracker/static/src/xml/website_sale_dashboard_utm_chart.xml +++ b/addons/website_sale_link_tracker/static/src/xml/website_sale_dashboard_utm_chart.xml @@ -20,13 +20,13 @@ <t t-name="website_sale.LinkTrackersDropDown"> <div class="dropdown"> - <button class="btn btn-secondary dropdown-toggle utm_dropdown ml4" id="utm_dropdown" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"><span class="utm_button_name">Campaigns</span><span class="caret ml4"/> + <button class="btn btn-secondary dropdown-toggle utm_dropdown ml4" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"><span class="utm_button_name">Campaigns</span> </button> - <ul class="dropdown-menu" role="menu" aria-labelledby="utm_dropdown"> - <li><a role="menuitem" class="js_utm_selector" name="campaign_id">Campaigns</a></li> - <li><a role="menuitem" class="js_utm_selector" name="medium_id">Medium</a></li> - <li><a role="menuitem" class="js_utm_selector" name="source_id">Sources</a></li> - </ul> + <div class="dropdown-menu" role="menu" aria-labelledby="utm_dropdown"> + <a name="campaign_id" class="dropdown-item js_utm_selector" role="menuitem">Campaigns</a> + <a name="medium_id" class="dropdown-item js_utm_selector" role="menuitem">Medium</a> + <a name="source_id" class="dropdown-item js_utm_selector" role="menuitem">Sources</a> + </div> </div> </t> </templates> diff --git a/addons/website_theme_install/static/src/scss/website_theme_install.scss b/addons/website_theme_install/static/src/scss/website_theme_install.scss index ea84164b6e5..721b6f33528 100644 --- a/addons/website_theme_install/static/src/scss/website_theme_install.scss +++ b/addons/website_theme_install/static/src/scss/website_theme_install.scss @@ -125,7 +125,7 @@ color: $text-color; } - &:hover, &.open { + &:hover, &.show { .o_kanban_config { display: none; } |
