diff --git a/addons/account/static/src/scss/account_journal_dashboard.scss b/addons/account/static/src/scss/account_journal_dashboard.scss index fdefc7c3c88..91ddc1295d1 100644 --- a/addons/account/static/src/scss/account_journal_dashboard.scss +++ b/addons/account/static/src/scss/account_journal_dashboard.scss @@ -38,16 +38,6 @@ width: 450px; } } - - .o_kanban_group { - &:not(.o_column_folded) { - width: 450px + 2*$o-kanban-group-padding; - - @include media-breakpoint-down(md) { - width: 100%; - } - } - } } // Style for the widget "dashboard_graph" diff --git a/addons/web/static/src/legacy/scss/utils.scss b/addons/web/static/src/legacy/scss/utils.scss index b07ea06b641..5f93a5d0e90 100644 --- a/addons/web/static/src/legacy/scss/utils.scss +++ b/addons/web/static/src/legacy/scss/utils.scss @@ -261,18 +261,10 @@ border-left-color: nth($o-colors, $size); &:after { background-color: nth($o-colors, $size); - outline: 1px solid nth($o-colors, $size); } } } } -@mixin o-kanban-slim-col { - position: relative; - flex: 0 0 auto; - margin: 0; - padding: 0 floor($o-kanban-group-padding * 0.7); - cursor: pointer; -} @mixin o-kanban-header-title { display: flex; align-items: center; @@ -280,15 +272,9 @@ line-height: 2.2; color: $headings-color; } -@mixin o-kanban-v-title { - @include o-position-absolute($o-kanban-inside-vgutter * 2, $left: floor(-$o-kanban-inside-vgutter * 1.2)); - transform-origin: left bottom 0; - transform: rotate(90deg); - overflow: visible; -} // ------- Kanban records mixins ------- -@mixin o-kanban-record-title($font-size: 1em) { +@mixin o-kanban-record-title($font-size: $h5-font-size) { color: $headings-color; font-size: $font-size; font-weight: 500; @@ -296,10 +282,8 @@ margin-top: 0; } @mixin o-kanban-dropdown($padding-base: $o-kanban-inside-vgutter) { - margin: -1px -1px 1px; + margin: 1px 1px 0 0; padding: if(type-of($padding-base) == 'string', calc(#{$padding-base}/2) $padding-base, $padding-base/2 $padding-base); - border: 1px solid transparent; - border-bottom: none; vertical-align: top; @include o-hover-text-color($body-color, $headings-color); @@ -311,8 +295,14 @@ @mixin o-kanban-dropdown-open { position: relative; background: $dropdown-bg; - border-color: $border-color; z-index: $zindex-dropdown + 1; + + &:before { + @include o-position-absolute(100%, 0, auto, 0); + height: $dropdown-border-radius; + background-color: $dropdown-bg; + content: ""; + } } @mixin o-kanban-colorpicker { max-width: 150px; diff --git a/addons/web/static/src/scss/bootstrap_overridden.scss b/addons/web/static/src/scss/bootstrap_overridden.scss index c003682d5dd..1af2f030e9c 100644 --- a/addons/web/static/src/scss/bootstrap_overridden.scss +++ b/addons/web/static/src/scss/bootstrap_overridden.scss @@ -133,8 +133,9 @@ $headings-color: $o-main-headings-color !default; // // Customizes the `.table` component with basic values, each used across all table variations. +$table-bg: transparent !default; $table-striped-color: inherit !default; -$table-striped-bg-factor: .01 !default; +$table-striped-bg-factor: 0.01 !default; $table-hover-bg-factor: .055 !default; $table-border-color: $gray-200 !default; $table-group-separator-color: $gray-200 !default; diff --git a/addons/web/static/src/scss/primary_variables.scss b/addons/web/static/src/scss/primary_variables.scss index 878013ae076..d52f09310fc 100644 --- a/addons/web/static/src/scss/primary_variables.scss +++ b/addons/web/static/src/scss/primary_variables.scss @@ -110,7 +110,7 @@ $o-shadow-color: #303030 !default; $o-form-lightsecondary: #ccc !default; -$o-list-footer-bg-color: #eee !default; +$o-list-footer-bg-color: transparent !default; $o-list-footer-font-weight: bold !default; // Custom colors generation maps diff --git a/addons/web/static/src/views/form/form_controller.scss b/addons/web/static/src/views/form/form_controller.scss index dc3e92cb4b3..a43c0a64d2c 100644 --- a/addons/web/static/src/views/form/form_controller.scss +++ b/addons/web/static/src/views/form/form_controller.scss @@ -907,6 +907,9 @@ // One2Many List views .o_field_widget .o_list_renderer { + --ListRenderer-thead-bg-color: #{$o-view-background-color}; + --ListRenderer-tfoot-bg-color: #{$o-view-background-color}; + margin-bottom: 10px; > tfoot > tr > td { diff --git a/addons/web/static/src/views/kanban/kanban.variables.scss b/addons/web/static/src/views/kanban/kanban.variables.scss index 9a3639c3b2e..339e9ce2d33 100644 --- a/addons/web/static/src/views/kanban/kanban.variables.scss +++ b/addons/web/static/src/views/kanban/kanban.variables.scss @@ -1,12 +1,12 @@ -$o-kanban-background: $o-gray-200 !default; -$o-kanban-default-record-width: 300px !default; -$o-kanban-small-record-width: 240px !default; +$o-kanban-background: $o-gray-100 !default; +$o-kanban-default-record-width: 320px !default; +$o-kanban-small-record-width: 300px !default; $o-kanban-header-title-height: 50px !default; $o-kanban-image-width: 64px !default; $o-kanban-image-fill-width: 95px !default; $o-kanban-inside-vgutter: $o-spacer * 0.5 !default; $o-kanban-inside-hgutter: $o-spacer * 0.5 !default; -$o-kanban-color-border-width: 2px !default; +$o-kanban-color-border-width: 3px !default; $o-kanban-inner-hmargin: 5px !default; $o-kanban-progressbar-height: 20px !default; $o-kanban-mobile-tabs-height: 40px !default; diff --git a/addons/web/static/src/views/kanban/kanban_column_progressbar.scss b/addons/web/static/src/views/kanban/kanban_column_progressbar.scss index a47ac2f166c..775fc8c8337 100644 --- a/addons/web/static/src/views/kanban/kanban_column_progressbar.scss +++ b/addons/web/static/src/views/kanban/kanban_column_progressbar.scss @@ -1,14 +1,10 @@ @mixin o-kanban-css-filter($class, $accent-color) { // Provide CSS reordering and highlight &.o_kanban_group_show_#{$class} { - $mix-soft: mix($accent-color, $o-webclient-background-color, 5%); - $mix-full: mix($accent-color, $o-webclient-background-color); + --KanbanGroup-background: #{mix($accent-color, $o-kanban-background, 5%)}; - &, - .o_kanban_header { - background-color: $mix-soft; - border-color: $mix-full; - } + outline: $border-width solid $o-view-background-color; + box-shadow: inset 2px 0 0 $accent-color, inset -2px 0 0 $accent-color; .oe_kanban_card_#{$class} { order: 1; @@ -22,7 +18,6 @@ .o_kanban_record:not(.oe_kanban_card_#{$class}) { order: 3; @include o-hover-opacity(0.5); - box-shadow: none; } } } @@ -34,6 +29,10 @@ > .o_column_progress { height: $font-size-sm; + + .bg-200 { + --background-color: RGBA(#{to-rgb($o-gray-300)}, var(--bg-opacity, 1)) + } } } @@ -43,5 +42,6 @@ @include o-kanban-css-filter(danger, map-get($theme-colors, "danger")); @include o-kanban-css-filter(muted, map-get($theme-colors, "dark")); @include o-kanban-css-filter(info, map-get($theme-colors, "info")); + @include o-kanban-css-filter(purple, purple); } } diff --git a/addons/web/static/src/views/kanban/kanban_column_quick_create.xml b/addons/web/static/src/views/kanban/kanban_column_quick_create.xml index 1a2f4bc0294..e49b4352c26 100644 --- a/addons/web/static/src/views/kanban/kanban_column_quick_create.xml +++ b/addons/web/static/src/views/kanban/kanban_column_quick_create.xml @@ -3,12 +3,12 @@
-
-
-
+
- Esc to discard + Press Esc to discard diff --git a/addons/web/static/src/views/kanban/kanban_controller.scss b/addons/web/static/src/views/kanban/kanban_controller.scss index 0a2b5cf11d3..d0fad63ae24 100644 --- a/addons/web/static/src/views/kanban/kanban_controller.scss +++ b/addons/web/static/src/views/kanban/kanban_controller.scss @@ -11,6 +11,9 @@ // Default KanbanView values --Kanban-background: #{$o-kanban-background}; + --Kanban-padding: 0; + + --KanbanGroup-background: var(--Kanban-background); --KanbanGroup-padding-h: #{$o-kanban-group-padding}; --KanbanGroup-padding-bottom: #{$o-kanban-group-padding}; @@ -28,22 +31,23 @@ --KanbanRecord__dropdown-gap: #{$border-width}; - --KanbanColumn__highlight-background: #{rgba($o-info, 0.05)}; - --KanbanColumn__highlight-border: #{$o-info}; + --KanbanColumn__highlight-background: #{tint-color($o-action, 90%)}; + --KanbanColumn__highlight-border: #{$o-action}; --o-view-nocontent-zindex: 1; // ---------------------------------------------------------------------------- + border-top: $border-width solid var(--Kanban-background); background: var(--Kanban-background); + padding: var(--Kanban-padding); @include media-breakpoint-down(md) { --KanbanRecord-padding-h: #{$o-kanban-inside-hgutter * 2}; - padding: 0px !important; } .o_kanban_record > div:not(.o_dropdown_kanban), .o_kanban_quick_create { - border: 1px solid $border-color; + border: $border-width solid $border-color; background-color: $o-view-background-color; } @@ -60,7 +64,7 @@ .o_kanban_record { position: relative; min-width: 150px; - margin: 0 0 -1px; + margin: 0 0 (-$border-width); > div:not(.o_dropdown_kanban) { padding: var(--KanbanRecord-padding-v) var(--KanbanRecord-padding-h); @@ -68,16 +72,11 @@ height: 100%; } - &:focus, - &:focus-within { - margin-bottom: 0; // show the shadow on top of the previous & next cards in grouped mode - } - // ------- Kanban Record, v11 Layout ------- // Records colours > div::after { content: ""; - @include o-position-absolute($border-width * 2, auto, $border-width * 2, $border-width); + @include o-position-absolute(0, auto, 0, 0); width: $o-kanban-color-border-width; } @@ -370,10 +369,10 @@ cursor: pointer; } - &:focus, + &:focus-visible, &:focus-within { @include global-click-selector { - outline: thin solid mix(map-get($theme-colors, "primary"), map-get($grays, "400")); + outline: thin solid mix($o-main-link-color, map-get($grays, "300")); outline-offset: -1px; &:after { @@ -450,23 +449,29 @@ // Kanban Grouped Layout &.o_kanban_grouped { + --KanbanGroup-width: calc(var(--KanbanRecord--small-width) + (2 * var(--KanbanGroup-padding-h))); + min-height: 100%; @include media-breakpoint-down(md) { + --KanbanGroup-width: 90%; // don't take full width to give a hint of next/previous column on smaller screens + min-height: initial; height: 100%; overflow: scroll hidden !important; scroll-snap-type: x mandatory; } + @include media-breakpoint-up(lg) { + --KanbanGroup-width: calc(var(--KanbanRecord-width) + (2 * var(--KanbanGroup-padding-h))); + } + .o_kanban_record { width: 100%; } - --KanbanGroup-width: 90%; // don't take full width to give a hint of next/previous column on smaller screens - - @include media-breakpoint-up(md) { - --KanbanGroup-width: calc(var(--KanbanRecord-width) + (2 * var(--KanbanGroup-padding-h))); + .o_kanban_group { + background: var(--KanbanGroup-background); } .o_kanban_group, @@ -481,8 +486,6 @@ // Kanban Grouped Layout - Column default .o_kanban_group { - padding: 0 var(--KanbanGroup-padding-h) var(--KanbanGroup-padding-bottom); - .o_kanban_header > .o_kanban_header_title { &:hover .o_kanban_config, .o_kanban_config.show { @@ -513,15 +516,15 @@ } } - .o_kanban_group .o_kanban_header, - .o_quick_create_folded { - position: sticky; // keep it visible - z-index: 1; + .o_kanban_group, .o_column_quick_create { + padding: 0 var(--KanbanGroup-padding-h) var(--KanbanGroup-padding-bottom); + } + + .o_kanban_group .o_kanban_header, .o_quick_create_folded { + background: inherit; } .o_kanban_group:not(.o_column_folded) .o_kanban_header { - background-color: $o-webclient-background-color; - .dropdown-item { max-width: calc(var(--KanbanRecord-width) * 0.75); text-overflow: ellipsis; @@ -530,7 +533,7 @@ } .o_quick_create_folded { - top: 1rem; + top: map-get($spacers, 3); } .o_column_quick_create, @@ -540,39 +543,58 @@ } .o_group_draggable .o_column_title { - cursor: move; + cursor: grab; + + &:active { + cursor: grabbing; + } } // Kanban Grouped Layout - Column Folded .o_kanban_group.o_column_folded { + // don't fill the width of record for a folded column .o_kanban_record.o_draggable { display: none !important; } // don't visually fold on smaller screens (aka. mobile) @include media-breakpoint-up(md) { - @include o-kanban-slim-col; + --KanbanGroup-padding-h: 0; - background-color: var(--KanbanGroup-grouped-bg, #{$gray-200}); + &, .o_column_unfold { + cursor: col-resize; + } & + .o_kanban_group.o_column_folded { margin-left: 1px; } - .o_kanban_header_title { - opacity: 0.5; + .o_kanban_header { + padding: 0 floor($o-kanban-group-padding * 0.7); + } - .o_column_title { - @include o-kanban-v-title; + button.o_column_unfold { + padding: 0 .15rem; + + .fa-caret-left { + margin-right: 0.2rem; } } - &:hover, - &.o_kanban_hover { - .o_kanban_header_title { - opacity: 1; + &:hover button.o_column_unfold { + padding: 0; + + .fa-caret-left { + margin-right: 0.5rem; } } + + .o_column_title { + @include o-position-absolute(map-get($spacers, 4)); + transform-origin: left bottom 0; + transform: rotate(90deg); + overflow: visible; + } } } @@ -587,14 +609,17 @@ // Kanban UN-grouped Layout &.o_kanban_ungrouped { min-height: 100%; - padding: var(--KanbanRecord-margin-v) var(--KanbanRecord-margin-h); + + @include media-breakpoint-up(md) { + --Kanban-padding: var(--KanbanRecord-margin-v) var(--KanbanRecord-margin-h); + } .o_kanban_record { width: var(--KanbanRecord-width); margin: calc(var(--KanbanRecord-margin-v) * 0.5) var(--KanbanRecord-margin-h); @include media-breakpoint-down(md) { - margin: 0 0 -1px 0 0 #{-$border-width}; + margin: 0 0 #{-$border-width}; flex-basis: 100%; } diff --git a/addons/web/static/src/views/kanban/kanban_header.js b/addons/web/static/src/views/kanban/kanban_header.js index a48fcf7abc2..2e885ba6a4b 100644 --- a/addons/web/static/src/views/kanban/kanban_header.js +++ b/addons/web/static/src/views/kanban/kanban_header.js @@ -64,7 +64,7 @@ export class KanbanHeader extends Component { } get groupName() { - const { groupByField, count, displayName, isFolded } = this.group; + const { groupByField, displayName } = this.group; let name = displayName; if (groupByField.type === "boolean") { name = name ? this.env._t("Yes") : this.env._t("No"); @@ -78,7 +78,7 @@ export class KanbanHeader extends Component { name = this.env._t("None"); } } - return !this.env.isSmall && isFolded ? `${name} (${count})` : name; + return name; } get groupAggregate() { diff --git a/addons/web/static/src/views/kanban/kanban_header.xml b/addons/web/static/src/views/kanban/kanban_header.xml index d711a35a390..9d12e4f836f 100644 --- a/addons/web/static/src/views/kanban/kanban_header.xml +++ b/addons/web/static/src/views/kanban/kanban_header.xml @@ -2,13 +2,20 @@ -
-
- +
+
+
+ + +
+ - + - + - + -
diff --git a/addons/web/static/src/views/kanban/kanban_record.xml b/addons/web/static/src/views/kanban/kanban_record.xml index f01614ca682..0dab261002a 100644 --- a/addons/web/static/src/views/kanban/kanban_record.xml +++ b/addons/web/static/src/views/kanban/kanban_record.xml @@ -17,7 +17,7 @@ diff --git a/addons/web/static/src/views/kanban/kanban_record_quick_create.xml b/addons/web/static/src/views/kanban/kanban_record_quick_create.xml index ccc3e465b27..482ef15142d 100644 --- a/addons/web/static/src/views/kanban/kanban_record_quick_create.xml +++ b/addons/web/static/src/views/kanban/kanban_record_quick_create.xml @@ -16,7 +16,7 @@ - diff --git a/addons/web/static/src/views/kanban/kanban_renderer.js b/addons/web/static/src/views/kanban/kanban_renderer.js index f0bcfb29008..54ec4c84952 100644 --- a/addons/web/static/src/views/kanban/kanban_renderer.js +++ b/addons/web/static/src/views/kanban/kanban_renderer.js @@ -295,10 +295,7 @@ export class KanbanRenderer extends Component { classes.push("o_kanban_no_records"); } if (!this.env.isSmall && group.isFolded) { - classes.push("o_column_folded"); - } - if (!group.isFolded) { - classes.push("bg-100"); + classes.push("o_column_folded", "flex-basis-0"); } if (group.progressBars.length) { classes.push("o_kanban_has_progressbar"); diff --git a/addons/web/static/src/views/kanban/kanban_renderer.xml b/addons/web/static/src/views/kanban/kanban_renderer.xml index 8b8af886f12..bc4c84414da 100644 --- a/addons/web/static/src/views/kanban/kanban_renderer.xml +++ b/addons/web/static/src/views/kanban/kanban_renderer.xml @@ -12,6 +12,7 @@
diff --git a/addons/web/static/src/views/list/list_renderer.scss b/addons/web/static/src/views/list/list_renderer.scss index 3bf2bec10cc..9203717b0ce 100644 --- a/addons/web/static/src/views/list/list_renderer.scss +++ b/addons/web/static/src/views/list/list_renderer.scss @@ -1,11 +1,10 @@ // ------- List renderer ------- .o_list_renderer { - --ListRenderer-table-padding-h: #{$table-cell-padding-x-sm}; - - --ListRenderer-thead-padding-v: #{$table-cell-padding-y * 1.25}; - --ListRenderer-thead-bg-color: #{$gray-200}; + --ListRenderer-table-padding-y: #{$table-cell-padding-x-sm}; + --ListRenderer-thead-padding-y: #{map-get($spacers, 4)}; + --ListRenderer-thead-bg-color: #{$o-webclient-background-color}; --ListRenderer-thead-border-end-color: #{$border-color}; - --ListRenderer-thead-shadow: linear-gradient(180deg, rgba(0, 0, 0, 0.08), transparent); + --ListRenderer-tfoot-bg-color: #{$o-list-footer-bg-color}; // sticky header on desktop @include media-breakpoint-up(md) { @@ -14,26 +13,23 @@ .o_list_table thead { @include o-position-sticky(0); z-index: 1; - - &:after { - @include o-position-absolute($left: 0, $right: 0); - height: map-get($spacers, 3); - border-top: $border-width solid $border-color; - background-image: var(--ListRenderer-thead-shadow); - transform: translateY(-#{$border-width}); // Compensate rendering misplacement - -moz-transform: translateY(0); // Firefox doesn't need rendering adjustments - pointer-events: none; - content: ''; - } } } + th, td { + // This fixes a bug that was hidding part of cell borders on Firefox. + background-clip: padding-box; + } + .o_list_view & { - --ListRenderer-table-padding-h: #{$o-horizontal-padding}; + --ListRenderer-thead-padding-y: #{$table-cell-padding-y-sm}; + --ListRenderer-table-padding-y: #{$o-horizontal-padding}; } .o_list_table { - background-color: $o-view-background-color; + --table-bg: #{$o-view-background-color}; + + // We need this to be collapse because we want to add a border on the rows // for sale order/invoice lines of type section. border-collapse: collapse; @@ -41,11 +37,11 @@ > thead, > tbody, > tfoot { > tr > :first-child { - padding-left: var(--ListRenderer-table-padding-h); + padding-left: var(--ListRenderer-table-padding-y); } > tr > :last-child { - padding-right: var(--ListRenderer-table-padding-h); + padding-right: var(--ListRenderer-table-padding-y); } > tr > :empty { @@ -53,16 +49,14 @@ } } - :not(.o_field_x2many_list) > & thead, tfoot { - tr > :not(:empty) { - padding-top: var(--ListRenderer-thead-padding-v); - padding-bottom: var(--ListRenderer-thead-padding-v); - } - } - thead { background-color: var(--ListRenderer-thead-bg-color); - color: $headings-color; + + th { + padding-top: var(--ListRenderer-thead-padding-y); + background-color: transparent; + color: $headings-color; + } } // Override BS default @@ -120,15 +114,10 @@ } tfoot { - // cursor: default; - color: $o-list-footer-color; - background-color: $o-list-footer-bg-color; - font-weight: $o-list-footer-font-weight; - border-top: 1px solid $table-border-color; - border-bottom: 1px solid $table-border-color; - - > tr > td { + color: $o-list-footer-color; + background-color: $o-list-footer-bg-color; + font-weight: $o-list-footer-font-weight; @include o-text-overflow(table-cell); } } @@ -448,7 +437,7 @@ // first-child will be hidden so add left padding to second child & + * { - padding-left: var(--ListRenderer-table-padding-h); + padding-left: var(--ListRenderer-table-padding-y); } } } diff --git a/addons/web/static/src/views/list/list_renderer.xml b/addons/web/static/src/views/list/list_renderer.xml index b3fb4845c77..56206fed12b 100644 --- a/addons/web/static/src/views/list/list_renderer.xml +++ b/addons/web/static/src/views/list/list_renderer.xml @@ -14,7 +14,7 @@ - + -
+
diff --git a/addons/web/static/tests/views/kanban_view_tests.js b/addons/web/static/tests/views/kanban_view_tests.js index 6cda94c7dbf..d1383afdf28 100644 --- a/addons/web/static/tests/views/kanban_view_tests.js +++ b/addons/web/static/tests/views/kanban_view_tests.js @@ -461,7 +461,7 @@ QUnit.module("Views", (hooks) => { assert.hasClass( target.querySelector(".o_kanban_group"), - "bg-100", + "bg-200", "o_kanban_group should have a background" ); assert.hasClass(target.querySelector(".o_kanban_view"), "o_kanban_test"); @@ -12718,8 +12718,8 @@ QUnit.module("Views", (hooks) => { assert.strictEqual(content.scrollLeft, 20); assert.containsOnce(target, ".o_kanban_record.o_dragged"); - // next 20 frames - await advanceFrame(20); + // next 40 frames + await advanceFrame(40); // Should be at the end of the content assert.strictEqual(content.clientWidth + content.scrollLeft, content.scrollWidth); @@ -12739,8 +12739,8 @@ QUnit.module("Views", (hooks) => { assert.containsOnce(target, ".o_kanban_record.o_dragged"); - // next 20 frames - await advanceFrame(20); + // next 40 frames + await advanceFrame(40); assert.strictEqual(content.scrollLeft, 0);