From ef313061301948693bfbeb16e8ccca786e5251f4 Mon Sep 17 00:00:00 2001 From: "stefanorigano (SRI)" Date: Sun, 7 May 2023 08:01:43 +0000 Subject: [PATCH] [REF] web, mail: badges design Part-of: odoo/odoo#116641 --- .../calendar/static/tests/calendar_tests.js | 4 +- .../many2many_avatar_user_field.scss | 7 +- .../many2many_avatar_user_field.xml | 1 - .../many2many_tags_email.xml | 2 +- .../static/src/core/colorlist/colorlist.js | 14 ++-- .../static/src/core/colorlist/colorlist.scss | 19 +---- .../static/src/core/colorlist/colorlist.xml | 4 +- .../static/src/core/tags_list/tags_list.js | 1 + .../static/src/core/tags_list/tags_list.scss | 61 +++------------- .../static/src/core/tags_list/tags_list.xml | 26 ++++--- addons/web/static/src/legacy/scss/fields.scss | 16 ---- addons/web/static/src/legacy/scss/utils.scss | 16 +--- .../static/src/scss/bootstrap_overridden.scss | 2 +- .../static/src/scss/primary_variables.scss | 2 +- .../static/src/scss/secondary_variables.scss | 4 +- .../kanban_many2many_tags_field.xml | 4 +- .../many2many_tags/many2many_tags_field.js | 6 +- .../many2many_tags/many2many_tags_field.scss | 19 ----- .../many2many_tags/many2many_tags_field.xml | 2 +- .../many2many_tags_avatar_field.scss | 73 +++---------------- .../views/fields/properties/property_tags.xml | 3 +- .../web/static/src/webclient/webclient.scss | 1 + .../web/static/tests/core/colorlist_tests.js | 4 +- .../many2many_tags_avatar_field_tests.js | 8 +- 24 files changed, 78 insertions(+), 221 deletions(-) diff --git a/addons/calendar/static/tests/calendar_tests.js b/addons/calendar/static/tests/calendar_tests.js index b65bbba217e..8398e2a5ffb 100644 --- a/addons/calendar/static/tests/calendar_tests.js +++ b/addons/calendar/static/tests/calendar_tests.js @@ -91,11 +91,11 @@ QUnit.module( ); assert.containsN( target, - '.o_field_widget[name="partner_ids"] .badge', + '.o_field_widget[name="partner_ids"] .o_tag', 2, "there should be 2 tags" ); - const badges = target.querySelectorAll('.o_field_widget[name="partner_ids"] .badge'); + const badges = target.querySelectorAll('.o_field_widget[name="partner_ids"] .o_tag'); assert.strictEqual( badges[0].textContent.trim(), "Jesus", diff --git a/addons/mail/static/src/web/fields/many2many_avatar_user_field/many2many_avatar_user_field.scss b/addons/mail/static/src/web/fields/many2many_avatar_user_field/many2many_avatar_user_field.scss index 71d6c0d0c5e..93adabeccf5 100644 --- a/addons/mail/static/src/web/fields/many2many_avatar_user_field/many2many_avatar_user_field.scss +++ b/addons/mail/static/src/web/fields/many2many_avatar_user_field/many2many_avatar_user_field.scss @@ -11,14 +11,11 @@ color: inherit; margin-right: 0px; } - - .o_m2m_avatar, .o_m2m_avatar_empty { + + .o_m2m_avatar_empty { width: 20px; height: 20px; margin-left: 0px; - } - - .o_m2m_avatar_empty { background-color: $o-gray-300; vertical-align: bottom; } diff --git a/addons/mail/static/src/web/fields/many2many_avatar_user_field/many2many_avatar_user_field.xml b/addons/mail/static/src/web/fields/many2many_avatar_user_field/many2many_avatar_user_field.xml index 58193422aba..0fa9b6cbe56 100644 --- a/addons/mail/static/src/web/fields/many2many_avatar_user_field/many2many_avatar_user_field.xml +++ b/addons/mail/static/src/web/fields/many2many_avatar_user_field/many2many_avatar_user_field.xml @@ -21,7 +21,6 @@ - !props.readonly displayText diff --git a/addons/mail/static/src/web/fields/many2many_tags_email/many2many_tags_email.xml b/addons/mail/static/src/web/fields/many2many_tags_email/many2many_tags_email.xml index 575c1b9b912..02fb4bfbbb6 100644 --- a/addons/mail/static/src/web/fields/many2many_tags_email/many2many_tags_email.xml +++ b/addons/mail/static/src/web/fields/many2many_tags_email/many2many_tags_email.xml @@ -1,7 +1,7 @@ - +
diff --git a/addons/web/static/src/core/colorlist/colorlist.js b/addons/web/static/src/core/colorlist/colorlist.js index 1c3ba27d9e7..830cf649f0b 100644 --- a/addons/web/static/src/core/colorlist/colorlist.js +++ b/addons/web/static/src/core/colorlist/colorlist.js @@ -40,14 +40,14 @@ ColorList.COLORS = [ _lt("Red"), _lt("Orange"), _lt("Yellow"), - _lt("Light blue"), - _lt("Dark purple"), - _lt("Salmon pink"), - _lt("Medium blue"), - _lt("Dark blue"), - _lt("Fuchsia"), - _lt("Green"), + _lt("Cyan"), _lt("Purple"), + _lt("Almond"), + _lt("Teal"), + _lt("Blue"), + _lt("Raspberry"), + _lt("Green"), + _lt("Violet"), ]; ColorList.template = "web.ColorList"; ColorList.defaultProps = { diff --git a/addons/web/static/src/core/colorlist/colorlist.scss b/addons/web/static/src/core/colorlist/colorlist.scss index cd28f4e57ab..2e7f864f845 100644 --- a/addons/web/static/src/core/colorlist/colorlist.scss +++ b/addons/web/static/src/core/colorlist/colorlist.scss @@ -1,6 +1,6 @@ .o_colorlist { button { - border: 1px solid $white; + border: 1px solid $dropdown-bg; box-shadow: 0 0 0 1px $gray-500; width: 22px; height: 17px; @@ -13,23 +13,12 @@ // Set all the colors but the "no-color" one @for $size from 2 through length($o-colors) { .o_colorlist_item_color_#{$size - 1} { - background-color: nth($o-colors, $size); + $-bg: adjust-color(nth($o-colors, $size), $lightness: 25%, $saturation: 15%); + @include o-print-color($-bg, background-color, bg-opacity); } } // Set the "no-color", a red bar on white background .o_colorlist_item_color_0 { - position: relative; - &::before { - content: ""; - @include o-position-absolute(-2px, $left: 10px); - display: block; - width: 1px; - height: 19px; - transform: rotate(45deg); - background-color: red; - } - &::after { - background-color: white; - } + background: linear-gradient(45deg, rgba($dropdown-bg, 0) 0%, rgba($dropdown-bg, 0) 48%, $danger 48%, $danger 52%, rgba($dropdown-bg, 0) 52%, rgba($dropdown-bg, 0) 100%); } diff --git a/addons/web/static/src/core/colorlist/colorlist.xml b/addons/web/static/src/core/colorlist/colorlist.xml index 724596e6353..04c7f119063 100644 --- a/addons/web/static/src/core/colorlist/colorlist.xml +++ b/addons/web/static/src/core/colorlist/colorlist.xml @@ -4,10 +4,10 @@
-
diff --git a/addons/web/static/src/core/tags_list/tags_list.js b/addons/web/static/src/core/tags_list/tags_list.js index b939fa8b7d2..61e4b267851 100644 --- a/addons/web/static/src/core/tags_list/tags_list.js +++ b/addons/web/static/src/core/tags_list/tags_list.js @@ -9,6 +9,7 @@ export class TagsList extends Component { displayText: true, }; static props = { + className: { type: String, optional: true }, displayBadge: { type: Boolean, optional: true }, displayText: { type: Boolean, optional: true }, itemsVisible: { type: Number, optional: true }, diff --git a/addons/web/static/src/core/tags_list/tags_list.scss b/addons/web/static/src/core/tags_list/tags_list.scss index e259b6236e1..a76a4d0f321 100644 --- a/addons/web/static/src/core/tags_list/tags_list.scss +++ b/addons/web/static/src/core/tags_list/tags_list.scss @@ -1,63 +1,24 @@ .o_tag { - user-select: none; + font-size: var(--Tag-font-size, #{$font-size-sm}); + max-width: var(--Tag-max-width, 100%); .o_badge_text, a { - color: inherit; line-height: 1.1; } - .o_tag_badge_text { - font-size: 12px; - } - - img { - height: 1.6em; - aspect-ratio: 1/1; - - + .o_tag_badge_text { - padding: 0.25em 0; - } + a { + color: inherit; } @for $size from 1 through length($o-colors) { &.o_tag_color_#{$size - 1} { - @if $size == 1 { - & { - background-color: $o-view-background-color; - color: nth($o-colors, $size); - box-shadow: inset 0 0 0 1px; - } - &:focus-within { - color: darken(nth($o-colors, $size), 40%) ; - } - &::after { - background-color: nth($o-colors, $size); - } - } @else { - &, &::after { - background-color: nth($o-colors, $size); - color: color-contrast(nth($o-colors, $size)); - } + $-bg: adjust-color(nth($o-colors, $size), $lightness: 25%, $saturation: 15%); + $-color: adjust-color(nth($o-colors, $size), $lightness: -40%, $saturation: -15%); + + &, &::after { + @include o-print-color($-bg, background-color, bg-opacity); + @include o-print-color($-color, color, text-opacity); } } } -} - -.o_kanban_view .o_kanban_record .o_tag { - display: inline-block; - margin-right: 4px; - font-size: 11px; - font-weight: 500; - background-color: transparent; - color: inherit; - box-shadow: none; - @include o-kanban-tag-color; - - span { - display: inline-block; - width: 6px; - height: 6px; - margin-right: 4px; - border-radius: 100%; - } -} +} \ No newline at end of file diff --git a/addons/web/static/src/core/tags_list/tags_list.xml b/addons/web/static/src/core/tags_list/tags_list.xml index 7e0d688cdfd..3283cd2ced1 100644 --- a/addons/web/static/src/core/tags_list/tags_list.xml +++ b/addons/web/static/src/core/tags_list/tags_list.xml @@ -3,15 +3,23 @@ - - - -
- - -
- - + + + + +
+ diff --git a/addons/web/static/src/legacy/scss/fields.scss b/addons/web/static/src/legacy/scss/fields.scss index 8cad9875e99..d68b6acea83 100644 --- a/addons/web/static/src/legacy/scss/fields.scss +++ b/addons/web/static/src/legacy/scss/fields.scss @@ -153,22 +153,6 @@ padding-bottom: 0; } - // Many2OneAvatar - &.o_field_many2one_avatar { - .o_m2o_avatar > img, .o_m2o_avatar > .o_m2o_avatar_empty { - border-radius: 50%; - width: 19px; - height: 19px; - object-fit: cover; - margin-right: 4px; - } - .o_m2o_avatar_empty { - display: block; - background: $o-black; - opacity: .1; - } - } - // Many2many tags &.o_field_many2manytags { flex-flow: row wrap; diff --git a/addons/web/static/src/legacy/scss/utils.scss b/addons/web/static/src/legacy/scss/utils.scss index 3be4a4e0473..3b41bed25c2 100644 --- a/addons/web/static/src/legacy/scss/utils.scss +++ b/addons/web/static/src/legacy/scss/utils.scss @@ -336,20 +336,8 @@ } // No Color - &:first-child > a { - position: relative; - &::before { - content: ""; - @include o-position-absolute(-2px, $left: 10px); - display: block; - width: 1px; - height: 20px; - transform: rotate(45deg); - background-color: red; - } - &::after { - background-color: white; - } + &:first-child > a:after { + background: linear-gradient(45deg, rgba($dropdown-bg, 0) 0%, rgba($dropdown-bg, 0) 48%, $danger 48%, $danger 52%, rgba($dropdown-bg, 0) 52%, rgba($dropdown-bg, 0) 100%); } } } diff --git a/addons/web/static/src/scss/bootstrap_overridden.scss b/addons/web/static/src/scss/bootstrap_overridden.scss index 80661c93a43..c36d9be94c5 100644 --- a/addons/web/static/src/scss/bootstrap_overridden.scss +++ b/addons/web/static/src/scss/bootstrap_overridden.scss @@ -281,7 +281,7 @@ $form-range-thumb-bg: $primary !default; // Badge $badge-color: inherit !default; $badge-padding-y: 0.25em !default; -$badge-padding-x: 0.4em !default; +$badge-padding-x: 0.82em !default; // Placeholder color $input-placeholder-color: $gray-300 !default; diff --git a/addons/web/static/src/scss/primary_variables.scss b/addons/web/static/src/scss/primary_variables.scss index 4436bdf9607..f2b747aa934 100644 --- a/addons/web/static/src/scss/primary_variables.scss +++ b/addons/web/static/src/scss/primary_variables.scss @@ -200,7 +200,7 @@ $o-list-group-active-bg: lighten(saturate(adjust-hue($o-info, 15), 1.8), 50) !de // == Badges // Define a minimum width. This value is arbitrary and strictly font-related. -$o-badge-min-width: 2.5ch !default; +$o-badge-min-width: 3ch !default; $o-nb-calendar-colors: 24 !default; diff --git a/addons/web/static/src/scss/secondary_variables.scss b/addons/web/static/src/scss/secondary_variables.scss index 04309feb61d..a636b541526 100644 --- a/addons/web/static/src/scss/secondary_variables.scss +++ b/addons/web/static/src/scss/secondary_variables.scss @@ -5,8 +5,8 @@ $o-list-group-header-color: lighten($o-brand-lightsecondary, 10%) !default; // UI custom colors for tags, kanban records' colors, ...) // Note: the first value is the old BS3 gray-light value -$o-colors: lighten(#000, 46.7%), #F06050, #F4A460, #F7CD1F, #6CC1ED, #814968, - #EB7E7F, #2C8397, #475577, #D6145F, #30C381, #9365B8 !default; +$o-colors: #a2a2a2, #ee2d2d, #dc8534, #e8bb1d, #5794dd, #9f628f, #db8865, + #41a9a2, #304be0, #ee2f8a, #61c36e, #9872e6 !default; $o-colors-secondary: #aa4b6b, #30C381, #97743a, #F7CD1F, #4285F4, #8E24AA, #D6145F, #173e43, #348F50, #AA3A38, #795548, #5e0231, diff --git a/addons/web/static/src/views/fields/many2many_tags/kanban_many2many_tags_field.xml b/addons/web/static/src/views/fields/many2many_tags/kanban_many2many_tags_field.xml index c1a1c8faa96..123a2a31b5e 100644 --- a/addons/web/static/src/views/fields/many2many_tags/kanban_many2many_tags_field.xml +++ b/addons/web/static/src/views/fields/many2many_tags/kanban_many2many_tags_field.xml @@ -2,6 +2,8 @@ - +
+ +
diff --git a/addons/web/static/src/views/fields/many2many_tags/many2many_tags_field.js b/addons/web/static/src/views/fields/many2many_tags/many2many_tags_field.js index a89b7f5a73d..e93882a9e24 100644 --- a/addons/web/static/src/views/fields/many2many_tags/many2many_tags_field.js +++ b/addons/web/static/src/views/fields/many2many_tags/many2many_tags_field.js @@ -158,7 +158,7 @@ export class Many2ManyTagsField extends Component { focusTag(index) { const autoCompleteParent = this.autoCompleteRef.el.parentElement; - const tags = autoCompleteParent.getElementsByClassName("badge"); + const tags = autoCompleteParent.getElementsByClassName("o_tag"); if (tags.length) { if (index === undefined) { tags[tags.length - 1].focus(); @@ -219,8 +219,8 @@ export class Many2ManyTagsField extends Component { } const hotkey = getActiveHotkey(ev); const autoCompleteParent = this.autoCompleteRef.el.parentElement; - const tags = [...autoCompleteParent.getElementsByClassName("badge")]; - const closestTag = ev.target.closest(".badge"); + const tags = [...autoCompleteParent.getElementsByClassName("o_tag")]; + const closestTag = ev.target.closest(".o_tag"); const tagIndex = tags.indexOf(closestTag); const input = this.autoCompleteRef.el.querySelector(".o-autocomplete--input"); switch (hotkey) { diff --git a/addons/web/static/src/views/fields/many2many_tags/many2many_tags_field.scss b/addons/web/static/src/views/fields/many2many_tags/many2many_tags_field.scss index 03da097806a..5b275a29794 100644 --- a/addons/web/static/src/views/fields/many2many_tags/many2many_tags_field.scss +++ b/addons/web/static/src/views/fields/many2many_tags/many2many_tags_field.scss @@ -11,11 +11,6 @@ .o_tags_input { padding: 1px 0; - - .o_tag { - padding-left: 0.6em; - padding-right: 0.6em; - } } .o_field_many2many_selection { @@ -29,12 +24,7 @@ .badge { flex: 0 0 auto; - margin: 1px 2px 1px 0; - border: none; - font-size: 12px; - user-select: none; display: flex; - max-width: 100%; &.dropdown { cursor: pointer; @@ -47,15 +37,6 @@ .o_badge_text, .o_tag_badge_text { @include o-text-overflow(inline-block); max-width: 200px; - color: inherit; - line-height: 1.1; - } - - .o_delete { - color: inherit; - cursor: pointer; - padding-left: 4px; - line-height: 1; } } } diff --git a/addons/web/static/src/views/fields/many2many_tags/many2many_tags_field.xml b/addons/web/static/src/views/fields/many2many_tags/many2many_tags_field.xml index 62ea1c44999..1a350617272 100644 --- a/addons/web/static/src/views/fields/many2many_tags/many2many_tags_field.xml +++ b/addons/web/static/src/views/fields/many2many_tags/many2many_tags_field.xml @@ -3,7 +3,7 @@
diff --git a/addons/web/static/src/views/fields/many2many_tags_avatar/many2many_tags_avatar_field.scss b/addons/web/static/src/views/fields/many2many_tags_avatar/many2many_tags_avatar_field.scss index 8f44c546db1..3710e1c6308 100644 --- a/addons/web/static/src/views/fields/many2many_tags_avatar/many2many_tags_avatar_field.scss +++ b/addons/web/static/src/views/fields/many2many_tags_avatar/many2many_tags_avatar_field.scss @@ -1,74 +1,22 @@ .o_field_widget.o_field_many2many_tags_avatar { - flex-flow: row wrap; + $-text-spacing-v: $o-line-height-base * 1em; + --img-text-gap-v: calc(var(--Avatar-size, #{$o-avatar-size}) - #{$-text-spacing-v}); - .o_tags_input { - padding: 1px 0; - } + flex-flow: row wrap; + margin-top: calc(var(--img-text-gap-v) * -0.5); // using transform conflicts with dropdown position .o_field_many2many_selection { flex: 1 0 50px; - .o_input { + .o-autocomplete, .o_input { height: 100%; + } + + .o_input { border: none; } } - .o_dropdown_button { - top: $o-input-padding-y; - } - - .badge { - flex: 0 0 auto; - margin: 1px 2px 1px 0; - border: none; - font-size: 12px; - user-select: none; - display: flex; - max-width: 100%; - align-items: center; - padding: 0; - padding-right: 0.6rem; - box-shadow: inset 0 0 0 1px; - - &.dropdown { - cursor: pointer; - } - - a { - color: inherit; - } - - .o_badge_text { - @include o-text-overflow(inline-block); - max-width: 200px; - color: inherit; - line-height: 1.1; - } - - .o_delete { - color: inherit; - cursor: pointer; - padding-left: 4px; - line-height: 1; - } - - img { - height: 1.4em; - width: 1.4em; - object-fit: cover; - } - - .o_badge_text, .o_delete { - padding-top: 0.25em; - padding-bottom: 0.25em; - } - - .o_tag_badge_text { - padding-left:2px; - } - } - } .o_kanban_record { @@ -85,10 +33,7 @@ } .o_list_view .o_field_widget.o_field_many2many_tags_avatar { - .o_tags_input { - border: 0; - padding: 0; - } + --img-text-gap-v: 0; .o_field_many2many_selection { flex-basis: 40px; diff --git a/addons/web/static/src/views/fields/properties/property_tags.xml b/addons/web/static/src/views/fields/properties/property_tags.xml index dfe6456c5ec..a333989336b 100644 --- a/addons/web/static/src/views/fields/properties/property_tags.xml +++ b/addons/web/static/src/views/fields/properties/property_tags.xml @@ -5,7 +5,8 @@
+ displayBadge="displayBadge" + className="props.canChangeTags ? '' : 'o_field_property_tag_readonly'"/>
diff --git a/addons/web/static/src/webclient/webclient.scss b/addons/web/static/src/webclient/webclient.scss index eb7bb1e003b..b0154830067 100644 --- a/addons/web/static/src/webclient/webclient.scss +++ b/addons/web/static/src/webclient/webclient.scss @@ -55,6 +55,7 @@ kbd { //== Badges .badge { min-width: $o-badge-min-width; + line-height: 1.1; } // Set position of our custom o-dropdown-menu (not bootstrap) diff --git a/addons/web/static/tests/core/colorlist_tests.js b/addons/web/static/tests/core/colorlist_tests.js index cd9d318dfce..f3d63e22ba7 100644 --- a/addons/web/static/tests/core/colorlist_tests.js +++ b/addons/web/static/tests/core/colorlist_tests.js @@ -48,8 +48,8 @@ QUnit.module("Components", () => { const secondBtn = target.querySelectorAll(".o_colorlist button")[1]; assert.strictEqual( secondBtn.attributes.title.value, - "Fuchsia", - "second button color is Fuchsia" + "Raspberry", + "second button color is Raspberry" ); assert.hasClass( secondBtn, diff --git a/addons/web/static/tests/views/fields/many2many_tags_avatar_field_tests.js b/addons/web/static/tests/views/fields/many2many_tags_avatar_field_tests.js index 09f0ffb5d43..76e53441079 100644 --- a/addons/web/static/tests/views/fields/many2many_tags_avatar_field_tests.js +++ b/addons/web/static/tests/views/fields/many2many_tags_avatar_field_tests.js @@ -455,24 +455,24 @@ QUnit.module("Fields", (hooks) => { assert.containsN( target, - ".o_field_many2many_tags_avatar.o_field_widget .badge", + ".o_field_many2many_tags_avatar.o_field_widget .o_tag", 2, "should have 2 records" ); await click( - target.querySelector(".o_field_many2many_tags_avatar.o_field_widget .badge .o_delete") + target.querySelector(".o_field_many2many_tags_avatar.o_field_widget .o_tag .o_delete") ); assert.containsOnce( target, - ".o_field_many2many_tags_avatar.o_field_widget .badge", + ".o_field_many2many_tags_avatar.o_field_widget .o_tag", "should have 1 record" ); await clickSave(target); assert.containsOnce( target, - ".o_field_many2many_tags_avatar.o_field_widget .badge", + ".o_field_many2many_tags_avatar.o_field_widget .o_tag", "should have 1 record" ); });