[REF] web: KanbanView, review and simplify scss
Review, simplify SCSS and adapt legacy code. Part of the overall v16 SCSS optimization/restyle, task-2704984 task-2892062 Part-of: odoo/odoo#96195
This commit is contained in:
@@ -45,19 +45,15 @@
|
||||
|
||||
// container ghost card in background
|
||||
.o_kanban_example_background_container {
|
||||
display: flex;
|
||||
padding: 0px;
|
||||
opacity: 0.4;
|
||||
|
||||
// content
|
||||
.o_kanban_example_background {
|
||||
flex: 1 1 100%;
|
||||
flex-basis: 100%;
|
||||
|
||||
.o_kanban_examples {
|
||||
.o_kanban_examples_group {
|
||||
.o_kanban_examples_ghost {
|
||||
width: 224px;
|
||||
margin-bottom: 10px;
|
||||
width: $o-kanban-small-record-width;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,31 +63,16 @@
|
||||
|
||||
// kanban ghost card
|
||||
.o_kanban_examples {
|
||||
display: flex;
|
||||
padding: 0 6px;
|
||||
|
||||
.o_kanban_examples_group {
|
||||
flex: 1 1 100%;
|
||||
margin: 10px;
|
||||
flex-basis: 100%;
|
||||
|
||||
.o_kanban_examples_ghost {
|
||||
padding: 5px;
|
||||
margin-top: -1px;
|
||||
border: thin solid map-get($grays, '300');
|
||||
background-color: white;
|
||||
.o_ghost_content {
|
||||
height: 12px;
|
||||
background: map-get($grays, '300');
|
||||
&.o_ghost_tag {
|
||||
display: inline-block;
|
||||
width: 40%;
|
||||
margin-top: 10px;
|
||||
}
|
||||
&.o_collapse {
|
||||
margin-top: -1px;
|
||||
}
|
||||
.o_ghost_avatar {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,7 +465,6 @@
|
||||
}
|
||||
|
||||
.o_kanban_quick_add i {
|
||||
@include o-kanban-icon;
|
||||
margin-left: $o-kanban-inside-hgutter*2;
|
||||
}
|
||||
|
||||
@@ -481,10 +480,6 @@
|
||||
@include media-breakpoint-down(md) {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
i {
|
||||
@include o-kanban-icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -521,7 +516,7 @@
|
||||
}
|
||||
|
||||
.o_column_unfold {
|
||||
@include o-kanban-icon(1);
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -237,14 +237,6 @@
|
||||
}
|
||||
|
||||
// ------- Kanban grouped mixins -------
|
||||
@mixin o-kanban-icon($base-opacity: 0.5) {
|
||||
display: block;
|
||||
text-align: center;
|
||||
color: $o-main-text-color;
|
||||
font-size: $font-size-sm;
|
||||
cursor: pointer;
|
||||
@include o-hover-opacity($base-opacity);
|
||||
}
|
||||
@mixin o-kanban-tag-color {
|
||||
@for $size from 1 through length($o-colors) {
|
||||
// Note: the first color is supposed to be invisible if there is a color
|
||||
@@ -285,8 +277,6 @@
|
||||
transform-origin: left bottom 0;
|
||||
transform: rotate(90deg);
|
||||
overflow: visible;
|
||||
white-space: nowrap;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
// ------- Kanban records mixins -------
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
role="feed" t-attf-aria-labelledby="kanban_header_#{widget.id or widget.db_id}">
|
||||
<div class="o_kanban_header">
|
||||
<div class="o_kanban_header_title">
|
||||
<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 t-attf-id="#kanban_header_#{widget.id or widget.db_id}" class="o_column_title" t-attf-class="{{ !widget.isMobile and widget.folded ? 'fs-4 overflow-visible' : '' }}"><t t-esc="widget.title"/></span>
|
||||
<button class="o_column_unfold btn btn-link p-0 border-0 small text-center text-700 cursor-pointer"><i class="fa fa-arrows-h" role="img" aria-label="Unfold" title="Unfold"/></button>
|
||||
<span class="o_kanban_config dropdown">
|
||||
<a class="dropdown-toggle o-no-caret" data-bs-toggle="dropdown" href="#"><i class="fa fa-gear" role="img" aria-label="Settings" title="Settings"/></a>
|
||||
<a class="dropdown-toggle o-no-caret" data-bs-toggle="dropdown" href="#"><i class="fa fa-gear d-block text-center text-700 small opacity-50 opacity-100-hover cursor-pointer" role="img" aria-label="Settings" title="Settings"/></a>
|
||||
<div class="dropdown-menu cursor-default" role="menu">
|
||||
<a t-if="!widget.isMobile" role="menuitem" class="dropdown-item o_kanban_toggle_fold" href="#">Fold</a>
|
||||
<t t-if="widget.grouped_by_m2o">
|
||||
@@ -29,7 +29,7 @@
|
||||
</t>
|
||||
</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>
|
||||
<a t-if="widget.quick_create" class="o_kanban_quick_add"><i class="fa fa-plus d-block small text-center text-700 opacity-50 opacity-100-hover cursor-pointer" role="img" aria-label="Quick add" title="Quick add"/></a>
|
||||
</div>
|
||||
</div>
|
||||
<div t-if="widget.loadMoreCount > 0" class="o_kanban_load_more">
|
||||
@@ -57,7 +57,7 @@
|
||||
</div>
|
||||
<span t-if="!widget.isMobile" class="o_discard_msg text-muted float-end">Esc to discard</span>
|
||||
<t t-if="widget.examples && !widget.isMobile">
|
||||
<button type="button" class="btn btn-link o_kanban_examples">See examples</button>
|
||||
<button type="button" class="btn btn-link o_kanban_examples p-0">See examples</button>
|
||||
</t>
|
||||
</div>
|
||||
<div class="o_kanban_muted_record"/>
|
||||
@@ -157,9 +157,9 @@
|
||||
<div t-if="example.description" class="o_kanban_examples_description">
|
||||
<t t-out="example.description"/>
|
||||
</div>
|
||||
<div class="o_kanban_examples">
|
||||
<div class="o_kanban_examples d-flex p-2">
|
||||
<t t-foreach="example.columns" t-as="column">
|
||||
<div class="o_kanban_examples_group">
|
||||
<div class="o_kanban_examples_group flex-grow-1 m-3">
|
||||
<h6><b><t t-esc="column"/></b></h6>
|
||||
<t t-foreach="_.random(1,4)">
|
||||
<t t-call="KanbanView.ExamplesDialog.RecordGhost"/>
|
||||
@@ -173,23 +173,23 @@
|
||||
</div>
|
||||
</div>
|
||||
<t t-name="KanbanView.ExamplesDialog.RecordGhost">
|
||||
<div class="o_kanban_examples_ghost">
|
||||
<div class="o_ghost_content"/>
|
||||
<div class="o_ghost_content o_ghost_tag"/>
|
||||
<div class="o_kanban_examples_ghost o_collapse p-2 border bg-white">
|
||||
<div class="o_ghost_content pb-3 bg-300"/>
|
||||
<div class="o_ghost_content o_ghost_tag d-inline-block w-50 mt-3 pb-3 bg-300"/>
|
||||
<t t-if="example.bullets and _.random(0, 5) > 3">
|
||||
<t t-out="_.sample(example.bullets)"/>
|
||||
</t>
|
||||
<img class="float-end o_ghost_avatar" src="/base/static/img/avatar.png" alt="Avatar"/>
|
||||
<img class="float-end o_ghost_avatar mt-2" src="/base/static/img/avatar.png" alt="Avatar"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<!-- Kanban Example Background -->
|
||||
<t t-name="KanbanView.ExamplesBackground">
|
||||
<div class="o_kanban_example_background_container">
|
||||
<div class="o_kanban_example_background">
|
||||
<div class="o_kanban_examples">
|
||||
<div class="o_kanban_example_background_container d-flex opacity-50">
|
||||
<div class="o_kanban_example_background flex-grow-1">
|
||||
<div class="o_kanban_examples d-flex p-2">
|
||||
<t t-foreach="ghostColumns" t-as="column">
|
||||
<div class="o_kanban_examples_group">
|
||||
<div class="o_kanban_examples_group flex-grow-1 m-3">
|
||||
<h6><b><t t-esc="column"/></b></h6>
|
||||
<t t-foreach="_.random(2,6)">
|
||||
<t t-call="KanbanView.ExamplesBackground.RecordGhost"/>
|
||||
@@ -201,10 +201,10 @@
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="KanbanView.ExamplesBackground.RecordGhost">
|
||||
<div class="o_kanban_examples_ghost">
|
||||
<div class="o_ghost_content"/>
|
||||
<div class="o_ghost_content o_ghost_tag"/>
|
||||
<img class="float-end o_ghost_avatar" src="/base/static/img/avatar.png" alt="Avatar"/>
|
||||
<div class="o_kanban_examples_ghost mb-3 p-2 border bg-white">
|
||||
<div class="o_ghost_content pb-3 bg-300"/>
|
||||
<div class="o_ghost_content o_ghost_tag d-inline-block w-50 mt-3 pb-3 bg-300"/>
|
||||
<img class="float-end o_ghost_avatar mt-2" src="/base/static/img/avatar.png" alt="Avatar"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="web.KanbanAnimatedNumber" owl="1">
|
||||
<div class="o_kanban_counter_side" t-att-class="state.value !== props.value and props.animationClass" t-att-title="props.title">
|
||||
<span t-if="props.currency and props.currency.position === 'before'" t-esc="props.currency.symbol" />
|
||||
<div class="o_kanban_counter_side ms-2 text-900 text-nowrap" t-att-class="state.value !== props.value and props.animationClass" t-att-title="props.title">
|
||||
<span t-if="props.currency and props.currency.position === 'before'" t-esc="props.currency.symbol" class="ms-1"/>
|
||||
<b t-esc="format(state.value)" />
|
||||
<span t-if="props.currency and props.currency.position === 'after'" t-esc="props.currency.symbol" />
|
||||
<span t-if="props.currency and props.currency.position === 'after'" t-esc="props.currency.symbol" class="ms-1"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
|
||||
<t t-name="web.KanbanExamplesNotebookTemplate" owl="1">
|
||||
<div t-if="props.description" class="o_kanban_examples_description" t-out="props.description"/>
|
||||
<div class="o_kanban_examples">
|
||||
<div class="o_kanban_examples d-flex p-2">
|
||||
<t t-foreach="columns" t-as="column" t-key="column.title">
|
||||
<div class="o_kanban_examples_group">
|
||||
<div class="o_kanban_examples_group flex-grow-1 m-3">
|
||||
<h6><b t-esc="column.title"/></h6>
|
||||
<div t-foreach="column.records" t-as="record" t-key="record.id" class="o_kanban_examples_ghost">
|
||||
<div class="o_ghost_content"/>
|
||||
<div class="o_ghost_content o_ghost_tag"/>
|
||||
<div t-foreach="column.records" t-as="record" t-key="record.id" class="o_kanban_examples_ghost p-2 border bg-white" t-att-class="{ 'o_collapse': record_index > 0 }">
|
||||
<div class="o_ghost_content pb-3 bg-300"/>
|
||||
<div class="o_ghost_content o_ghost_tag d-inline-block w-50 mt-3 pb-3 bg-300"/>
|
||||
<span class="ms-2" t-if="record.bullet" t-out="record.bullet"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,21 +10,8 @@
|
||||
border-color: $mix-full;
|
||||
}
|
||||
|
||||
.progress-bar.bg-#{$class} {
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
.oe_kanban_card_#{$class} {
|
||||
order: 1;
|
||||
margin-bottom: $o-kanban-inside-vgutter*0.5;
|
||||
|
||||
~ .oe_kanban_card_#{$class} {
|
||||
margin-top: -$o-kanban-inside-vgutter*0.5 - 1px;
|
||||
}
|
||||
|
||||
~ .o_kanban_load_more {
|
||||
margin-top: -$o-kanban-inside-vgutter*0.5;
|
||||
}
|
||||
}
|
||||
|
||||
.o_kanban_load_more {
|
||||
@@ -40,47 +27,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
// If columns has the progressbar, adapt the layout
|
||||
.o_kanban_view .o_kanban_group.o_kanban_has_progressbar {
|
||||
> .o_kanban_header .o_kanban_header_title {
|
||||
height: $o-kanban-header-title-height*0.6;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
&.o_kanban_no_records {
|
||||
.o_kanban_counter {
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.o_kanban_counter {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
transition: opacity 0.3s ease 0s;
|
||||
margin-bottom: $o-kanban-record-margin*2;
|
||||
|
||||
> .o_kanban_counter_progress {
|
||||
width: 76%;
|
||||
height: $font-size-sm;
|
||||
margin-bottom: 0;
|
||||
background-color: map-get($grays, '300');
|
||||
box-shadow: none;
|
||||
|
||||
.progress-bar {
|
||||
margin-bottom: 0;
|
||||
box-shadow: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
> .o_kanban_counter_side {
|
||||
width: 21%;
|
||||
margin-left: 3%;
|
||||
color: $headings-color;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
transform-origin: right center;
|
||||
|
||||
&.o_kanban_grow {
|
||||
@@ -90,53 +44,25 @@
|
||||
&.o_kanban_grow_huge {
|
||||
animation: grow_huge 1s ease 0s 1 normal none running;
|
||||
}
|
||||
|
||||
// Target currency icon
|
||||
> span {
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.o_column_folded .o_kanban_counter {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.o_kanban_view .o_kanban_group {
|
||||
@include o-kanban-css-filter(success, map-get($theme-colors, 'success'));
|
||||
@include o-kanban-css-filter(warning, map-get($theme-colors, 'warning'));
|
||||
@include o-kanban-css-filter(danger, map-get($theme-colors, 'danger'));
|
||||
@include o-kanban-css-filter(muted, map-get($theme-colors, 'dark'));
|
||||
|
||||
&.o_kanban_group_show {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
|
||||
> * {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
}
|
||||
@include o-kanban-css-filter(info, map-get($theme-colors, 'info'));
|
||||
}
|
||||
|
||||
@keyframes grow {
|
||||
0% {
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
30% {
|
||||
transform: scale3d(1.1, 1.1, 1.1);
|
||||
}
|
||||
100% {
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes grow_huge {
|
||||
0% {
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
30% {
|
||||
transform: scale3d(1.3, 1.3, 1.3);
|
||||
}
|
||||
100% {
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
|
||||
<t t-name="web.KanbanColumnQuickCreate" owl="1">
|
||||
<div class="o_column_quick_create" t-ref="root">
|
||||
<div t-if="props.folded" class="o_quick_create_folded" t-on-click="unfold">
|
||||
<div t-if="props.folded" class="o_quick_create_folded m-3 text-nowrap fw-bold opacity-75 opacity-100-hover" t-on-click="unfold">
|
||||
<button class="o_kanban_add_column btn btn-outline-secondary w-100">
|
||||
<i class="fa fa-plus me-2" role="img" aria-label="Add column" title="Add column"/><t t-out="props.groupByFieldString"/>
|
||||
</button>
|
||||
</div>
|
||||
<div t-else="" class="o_quick_create_unfolded">
|
||||
<div class="o_kanban_header">
|
||||
<div t-else="" class="o_quick_create_unfolded pt-3 px-2 pb-2">
|
||||
<div class="o_kanban_header top-0 pb-3">
|
||||
<div class="input-group">
|
||||
<input type="text"
|
||||
class="form-control o_input"
|
||||
class="form-control o_input bg-transparent fs-4"
|
||||
t-attf-placeholder="{{ props.groupByFieldString }}..."
|
||||
t-ref="autofocus"
|
||||
t-model.trim="state.columnTitle"
|
||||
@@ -25,14 +25,14 @@
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<span t-if="!env.isSmall and state.hasInputFocused" class="o_discard_msg text-muted float-end">
|
||||
<small t-if="!env.isSmall and state.hasInputFocused" class="o_discard_msg text-muted float-end">
|
||||
Esc to discard
|
||||
</span>
|
||||
</small>
|
||||
<t t-if="props.exampleData and !env.isSmall">
|
||||
<button type="button" class="btn btn-link o_kanban_examples" t-on-click="showExamples">See examples</button>
|
||||
<button type="button" class="btn btn-link o_kanban_examples p-0" t-on-click="showExamples">See examples</button>
|
||||
</t>
|
||||
</div>
|
||||
<div t-foreach="[,,,]" t-as="i" t-key="i_index" class="o_kanban_muted_record" />
|
||||
<div t-foreach="[,,,]" t-as="i" t-key="i_index" class="o_kanban_muted_record mt-3 py-5 bg-300" />
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
// ------- Kanban View Layout -------
|
||||
.o_kanban_renderer {
|
||||
display: flex;
|
||||
align-content: stretch;
|
||||
|
||||
.dropdown,
|
||||
.o_kanban_manage_button_section {
|
||||
position: inherit;
|
||||
@@ -29,29 +26,15 @@
|
||||
}
|
||||
|
||||
.o_kanban_quick_create {
|
||||
box-shadow: $box-shadow;
|
||||
margin: 0 $o-kanban-record-margin ($o-kanban-record-margin * 2);
|
||||
|
||||
.o_form_view {
|
||||
padding: 0;
|
||||
.o_group.o_inner_group {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.o_kanban_cancel {
|
||||
color: map-get($grays, "600"); // to make color uniform in community and enterprise
|
||||
}
|
||||
|
||||
&.o_disabled {
|
||||
pointer-events: none;
|
||||
opacity: 0.7;
|
||||
.o_form_view .o_group.o_inner_group {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.o_kanban_record {
|
||||
position: relative;
|
||||
display: inline-block; // Force the creation of a block formatting context to clear float items
|
||||
min-width: 150px;
|
||||
margin: 0 0 -1px;
|
||||
|
||||
@@ -68,13 +51,6 @@
|
||||
width: $o-kanban-color-border-width;
|
||||
}
|
||||
|
||||
.o_kanban_record_details {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// Inner Sections
|
||||
.o_kanban_record_top,
|
||||
.o_kanban_record_body {
|
||||
@@ -247,7 +223,6 @@
|
||||
}
|
||||
|
||||
.o_dragged {
|
||||
@extend .shadow;
|
||||
transform: rotate(-3deg);
|
||||
transition: transform 0.6s, box-shadow 0.3s;
|
||||
|
||||
@@ -461,8 +436,6 @@
|
||||
// Kanban Grouped Layout
|
||||
&.o_kanban_grouped {
|
||||
min-height: 100%;
|
||||
padding: 0;
|
||||
background-color: $gray-100;
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
min-height: initial;
|
||||
@@ -471,11 +444,8 @@
|
||||
scroll-snap-type: x mandatory;
|
||||
}
|
||||
|
||||
.o_kanban_record,
|
||||
.o_kanban_quick_create {
|
||||
.o_kanban_record {
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&.o_kanban_small_column .o_kanban_group:not(.o_column_folded) {
|
||||
@@ -485,29 +455,10 @@
|
||||
|
||||
// Kanban Grouped Layout - Column default
|
||||
.o_kanban_group {
|
||||
flex: 0 0 $o-kanban-default-record-width + 2 * $o-kanban-group-padding;
|
||||
flex-basis: $o-kanban-default-record-width + 2 * $o-kanban-group-padding;
|
||||
padding: 0 $o-kanban-group-padding $o-kanban-group-padding $o-kanban-group-padding;
|
||||
background-color: inherit;
|
||||
|
||||
.o_kanban_header > .o_kanban_header_title {
|
||||
@include o-kanban-header-title;
|
||||
|
||||
.o_column_title {
|
||||
flex: 1 1 auto;
|
||||
@include o-text-overflow;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.o_column_unfold {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.o_kanban_quick_add i {
|
||||
@include o-kanban-icon;
|
||||
margin-left: $o-kanban-inside-hgutter * 2;
|
||||
}
|
||||
|
||||
&:hover .o_kanban_config,
|
||||
.o_kanban_config.show {
|
||||
visibility: visible;
|
||||
@@ -522,9 +473,6 @@
|
||||
> .dropdown-menu {
|
||||
cursor: default;
|
||||
}
|
||||
i {
|
||||
@include o-kanban-icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -545,22 +493,11 @@
|
||||
}
|
||||
|
||||
.o_kanban_header_title {
|
||||
position: relative;
|
||||
opacity: 0.5;
|
||||
|
||||
.o_column_title {
|
||||
@include o-kanban-v-title;
|
||||
}
|
||||
.o_column_unfold {
|
||||
@include o-kanban-icon(1);
|
||||
}
|
||||
}
|
||||
|
||||
> .o_kanban_record,
|
||||
.o_kanban_quick_add,
|
||||
.o_kanban_config,
|
||||
.o_kanban_load_more {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
@@ -576,94 +513,42 @@
|
||||
.o_column_quick_create {
|
||||
flex: 0 0 $o-kanban-small-record-width + 2 * $o-kanban-group-padding;
|
||||
|
||||
.o_quick_create_folded {
|
||||
cursor: pointer;
|
||||
padding: 12px 16px;
|
||||
white-space: nowrap;
|
||||
font-weight: $font-weight-bold;
|
||||
@include o-hover-opacity(0.7);
|
||||
@include o-hover-text-color($text-muted, $body-color);
|
||||
}
|
||||
|
||||
.o_quick_create_unfolded {
|
||||
margin: $border-width ($o-kanban-inside-hgutter * 0.5) 0;
|
||||
padding: $o-kanban-inside-vgutter $o-kanban-inside-hgutter;
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.o_kanban_header {
|
||||
height: 50px;
|
||||
|
||||
.o_kanban_examples {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input,
|
||||
input:focus,
|
||||
input:hover {
|
||||
font-size: 16px;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.o_kanban_muted_record {
|
||||
background: map-get($grays, "300");
|
||||
height: 70px;
|
||||
margin: 10px 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
.o_kanban_group,
|
||||
.o_column_quick_create {
|
||||
flex: 1 0 90%; // don't take full width to give a hint of next/previous column
|
||||
flex-basis: 90%; // don't take full width to give a hint of next/previous column
|
||||
scroll-snap-align: center;
|
||||
overflow-y: scroll;
|
||||
|
||||
.o_kanban_header {
|
||||
position: sticky; // keep it visible
|
||||
top: 0;
|
||||
z-index: 10; // same as the sticky ControlPanel
|
||||
z-index: $zindex-sticky;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.o_kanban_header_title {
|
||||
margin-top: 0 !important; // avoid sticky glitch when scrolling
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Kanban UN-grouped Layout
|
||||
&.o_kanban_ungrouped {
|
||||
min-height: 100%;
|
||||
align-content: flex-start;
|
||||
flex-flow: row wrap;
|
||||
justify-content: flex-start;
|
||||
|
||||
padding: $o-kanban-record-margin ($o-horizontal-padding - $o-kanban-record-margin);
|
||||
|
||||
.o_kanban_record {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
width: $o-kanban-default-record-width;
|
||||
margin: ($o-kanban-record-margin * 0.5) $o-kanban-record-margin;
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
margin: 0 0 -1px 0;
|
||||
flex: 1 0 100%;
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
&.o_kanban_ghost {
|
||||
height: 0;
|
||||
border: none;
|
||||
min-height: 0 !important; // to prevent view writers to override this height
|
||||
visibility: hidden;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding: 0;
|
||||
max-height: 0 !important; // to prevent view writers to override this height
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -686,17 +571,6 @@
|
||||
|
||||
// ----------------- Set Cover Dialog -----------------
|
||||
.modal .o_kanban_cover_container .o_kanban_cover_image {
|
||||
border: 1px solid $border-color;
|
||||
height: 120px;
|
||||
width: 120px;
|
||||
cursor: pointer;
|
||||
|
||||
&.o_selected {
|
||||
border-color: $o-brand-primary;
|
||||
}
|
||||
|
||||
> img {
|
||||
@include o-position-absolute(0, 0, 0, 0);
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
<Dialog title="'Set a Cover Image'" size="'lg'">
|
||||
<div t-if="attachments.length" class="o_kanban_cover_container bg-100">
|
||||
<t t-foreach="attachments" t-as="attachment" t-key="attachment.id">
|
||||
<div class="o_kanban_cover_image position-relative d-inline-block m-2 bg-white" t-att-class="{
|
||||
o_selected: state.selectedAttachmentId === attachment.id,
|
||||
<div class="o_kanban_cover_image position-relative d-inline-block m-2 border bg-white o_cursor_pointer" t-att-class="{
|
||||
'o_selected border-primary': state.selectedAttachmentId === attachment.id,
|
||||
}">
|
||||
<img t-attf-src="/web/image/{{attachment.id}}?unique=1"
|
||||
class="m-auto mw-100"
|
||||
class="position-absolute start-0 end-0 top-0 bottom-0 mw-100 mh-100 m-auto"
|
||||
alt="Attachment"
|
||||
t-on-click="() => this.selectAttachment(attachment, false)"
|
||||
t-on-dblclick="() => this.selectAttachment(attachment, true)"
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
.o_kanban_dashboard:not(.o_legacy_kanban_view) {
|
||||
&:not(.o_kanban_grouped) {
|
||||
// correctly display the no_content_helper in dashboards
|
||||
flex-flow: row wrap;
|
||||
}
|
||||
|
||||
.o_kanban_record > div {
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
||||
@@ -46,54 +46,25 @@
|
||||
|
||||
// container ghost card in background
|
||||
.o_kanban_example_background_container {
|
||||
display: flex;
|
||||
padding: 0px;
|
||||
opacity: 0.4;
|
||||
|
||||
// content
|
||||
.o_kanban_example_background {
|
||||
flex: 1 1 100%;
|
||||
flex-basis: 100%;
|
||||
|
||||
.o_kanban_examples {
|
||||
.o_kanban_examples_group {
|
||||
.o_kanban_examples_ghost {
|
||||
width: 224px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
.o_kanban_examples .o_kanban_examples_group .o_kanban_examples_ghost {
|
||||
width: $o-kanban-small-record-width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// kanban ghost card
|
||||
.o_kanban_examples {
|
||||
display: flex;
|
||||
padding: 0 6px;
|
||||
.o_kanban_examples .o_kanban_examples_group .o_kanban_examples_ghost {
|
||||
&.o_collapse {
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.o_kanban_examples_group {
|
||||
flex: 1 1 100%;
|
||||
margin: 10px;
|
||||
|
||||
.o_kanban_examples_ghost {
|
||||
padding: 5px;
|
||||
margin-top: -1px;
|
||||
border: thin solid map-get($grays, '300');
|
||||
background-color: white;
|
||||
.o_ghost_content {
|
||||
height: 12px;
|
||||
background: map-get($grays, '300');
|
||||
&.o_ghost_tag {
|
||||
display: inline-block;
|
||||
width: 40%;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
.o_ghost_avatar {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
}
|
||||
.o_ghost_avatar {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ export class KanbanRecord extends Component {
|
||||
|
||||
getRecordClasses() {
|
||||
const { archInfo, canResequence, forceGlobalClick, group, record } = this.props;
|
||||
const classes = ["o_kanban_record"];
|
||||
const classes = ["o_kanban_record d-flex"];
|
||||
if (canResequence) {
|
||||
classes.push("o_record_draggable");
|
||||
}
|
||||
@@ -239,6 +239,9 @@ export class KanbanRecord extends Component {
|
||||
if (record.model.useSampleModel) {
|
||||
classes.push("o_sample_data_disabled");
|
||||
}
|
||||
if (!this.props.list.isGrouped) {
|
||||
classes.push("flex-grow-1 flex-md-shrink-1 flex-shrink-0");
|
||||
}
|
||||
return classes.join(" ");
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
|
||||
<t t-name="web.KanbanRecordQuickCreate" owl="1">
|
||||
<div
|
||||
class="o_kanban_quick_create"
|
||||
t-att-class="{ o_disabled: state.disabled }"
|
||||
class="o_kanban_quick_create shadow"
|
||||
t-att-class="{ o_disabled: state.disabled, 'w-100 mx-0': props.listIsGrouped }"
|
||||
t-ref="root"
|
||||
>
|
||||
<FormRenderer class="'o_form_view o_xxs_form_view'" record="props.record" archInfo="props.archInfo" />
|
||||
<FormRenderer class="'o_form_view o_xxs_form_view p-0'" record="props.record" archInfo="props.archInfo" />
|
||||
<div class="d-flex">
|
||||
<button class="btn btn-primary o_kanban_add me-1 text_truncate" t-on-click="() => this.validate('add')">
|
||||
Add
|
||||
@@ -15,7 +15,7 @@
|
||||
<button class="btn btn-primary o_kanban_edit me-1 text_truncate" t-on-click="() => this.validate('edit')">
|
||||
Edit
|
||||
</button>
|
||||
<button class="btn btn-secondary o_kanban_cancel ms-auto" t-on-click="() => this.cancel(true)">
|
||||
<button class="btn btn-secondary o_kanban_cancel ms-auto text-600" t-on-click="() => this.cancel(true)">
|
||||
<i class="fa fa-trash" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -61,11 +61,11 @@ export class KanbanRenderer extends Component {
|
||||
if (group) {
|
||||
dataGroupId = group.dataset.id;
|
||||
}
|
||||
element.classList.add("o_dragged");
|
||||
element.classList.add("o_dragged", "shadow");
|
||||
},
|
||||
onGroupEnter: (group) => group.classList.add("o_kanban_hover"),
|
||||
onGroupLeave: (group) => group.classList.remove("o_kanban_hover"),
|
||||
onStop: (_group, element) => element.classList.remove("o_dragged"),
|
||||
onStop: (_group, element) => element.classList.remove("o_dragged", "shadow"),
|
||||
onDrop: async ({ element, previous, parent }) => {
|
||||
element.classList.remove("o_record_draggable");
|
||||
const refId = previous ? previous.dataset.id : null;
|
||||
@@ -89,9 +89,9 @@ export class KanbanRenderer extends Component {
|
||||
// Hooks
|
||||
onStart: (_group, element) => {
|
||||
dataGroupId = element.dataset.id;
|
||||
element.classList.add("o_dragged");
|
||||
element.classList.add("o_dragged", "shadow");
|
||||
},
|
||||
onStop: (_group, element) => element.classList.remove("o_dragged"),
|
||||
onStop: (_group, element) => element.classList.remove("o_dragged", "shadow"),
|
||||
onDrop: async ({ element, previous }) => {
|
||||
element.classList.remove("o_group_draggable");
|
||||
const refId = previous ? previous.dataset.id : null;
|
||||
@@ -262,6 +262,9 @@ export class KanbanRenderer extends Component {
|
||||
if (!this.env.isSmall && group.isFolded) {
|
||||
classes.push("o_column_folded");
|
||||
}
|
||||
if (this.canResequenceGroups && group.value && !group.isFolded && !group.hasActiveProgressValue) {
|
||||
classes.push("bg-100");
|
||||
}
|
||||
if (group.progressBars.length) {
|
||||
classes.push("o_kanban_has_progressbar");
|
||||
if (!group.isFolded && group.hasActiveProgressValue) {
|
||||
|
||||
@@ -2,25 +2,25 @@
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="web.KanbanRenderer" owl="1">
|
||||
<div class="o_kanban_renderer o_renderer"
|
||||
t-attf-class="o_kanban_{{ props.list.isGrouped ? '' : 'un' }}grouped {{ props.archInfo.className or '' }}"
|
||||
<div class="o_kanban_renderer o_renderer d-flex"
|
||||
t-attf-class="{{ props.list.isGrouped ? 'o_kanban_grouped align-content-stretch' : 'o_kanban_ungrouped align-content-start flex-wrap justify-content-start' }} {{ props.archInfo.className or '' }}"
|
||||
t-ref="root"
|
||||
>
|
||||
<t t-foreach="getGroupsOrRecords()" t-as="groupOrRecord" t-key="groupOrRecord.key">
|
||||
<t t-if="groupOrRecord.group">
|
||||
<t t-set="group" t-value="groupOrRecord.group" />
|
||||
<div class="o_kanban_group"
|
||||
<div class="o_kanban_group flex-shrink-0 flex-grow-1 flex-md-grow-0"
|
||||
t-att-class="getGroupClasses(group)"
|
||||
t-att-data-id="(canResequenceRecords or canResequenceGroups) and group.id"
|
||||
t-on-click="(ev) => this.onGroupClick(group, ev)"
|
||||
>
|
||||
<div class="o_kanban_header">
|
||||
<div class="o_kanban_header_title" t-att="tooltipAttributes(group)">
|
||||
<span class="o_column_title" t-esc="getGroupName(group)"/>
|
||||
<div class="o_kanban_header top-0" t-attf-class="{{ !env.isSmall and group.isFolded ? 'pt-3' : 'py-3' }}">
|
||||
<div class="o_kanban_header_title position-relative d-flex align-items-center lh-lg text-900" t-att="tooltipAttributes(group)">
|
||||
<span class="o_column_title flex-grow-1 d-inline-block mw-100 text-truncate fs-4 fw-bold align-top" t-att-class="{ 'overflow-visible': !env.isSmall and group.isFolded }" t-esc="getGroupName(group)"/>
|
||||
<t t-if="env.isSmall or !group.isFolded">
|
||||
<Dropdown class="'o_kanban_config'" togglerClass="'btn p-0'">
|
||||
<Dropdown class="'o_kanban_config'" togglerClass="'btn p-0 border-0'">
|
||||
<t t-set-slot="toggler">
|
||||
<i class="fa fa-gear" role="img" aria-label="Settings" title="Settings" />
|
||||
<i class="fa fa-gear fa-stack d-block text-center text-700 small opacity-50 opacity-100-hover cursor-pointer" role="img" aria-label="Settings" title="Settings" />
|
||||
</t>
|
||||
<DropdownItem t-if="!env.isSmall" class="{
|
||||
'o_kanban_toggle_fold': true,
|
||||
@@ -47,21 +47,21 @@
|
||||
</DropdownItem>
|
||||
</t>
|
||||
</Dropdown>
|
||||
<span t-if="props.list.canQuickCreate()" class="o_kanban_quick_add" t-on-click="() => this.quickCreate(group)">
|
||||
<i class="fa fa-plus" role="img" aria-label="Quick add" title="Quick add" />
|
||||
</span>
|
||||
<button t-if="props.list.canQuickCreate()" class="o_kanban_quick_add btn p-0 border-0 fs-6 shadow-none" t-on-click="() => this.quickCreate(group)">
|
||||
<i class="fa fa-plus fa-stack d-block small text-end text-700 opacity-50 opacity-100-hover cursor-pointer" role="img" aria-label="Quick add" title="Quick add" />
|
||||
</button>
|
||||
</t>
|
||||
<span t-else="" class="o_column_unfold">
|
||||
<button t-else="" class="o_column_unfold btn btn-link d-block mt-0 mt-md-2 p-0 border-0 small text-center text-700 cursor-pointer">
|
||||
<i class="fa fa-arrows-h" role="img" aria-label="Unfold" title="Unfold" />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div t-if="(env.isSmall or !group.isFolded) and group.progressBars.length" class="o_kanban_counter">
|
||||
<div class="o_kanban_counter_progress progress">
|
||||
<div t-if="(env.isSmall or !group.isFolded) and group.progressBars.length" class="o_kanban_counter position-relative d-flex align-items-center justify-content-between" t-att-class="{ 'opacity-25': !group.count }">
|
||||
<div class="o_kanban_counter_progress progress w-75 bg-300">
|
||||
<t t-foreach="group.progressBars" t-as="progressBar" t-key="progressBar.value">
|
||||
<div t-if="progressBar.count"
|
||||
role="progressbar"
|
||||
class="progress-bar o_bar_has_records"
|
||||
t-att-class="{ 'progress-bar-animated progress-bar-striped': group.progressValue.active === progressBar.value }"
|
||||
class="progress-bar o_bar_has_records cursor-pointer"
|
||||
t-att-class="{ 'progress-bar-animated progress-bar-striped': group.progressValue.active === progressBar.value, 'border border-white': !group.isFolded and group.hasActiveProgressValue }"
|
||||
t-attf-class="bg-{{ progressBar.color }}"
|
||||
t-attf-style="width: {{ progressBar.count / (group.count or 1) * 100 }}%;"
|
||||
aria-valuemin="0"
|
||||
@@ -91,6 +91,7 @@
|
||||
archInfo="props.list.quickCreateInfo"
|
||||
onCancel="force => group.list.cancelQuickCreate(force)"
|
||||
onValidate="mode => this.validateQuickCreate(mode, group)"
|
||||
listIsGrouped="props.list.isGrouped"
|
||||
/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
@@ -144,16 +145,16 @@
|
||||
/>
|
||||
</t>
|
||||
<!-- Kanban Example Background -->
|
||||
<div t-if="props.list.groups.length === 0" class="o_kanban_example_background_container">
|
||||
<div class="o_kanban_example_background">
|
||||
<div class="o_kanban_examples">
|
||||
<div t-foreach="ghostColumns" t-as="column" t-key="column" class="o_kanban_examples_group">
|
||||
<div t-if="props.list.groups.length === 0" class="o_kanban_example_background_container d-flex opacity-50">
|
||||
<div class="o_kanban_example_background flex-grow-1">
|
||||
<div class="o_kanban_examples d-flex p-2">
|
||||
<div t-foreach="ghostColumns" t-as="column" t-key="column" class="o_kanban_examples_group flex-grow-1 m-3">
|
||||
<h6><b t-esc="column.name"/></h6>
|
||||
<div t-foreach="column.cards" t-as="card" t-key="card_index" class="o_kanban_examples_ghost">
|
||||
<div class="o_ghost_content"/>
|
||||
<div class="o_ghost_content o_ghost_tag"/>
|
||||
<div t-foreach="column.cards" t-as="card" t-key="card_index" class="o_kanban_examples_ghost d-flex flex-wrap justify-content-between mb-3 p-2 border bg-white">
|
||||
<div class="o_ghost_content w-100 pb-3 bg-300"/>
|
||||
<div class="o_ghost_content o_ghost_tag d-inline-block w-50 mt-3 pb-3 bg-300"/>
|
||||
<!-- FIXME WOWL example avatar is white on white (also in legacy) -->
|
||||
<img class="float-end o_ghost_avatar" src="/base/static/img/avatar.png" alt="Avatar"/>
|
||||
<img class="o_ghost_avatar" src="/base/static/img/avatar.png" alt="Avatar"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -162,7 +163,7 @@
|
||||
</t>
|
||||
<t t-else="">
|
||||
<!-- kanban ghost cards are used to properly space last elements. -->
|
||||
<div t-foreach="[,,,,,,]" t-as="i" t-key="i_index" class="o_kanban_record o_kanban_ghost" />
|
||||
<div t-foreach="[,,,,,,]" t-as="i" t-key="i_index" class="o_kanban_record o_kanban_ghost flex-grow-1 flex-md-shrink-1 flex-shrink-0 my-0" />
|
||||
</t>
|
||||
<t t-if="showNoContentHelper">
|
||||
<t t-if="props.noContentHelp" t-call="web.ActionHelper">
|
||||
|
||||
Reference in New Issue
Block a user