[REF] mail: Composer, review and simplify scss
Part of the overall v16 SCSS optimization/restyle, task-2704984 task-2812455 closes odoo/odoo#87439 Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
.o_Composer {
|
||||
// Could be replaced by .d-grid after the migration to BS5.
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"sidebar-header core-header"
|
||||
@@ -13,109 +14,37 @@
|
||||
|
||||
&.o-has-current-partner-avatar {
|
||||
grid-template-columns: 50px 1fr;
|
||||
padding: map-get($spacers, 3) map-get($spacers, 3) map-get($spacers, 4) map-get($spacers, 1);
|
||||
|
||||
&:not(.o-has-footer) {
|
||||
padding-bottom: map-get($spacers, 4);
|
||||
}
|
||||
|
||||
&:not(.o-has-header) {
|
||||
padding-top: map-get($spacers, 4);
|
||||
|
||||
&.o-is-in-thread-view {
|
||||
padding-top: map-get($spacers, 1);
|
||||
padding-bottom: map-get($spacers, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.o_Composer_actionButtons {
|
||||
&.o-composer-is-compact {
|
||||
display: flex;
|
||||
}
|
||||
&:not(.o-composer-is-compact) {
|
||||
margin-top: map-get($spacers, 2);
|
||||
}
|
||||
}
|
||||
|
||||
.o_Composer_attachmentList {
|
||||
flex: 1 1 auto;
|
||||
max-height: 300px;
|
||||
|
||||
&.o-composer-is-compact {
|
||||
max-height: 100px;
|
||||
}
|
||||
|
||||
&:not(.o-composer-is-compact) {
|
||||
overflow-y: auto;
|
||||
max-height: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
.o_Composer_buttons {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
align-self: stretch;
|
||||
flex: 0 0 auto;
|
||||
min-height: 41px; // match minimal-height of input, including border width
|
||||
|
||||
&:not(.o-composer-is-compact) {
|
||||
border: 0;
|
||||
height: auto;
|
||||
padding: 0 10px;
|
||||
width: 100%;
|
||||
}
|
||||
min-height: $o-mail-composer-text-input-height + $border-width; // match minimal-height of input, including border width
|
||||
}
|
||||
|
||||
.o_Composer_coreFooter {
|
||||
grid-area: core-footer;
|
||||
overflow-x: hidden;
|
||||
|
||||
&:not(.o-composer-is-compact) {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.o_Composer_coreHeader {
|
||||
grid-area: core-header;
|
||||
}
|
||||
|
||||
.o_Composer_cancelReply {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.o_Composer_coreMain {
|
||||
grid-area: core-main;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: flex-start;
|
||||
flex: 1 1 auto;
|
||||
|
||||
&:not(.o-composer-is-compact) {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.o_Composer_currentPartnerAvatar {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
.o_Composer_followers,
|
||||
.o_Composer_suggestedPartners {
|
||||
flex: 0 0 100%;
|
||||
margin-bottom: $o-mail-chatter-gap * 0.5;
|
||||
}
|
||||
|
||||
.o_Composer_primaryToolButtons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&.o-composer-is-compact {
|
||||
padding-left: map-get($spacers, 2);
|
||||
padding-right: map-get($spacers, 2);
|
||||
}
|
||||
width: $o-mail-thread-avatar-size;
|
||||
height: $o-mail-thread-avatar-size;
|
||||
}
|
||||
|
||||
.o_Composer_sidebarMain {
|
||||
@@ -123,148 +52,23 @@
|
||||
justify-self: center;
|
||||
}
|
||||
|
||||
.o_Composer_textInput {
|
||||
flex: 1 1 auto;
|
||||
align-self: stretch;
|
||||
|
||||
&:not(.o-composer-is-compact) {
|
||||
border: 0;
|
||||
min-height: 40px;
|
||||
}
|
||||
.o_Composer_textInput:not(.o-composer-is-compact) {
|
||||
min-height: $o-mail-composer-text-input-height;
|
||||
}
|
||||
|
||||
.o_Composer_threadTextualTypingStatus {
|
||||
font-size: $font-size-sm;
|
||||
|
||||
&:before {
|
||||
// invisible character so that typing status bar has constant height, regardless of text content.
|
||||
content: "\200b"; /* unicode zero width space character */
|
||||
}
|
||||
}
|
||||
|
||||
.o_Composer_toolButton {
|
||||
// keep a margin between the buttons to prevent their focus shadow from overlapping
|
||||
margin-left: map-get($spacers, 1);
|
||||
margin-right: map-get($spacers, 1);
|
||||
}
|
||||
|
||||
.o_Composer_toolButtons {
|
||||
display: flex;
|
||||
padding-top: map-get($spacers, 1);
|
||||
padding-bottom: map-get($spacers, 1);
|
||||
|
||||
&:not(.o-composer-is-compact) {
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
flex: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.o_Composer_toolButtonSeparator {
|
||||
flex: 0 0 auto;
|
||||
margin-top: map-get($spacers, 2);
|
||||
margin-bottom: map-get($spacers, 2);
|
||||
.o_Composer_threadTextualTypingStatus:before {
|
||||
// invisible character so that typing status bar has constant height, regardless of text content.
|
||||
content: "\200b"; /* unicode zero width space character */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Style
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
// TODO FIXME o-open on the button should be enough.
|
||||
// Style of button when popover is "open" comes from web.Popover, and we can't
|
||||
// define a modifier on .o_Composer_button due to not being aware of Popover's
|
||||
// state in context of template. https://github.com/odoo/owl/issues/693
|
||||
.o_is_open .o_Composer_toolButton {
|
||||
background-color: gray('200');
|
||||
}
|
||||
|
||||
.o_Composer {
|
||||
&:not(.o-messaging-in-editing) {
|
||||
background-color: gray('100');
|
||||
}
|
||||
|
||||
&.o-is-in-thread-view {
|
||||
background-color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
.o_Composer_actionButton.o-last.o-has-current-partner-avatar.o-composer-is-compact {
|
||||
border-radius: 0 $o-mail-rounded-rectangle-border-radius-lg $o-mail-rounded-rectangle-border-radius-lg 0;
|
||||
}
|
||||
|
||||
.o_Composer_button.o-composer-is-compact {
|
||||
border-left: none; // overrides bootstrap button style
|
||||
|
||||
:last-child {
|
||||
border-radius: 0 3px 3px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.o_Composer_buttonDiscard {
|
||||
border: $border-width solid lighten(gray('400'), 5%);
|
||||
border: $border-width solid lighten($gray-400, 5%);
|
||||
}
|
||||
|
||||
.o_Composer_buttons {
|
||||
border: 0;
|
||||
|
||||
&.o-messaging-in-editing {
|
||||
border-right: $border-width solid $border-color;
|
||||
}
|
||||
}
|
||||
|
||||
.o_Composer_coreMain:not(.o-composer-is-compact) {
|
||||
background: $white;
|
||||
border: $border-width solid $border-color;
|
||||
border-radius: $o-mail-rounded-rectangle-border-radius-lg;
|
||||
}
|
||||
|
||||
.o_Composer_currentPartnerAvatar {
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.o_Composer_textInput {
|
||||
appearance: none;
|
||||
outline: none;
|
||||
background-color: $white;
|
||||
border: $border-width solid $border-color;
|
||||
border-right: 0;
|
||||
|
||||
&:not(.o-composer-is-compact) {
|
||||
border: 0;
|
||||
border-radius: $o-mail-rounded-rectangle-border-radius-lg;
|
||||
}
|
||||
|
||||
&.o-has-current-partner-avatar.o-composer-is-compact {
|
||||
border-radius: $o-mail-rounded-rectangle-border-radius-lg 0 0 $o-mail-rounded-rectangle-border-radius-lg;
|
||||
}
|
||||
}
|
||||
|
||||
.o_Composer_toolButton {
|
||||
border: 0; // overrides bootstrap btn
|
||||
background-color: $white; // overrides bootstrap btn-light
|
||||
color: gray('600'); // overrides bootstrap btn-light
|
||||
border-radius: 50%;
|
||||
|
||||
&.o-open {
|
||||
background-color: gray('200');
|
||||
}
|
||||
}
|
||||
|
||||
.o_Composer_toolButtons {
|
||||
background-color: $white;
|
||||
border-top: $border-width solid $border-color;
|
||||
border-bottom: $border-width solid $border-color;
|
||||
|
||||
&:not(.o-composer-is-compact) {
|
||||
border-bottom: 0;
|
||||
border-radius: initial;
|
||||
}
|
||||
|
||||
&:last-child:not(.o-composer-has-current-partner-avatar) {
|
||||
border-right: $border-width solid lighten(gray('400'), 5%);
|
||||
}
|
||||
}
|
||||
|
||||
.o_Composer_toolButtonSeparator {
|
||||
border-left: $border-width solid $border-color;
|
||||
.o_Composer_toolButtons:last-child:not(.o-composer-has-current-partner-avatar) {
|
||||
border-right: $border-width solid lighten($gray-400, 5%);
|
||||
}
|
||||
|
||||
@@ -6,12 +6,16 @@
|
||||
<div class="o_Composer"
|
||||
t-att-class="{
|
||||
'o-focused': composerView.isFocused,
|
||||
'o-has-current-partner-avatar': composerView.hasCurrentPartnerAvatar,
|
||||
'o-has-current-partner-avatar pr-3 pl-1': composerView.hasCurrentPartnerAvatar,
|
||||
'o-has-footer': composerView.hasFooter,
|
||||
'o-has-header': composerView.hasHeader,
|
||||
'o-is-in-thread-view': composerView.threadView,
|
||||
'o-is-in-thread-view bg-white': composerView.threadView,
|
||||
'o-is-compact': composerView.isCompact,
|
||||
'o-messaging-in-editing': composerView.messageViewInEditing,
|
||||
'bg-100': !composerView.messageViewInEditing and !composerView.threadView,
|
||||
'pt-3 pb-4': composerView.hasCurrentPartnerAvatar and composerView.hasHeader,
|
||||
'py-4': composerView.hasCurrentPartnerAvatar and !composerView.hasHeader and !composerView.threadView,
|
||||
'py-1': composerView.hasCurrentPartnerAvatar and !composerView.hasHeader and composerView.threadView,
|
||||
}"
|
||||
t-attf-class="{{ className }}"
|
||||
t-on-keydown="composerView.onKeydown"
|
||||
@@ -27,7 +31,7 @@
|
||||
<div class="o_Composer_coreHeader text-truncate">
|
||||
<t t-if="composerView.threadView and composerView.threadView.replyingToMessageView">
|
||||
Replying to <b t-esc="composerView.threadView.replyingToMessageView.message.authorName"/>
|
||||
<i t-if="composerView.threadView.thread !== messaging.inbox" class="o_Composer_cancelReply fa fa-lg fa-times-circle rounded-circle p-0 ml-1" title="Stop replying" t-on-click="composerView.onClickStopReplying"/>
|
||||
<i t-if="composerView.threadView.thread !== messaging.inbox" class="o_Composer_cancelReply fa fa-lg fa-times-circle rounded-circle p-0 ml-1 o_cursor_pointer" title="Stop replying" t-on-click="composerView.onClickStopReplying"/>
|
||||
</t>
|
||||
<t t-if="composerView.hasThreadName">
|
||||
<span class="o_Composer_threadName">
|
||||
@@ -36,7 +40,7 @@
|
||||
</t>
|
||||
<t t-if="composerView.hasFollowers and !composerView.composer.isLog">
|
||||
<!-- Text for followers -->
|
||||
<small class="o_Composer_followers">
|
||||
<small class="o_Composer_followers flex-shrink-0">
|
||||
<b class="text-muted">To: </b>
|
||||
<em class="text-muted">Followers of </em>
|
||||
<b>
|
||||
@@ -55,42 +59,46 @@
|
||||
<t t-if="composerView.hasCurrentPartnerAvatar">
|
||||
<div class="o_Composer_sidebarMain">
|
||||
<t t-if="!messaging.currentGuest or composerView.composer.activeThread.model !== 'mail.channel'">
|
||||
<img class="o_Composer_currentPartnerAvatar rounded-circle" t-att-src="composerView.currentPartnerAvatar" alt="Avatar of user"/>
|
||||
<img class="o_Composer_currentPartnerAvatar rounded-circle o_object_fit_cover" t-att-src="composerView.currentPartnerAvatar" alt="Avatar of user"/>
|
||||
</t>
|
||||
<t t-if="messaging.currentGuest and composerView.composer.activeThread.model === 'mail.channel'">
|
||||
<img class="o_Composer_currentPartnerAvatar rounded-circle" t-attf-src="/mail/channel/{{ composerView.composer.activeThread.id }}/guest/{{ messaging.currentGuest.id }}/avatar_128?unique={{ messaging.currentGuest.name }}" alt="Avatar of guest"/>
|
||||
<img class="o_Composer_currentPartnerAvatar rounded-circle o_object_fit_cover" t-attf-src="/mail/channel/{{ composerView.composer.activeThread.id }}/guest/{{ messaging.currentGuest.id }}/avatar_128?unique={{ messaging.currentGuest.name }}" alt="Avatar of guest"/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
<div
|
||||
class="o_Composer_coreMain"
|
||||
class="o_Composer_coreMain d-flex flex-nowrap align-items-start flex-grow-1"
|
||||
t-att-class="{
|
||||
'o-composer-is-compact': composerView.isCompact,
|
||||
'flex-column border rounded-lg bg-white': !composerView.isCompact,
|
||||
}"
|
||||
>
|
||||
<ComposerTextInput
|
||||
className="'o_Composer_textInput'"
|
||||
className="'o_Composer_textInput flex-grow-1 align-self-stretch'"
|
||||
classNameObj="{
|
||||
'o-composer-is-compact': composerView.isCompact,
|
||||
'rounded-lg': !composerView.isCompact,
|
||||
'o_Composer_textInput-mobile': messaging.device.isSmall,
|
||||
'o-has-current-partner-avatar': composerView.hasCurrentPartnerAvatar,
|
||||
'rounded-lg-left': composerView.isCompact and composerView.hasCurrentPartnerAvatar,
|
||||
}"
|
||||
record="composerView"
|
||||
t-key="composerView.localId"
|
||||
/>
|
||||
<div class="o_Composer_buttons" t-att-class="{ 'o-composer-is-compact': composerView.isCompact, 'o-isDeviceSmall': messaging.device.isSmall, 'o-messaging-in-editing': composerView and composerView.messageViewInEditing }">
|
||||
<div class="o_Composer_toolButtons"
|
||||
<div class="o_Composer_buttons d-flex align-items-stretch align-self-stretch flex-shrink-0" t-att-class="{ 'o-composer-is-compact': composerView.isCompact, 'h-auto w-100 px-3': !composerView.isCompact, 'o-isDeviceSmall': messaging.device.isSmall, 'o-messaging-in-editing border-right': composerView and composerView.messageViewInEditing }">
|
||||
<div class="o_Composer_toolButtons d-flex py-1 border-top bg-white"
|
||||
t-att-class="{
|
||||
'o-composer-has-current-partner-avatar': composerView.hasCurrentPartnerAvatar,
|
||||
'o-composer-is-compact': composerView.isCompact,
|
||||
'o-composer-is-compact border-bottom': composerView.isCompact,
|
||||
'flex-row flex-grow-1 justify-content-between': !composerView.isCompact,
|
||||
}">
|
||||
<t t-if="composerView.isCompact">
|
||||
<div class="o_Composer_toolButtonSeparator"/>
|
||||
<div class="o_Composer_toolButtonSeparator flex-shrink-0 my-2 border-left"/>
|
||||
</t>
|
||||
<div class="o_Composer_primaryToolButtons" t-att-class="{ 'o-composer-is-compact': composerView.isCompact }">
|
||||
<button class="o_Composer_button o_Composer_buttonEmojis o_Composer_toolButton btn btn-light"
|
||||
<div class="o_Composer_primaryToolButtons d-flex align-items-center" t-att-class="{ 'o-composer-is-compact px-2': composerView.isCompact }">
|
||||
<button class="o_Composer_button o_Composer_buttonEmojis o_Composer_toolButton btn btn-light mx-1 border-0 rounded-pill bg-white"
|
||||
t-att-class="{
|
||||
'o-open': composerView.emojisPopoverView,
|
||||
'o-open bg-200': composerView.emojisPopoverView,
|
||||
'o-isDeviceSmall': messaging.device.isSmall,
|
||||
}"
|
||||
t-on-keydown="composerView.onKeydownButtonEmojis"
|
||||
@@ -100,11 +108,11 @@
|
||||
<i class="fa fa-smile-o"/>
|
||||
</button>
|
||||
<PopoverView t-if="composerView.emojisPopoverView" record="composerView.emojisPopoverView"/>
|
||||
<button class="o_Composer_button o_Composer_buttonAttachment o_Composer_toolButton btn btn-light fa fa-paperclip" t-att-class="{ 'o-isDeviceSmall': messaging.device.isSmall }" title="Add attachment" type="button" t-on-click="composerView.onClickAddAttachment"/>
|
||||
<button class="o_Composer_button o_Composer_buttonAttachment o_Composer_toolButton btn btn-light fa fa-paperclip mx-1 border-0 rounded-pill bg-white" t-att-class="{ 'o-isDeviceSmall': messaging.device.isSmall }" title="Add attachment" type="button" t-on-click="composerView.onClickAddAttachment"/>
|
||||
</div>
|
||||
<t t-if="composerView.isExpandable">
|
||||
<div class="o_Composer_secondaryToolButtons">
|
||||
<button class="btn btn-light fa fa-expand o_Composer_button o_Composer_buttonFullComposer o_Composer_toolButton" t-att-class="{ 'o-isDeviceSmall': messaging.device.isSmall }" title="Full composer" type="button" t-on-click="composerView.onClickFullComposer"/>
|
||||
<button class="o_Composer_button o_Composer_buttonFullComposer o_Composer_toolButton btn btn-light fa fa-expand mx-1 border-0 rounded-pill bg-white" t-att-class="{ 'o-isDeviceSmall': messaging.device.isSmall }" title="Full composer" type="button" t-on-click="composerView.onClickFullComposer"/>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
@@ -114,14 +122,14 @@
|
||||
</div>
|
||||
</div>
|
||||
<t t-if="composerView.hasFooter">
|
||||
<div class="o_Composer_coreFooter" t-att-class="{ 'o-composer-is-compact': composerView.isCompact }">
|
||||
<div class="o_Composer_coreFooter overflow-auto" t-att-class="{ 'o-composer-is-compact': composerView.isCompact, 'ms-0': !composerView.isCompact }">
|
||||
<t t-if="composerView.hasThreadTyping">
|
||||
<ThreadTextualTypingStatus className="'o_Composer_threadTextualTypingStatus'" thread="composerView.composer.activeThread"/>
|
||||
<ThreadTextualTypingStatus className="'o_Composer_threadTextualTypingStatus small'" thread="composerView.composer.activeThread"/>
|
||||
</t>
|
||||
<AttachmentList
|
||||
t-if="composerView.attachmentList"
|
||||
className="'o_Composer_attachmentList'"
|
||||
classNameObj="{ 'o-composer-is-compact': composerView.isCompact }"
|
||||
className="'o_Composer_attachmentList flex-grow-1'"
|
||||
classNameObj="{ 'o-composer-is-compact': composerView.isCompact, 'overflow-auto': !composerView.isCompact }"
|
||||
record="composerView.attachmentList"
|
||||
/>
|
||||
<t t-if="!composerView.isCompact">
|
||||
@@ -137,13 +145,14 @@
|
||||
</t>
|
||||
|
||||
<t t-name="mail.Composer.actionButtons" owl="1">
|
||||
<div class="o_Composer_actionButtons" t-att-class="{ 'o-composer-is-compact': composerView.isCompact }">
|
||||
<div class="o_Composer_actionButtons" t-att-class="{ 'o-composer-is-compact d-flex': composerView.isCompact, 'mt-2': !composerView.isCompact }">
|
||||
<t t-if="composerView.hasSendButton">
|
||||
<button class="o_Composer_actionButton o_Composer_button o_Composer_buttonSend btn btn-primary"
|
||||
t-att-class="{
|
||||
'o-last': !composerView.hasDiscardButton,
|
||||
'o-composer-is-compact': composerView.isCompact,
|
||||
'o-composer-is-compact border-left-0': composerView.isCompact,
|
||||
'o-has-current-partner-avatar': composerView.hasCurrentPartnerAvatar,
|
||||
'rounded-0 rounded-lg-right': !composerView.hasDiscardButton and composerView.hasCurrentPartnerAvatar and composerView.isCompact,
|
||||
}"
|
||||
t-att-disabled="!composerView.composer.canPostMessage ? 'disabled' : ''"
|
||||
type="button"
|
||||
@@ -154,7 +163,7 @@
|
||||
</button>
|
||||
</t>
|
||||
<t t-if="composerView.hasDiscardButton">
|
||||
<button class="o_Composer_actionButton o-last o_Composer_button o_Composer_buttonDiscard btn btn-secondary" t-att-class="{ 'o-composer-is-compact': composerView.isCompact, 'o-has-current-partner-avatar': composerView.hasCurrentPartnerAvatar }" type="button" t-on-click="composerView.onClickDiscard">
|
||||
<button class="o_Composer_actionButton o-last o_Composer_button o_Composer_buttonDiscard btn btn-secondary" t-att-class="{ 'o-composer-is-compact border-left-0': composerView.isCompact, 'o-has-current-partner-avatar': composerView.hasCurrentPartnerAvatar, 'rounded-0 rounded-lg-right': composerView.hasCurrentPartnerAvatar and composerView.isCompact }" type="button" t-on-click="composerView.onClickDiscard">
|
||||
Discard
|
||||
</button>
|
||||
</t>
|
||||
|
||||
Reference in New Issue
Block a user