[IMP] web,hr_holiday: improve calendar filter panel
We replaced the customized checkboxes with the original input element with `.form-check-input` whilst still using the custom colors for more consistency accross modules. Avatars have the .o_avatar class added to them which allows us to resize them with the CSS variable. And SCSS has been replaced with utility classes where possible. This commit has been moved here from PR https://github.com/odoo/odoo/pull/127532 task-3389317 Part-of: odoo/odoo#138670
This commit is contained in:
committed by
Leonardo Pavan Rocha
parent
f9222c4976
commit
775ff75e40
+2
-22
@@ -1,10 +1,7 @@
|
||||
.o_calendar_filter {
|
||||
span {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
& img {
|
||||
width:30px;
|
||||
img:not(.o_avatar) {
|
||||
width: 30px;
|
||||
|
||||
&.o_calendar_filter_plain {
|
||||
content:var(--calendarFilter-icon--plain);
|
||||
@@ -19,23 +16,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.o_timeoff_legend {
|
||||
display: inline-block;
|
||||
width: 24px;
|
||||
height: 30px;
|
||||
margin: 0 3px;
|
||||
padding: 3px 0;
|
||||
text-align: center;
|
||||
|
||||
&_bankholiday {
|
||||
background-color: $gray-200;
|
||||
}
|
||||
|
||||
&_mandatoryday {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
@for $size from 1 through length($o-colors) {
|
||||
.hr_mandatory_day_#{$size - 1}:not(.fc-disabled-day) {
|
||||
color: nth($o-colors, $size) !important;
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
|
||||
<t t-name="hr_holidays.CalendarFilterPanel" t-inherit="web.CalendarFilterPanel" t-inherit-mode="primary">
|
||||
<xpath expr="//t[@t-foreach='props.model.filterSections']" position="after">
|
||||
<div class="o_calendar_filter">
|
||||
<div class="o_calendar_filter mt-4">
|
||||
<h5>Legend</h5>
|
||||
<div class="d-flex flex-column">
|
||||
<span><img class="o_calendar_filter_plain" src="/hr/static/src/img/icons/plain.svg"/> Validated</span>
|
||||
<span><img class="o_calendar_filter_hatched" src="/hr/static/src/img/icons/hatched.svg"/> To Approve</span>
|
||||
<span><img class="o_calendar_filter_line" src="/hr/static/src/img/icons/line.svg"/> Refused</span>
|
||||
<span class="align-middle"><img class="o_calendar_filter_plain" src="/hr/static/src/img/icons/plain.svg"/> Validated</span>
|
||||
<span class="align-middle"><img class="o_calendar_filter_hatched" src="/hr/static/src/img/icons/hatched.svg"/> To Approve</span>
|
||||
<span class="align-middle"><img class="o_calendar_filter_line" src="/hr/static/src/img/icons/line.svg"/> Refused</span>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-column mt-4" t-if="leaveState.mandatoryDays.length">
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
<t t-name="hr_holidays.CalendarFilterPanel.filter" t-inherit="web.CalendarFilterPanel.filter" t-inherit-mode="primary">
|
||||
<xpath expr="//span[@t-esc='filter.label']" position="replace">
|
||||
<span class="o_cw_filter_title text-truncate flex-grow">
|
||||
<span class="o_cw_filter_title flex-grow-1 text-truncate lh-base">
|
||||
<t t-esc="filter.label"/>
|
||||
|
||||
<t t-if="env.isSmall">
|
||||
|
||||
@@ -28,6 +28,9 @@ $o-cw-filter-avatar-size: 20px;
|
||||
}
|
||||
|
||||
.o_calendar_sidebar_container {
|
||||
--Avatar-size: #{$o-cw-filter-avatar-size};
|
||||
|
||||
flex: 0 0 auto;
|
||||
position: relative;
|
||||
grid-area: side;
|
||||
background-color: $o-view-background-color;
|
||||
@@ -59,82 +62,17 @@ $o-cw-filter-avatar-size: 20px;
|
||||
}
|
||||
|
||||
.o_calendar_filter {
|
||||
font-size: 0.9em;
|
||||
padding: 2em 0 1em;
|
||||
|
||||
.o_cw_filter_collapse_icon {
|
||||
transition: all 0.3s ease;
|
||||
@include o-hover-opacity();
|
||||
font-size: 0.7em;
|
||||
}
|
||||
|
||||
.collapsed .o_cw_filter_collapse_icon {
|
||||
transform: rotate(90deg);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.o_calendar_filter_items_checkall,
|
||||
.o_calendar_filter_item {
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
|
||||
input {
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.o_cw_filter_input_bg {
|
||||
width: 1.3em;
|
||||
height: 1.3em;
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
border-radius: 1px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
|
||||
&.o_beside_avatar {
|
||||
width: $o-cw-filter-avatar-size;
|
||||
height: $o-cw-filter-avatar-size;
|
||||
border-radius: 2px;
|
||||
object-fit: cover;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
input:not(:checked) + label .o_cw_filter_input_bg {
|
||||
&:not(.o_cw_filter_avatar) {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
i.fa {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.o_cw_filter_avatar {
|
||||
width: $o-cw-filter-avatar-size;
|
||||
height: $o-cw-filter-avatar-size;
|
||||
border-radius: 2px;
|
||||
|
||||
&.fa {
|
||||
padding: 4px 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.o_cw_filter_title {
|
||||
line-height: $o-line-height-base;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
button.o_remove {
|
||||
@include o-position-absolute(0, 0, 0);
|
||||
transform: translateX(100%);
|
||||
transition: transform 0.2s;
|
||||
transform: translate(100%, -50%);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
button.o_remove {
|
||||
transform: translateX(0%);
|
||||
transform: translate(0%, -50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -573,10 +573,16 @@
|
||||
}
|
||||
|
||||
.o_cw_filter_color_#{$i - 1} {
|
||||
.o_cw_filter_input_bg:not(.no_filter_color) {
|
||||
&.form-check:hover .o_cw_filter_input_bg:not(.no_filter_color) {
|
||||
border-color: shade-color($color, 20%);
|
||||
}
|
||||
|
||||
.o_cw_filter_input_bg {
|
||||
border-color: $color;
|
||||
background: $color;
|
||||
color: color-contrast($color);
|
||||
|
||||
&:checked {
|
||||
background-color: $color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
overflow: hidden !important;
|
||||
}
|
||||
&.o-section-slide-enter-active {
|
||||
max-height: 20rem; // fixed value is required to properly trigger transition
|
||||
max-height: 100%; // max-height is required to properly trigger transition
|
||||
overflow: auto;
|
||||
}
|
||||
.o_calendar_filter_item {
|
||||
|
||||
@@ -5,63 +5,52 @@
|
||||
<t t-foreach="props.model.filterSections" t-as="section" t-key="section.fieldName">
|
||||
<t t-if="section.filters.length gt 0">
|
||||
<div
|
||||
class="o_calendar_filter"
|
||||
class="o_calendar_filter d-flex flex-column gap-1 mt-4"
|
||||
t-att-class="{'o-calendar-filter-panel--section-collapsed': isSectionCollapsed(section)}"
|
||||
t-att-data-name="section.fieldName"
|
||||
>
|
||||
<t t-if="section.label">
|
||||
<div class="d-flex">
|
||||
<div
|
||||
class="o_calendar_filter_items_checkall me-2"
|
||||
data-value="section"
|
||||
>
|
||||
<t t-set="filterId" t-value="nextFilterId" />
|
||||
<input
|
||||
type="checkbox"
|
||||
name="select-all"
|
||||
class="position-absolute"
|
||||
t-attf-id="o_calendar_filter_{{filterId}}"
|
||||
t-att-checked="isAllActive(section)"
|
||||
t-on-change="(ev) => this.onAllFilterInputChange(section, ev)"
|
||||
/>
|
||||
<div
|
||||
class="o_calendar_filter_items_checkall o-checkbox form-check"
|
||||
data-value="section"
|
||||
>
|
||||
<t t-set="filterId" t-value="nextFilterId"/>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="select-all"
|
||||
class="form-check-input"
|
||||
t-attf-id="o_calendar_filter_{{filterId}}"
|
||||
t-att-checked="isAllActive(section)"
|
||||
t-on-change="(ev) => this.onAllFilterInputChange(section, ev)"
|
||||
/>
|
||||
<t t-if="section.canCollapse">
|
||||
<label
|
||||
class="d-flex align-items-center m-0"
|
||||
t-attf-for="o_calendar_filter_{{filterId}}"
|
||||
>
|
||||
<span class="o_cw_filter_input_bg o_calendar_filter_all">
|
||||
<i class="fa fa-check position-relative" />
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<t t-if="section.canCollapse">
|
||||
<div
|
||||
class="justify-content-between align-items-center h5"
|
||||
class="d-flex align-items-center"
|
||||
type="button"
|
||||
t-on-click.stop.prevent="() => this.toggleSection(section, ev)"
|
||||
>
|
||||
<span class="o_cw_filter_label" t-esc="section.label" />
|
||||
<span class="o_cw_filter_label fw-bolder" t-esc="section.label"/>
|
||||
<i
|
||||
class="o_cw_filter_collapse_icon fa"
|
||||
t-attf-class="fa-chevron-{{ isSectionCollapsed(section) ? 'left' : 'down' }}"
|
||||
class="o_cw_filter_collapse_icon fa ms-1"
|
||||
t-attf-class="fa-caret-{{ isSectionCollapsed(section) ? 'left' : 'down' }}"
|
||||
/>
|
||||
</div>
|
||||
</label>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<h5 class="o_cw_filter_label" t-esc="section.label" />
|
||||
<label class="o_cw_filter_label fw-bolder" t-esc="section.label"/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
<Transition visible="!isSectionCollapsed(section)" name="'o-section-slide'" leaveDuration="350" t-slot-scope="transition">
|
||||
<div class="o_calendar_filter_items" t-att-class="transition.className">
|
||||
<div class="o_calendar_filter_items d-flex flex-column gap-1" t-att-class="transition.className">
|
||||
<t t-foreach="getSortedFilters(section)" t-as="filter" t-key="filter.value">
|
||||
<t t-set="filterId" t-value="nextFilterId" />
|
||||
<t t-call="{{ constructor.subTemplates.filter }}" />
|
||||
<t t-set="filterId" t-value="nextFilterId"/>
|
||||
<t t-call="{{ constructor.subTemplates.filter }}"/>
|
||||
</t>
|
||||
</div>
|
||||
</Transition>
|
||||
<t t-if="section.canAddFilter">
|
||||
<AutoComplete t-props="getAutoCompleteProps(section)" />
|
||||
<AutoComplete t-props="getAutoCompleteProps(section)"/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
@@ -70,56 +59,52 @@
|
||||
|
||||
<t t-name="web.CalendarFilterPanel.filter">
|
||||
<div
|
||||
class="o_calendar_filter_item w-100 position-relative mb-2"
|
||||
class="o_calendar_filter_item o-checkbox form-check position-relative w-100 overflow-hidden cursor-pointer"
|
||||
t-att-class="getFilterColor(filter)"
|
||||
t-att-data-value="filter.value"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="selection"
|
||||
class="position-absolute"
|
||||
class="o_cw_filter_input_bg form-check-input"
|
||||
t-att-style="filter.colorIndex and typeof filter.colorIndex !== 'number' ? `border-color: ${filter.colorIndex}; background-color: ${filter.colorIndex};` : ''"
|
||||
t-attf-id="o_calendar_filter_item_{{filterId}}"
|
||||
t-att-checked="filter.active"
|
||||
t-on-change="(ev) => this.onFilterInputChange(section, filter, ev)"
|
||||
/>
|
||||
<label
|
||||
class="d-flex align-items-start m-0"
|
||||
class="d-flex align-items-center gap-1"
|
||||
t-attf-for="o_calendar_filter_item_{{filterId}}"
|
||||
>
|
||||
<span
|
||||
class="o_cw_filter_input_bg d-flex flex-shrink-0 justify-content-center position-relative me-1 o_beside_avatar"
|
||||
>
|
||||
<i class="fa fa-check position-relative" />
|
||||
</span>
|
||||
<t t-if="section.hasAvatar and filter.hasAvatar">
|
||||
<img
|
||||
class="o_cw_filter_avatar flex-shrink-0 me-1"
|
||||
class="o_cw_filter_avatar o_avatar rounded"
|
||||
t-attf-src="/web/image/{{ section.avatar.model }}/{{ filter.value }}/{{ section.avatar.field }}"
|
||||
alt="Avatar"
|
||||
/>
|
||||
</t>
|
||||
<t t-elif="filter.type === 'all'">
|
||||
<i
|
||||
class="o_cw_filter_avatar fa fa-users fa-fw flex-shrink-0 me-1"
|
||||
class="o_cw_filter_avatar o_avatar fa fa-users fa-fw flex-shrink-0 me-1"
|
||||
role="img"
|
||||
aria-label="Avatar"
|
||||
title="Avatar"
|
||||
/>
|
||||
</t>
|
||||
<span
|
||||
class="o_cw_filter_title text-truncate flex-grow"
|
||||
class="o_cw_filter_title flex-grow-1 text-truncate lh-base"
|
||||
t-esc="filter.label"
|
||||
/>
|
||||
</label>
|
||||
<t t-if="filter.canRemove">
|
||||
<button
|
||||
class="o_remove btn bg-white text-700 py-0 px-2"
|
||||
class="o_remove btn position-absolute top-50 end-0 bg-white py-0 px-2 text-700 transition-base"
|
||||
role="img"
|
||||
title="Remove this favorite from the list"
|
||||
aria-label="Remove this favorite from the list"
|
||||
t-on-click="() => this.onFilterRemoveBtnClick(section, filter)"
|
||||
>
|
||||
<i class="fa fa-times" />
|
||||
<i class="oi oi-close"/>
|
||||
</button>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user