[IMP] mail: adds new props and buttons to handle comment Threads
This commit adds new optional props to the Message and Thread Components: closeThread, openThread, avatarPlaceholder and showDates. * `closeThread` is a function that enables the user to close an active comment thread. * `openThread` is a function that reopens a previously closed thread. * `avatarPlaceholder` is a boolean that will add an avatar placeholder (fa-user icon) when needed. For example when using Knowledge via the portal. * `showDates` enables us to hide the dates showed inside the Thread component, it may not be useful for certain comment threads. We also added a button inside the actionBox in the Message Component and it is only rendered if we are on the first message of the thread. The button can trigger either of the new function props depending on what is provided to the component. task-3317056 closes odoo/odoo#127380 Related: odoo/enterprise#41951 Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
@@ -58,6 +58,8 @@ export class Composer extends Component {
|
||||
mode: "normal",
|
||||
className: "",
|
||||
sidebar: true,
|
||||
showFullComposer: true,
|
||||
allowUpload: true
|
||||
};
|
||||
static props = [
|
||||
"composer",
|
||||
@@ -73,6 +75,8 @@ export class Composer extends Component {
|
||||
"className?",
|
||||
"sidebar?",
|
||||
"type?",
|
||||
"showFullComposer?",
|
||||
"allowUpload?"
|
||||
];
|
||||
static template = "mail.Composer";
|
||||
|
||||
@@ -233,7 +237,7 @@ export class Composer extends Component {
|
||||
}
|
||||
|
||||
get allowUpload() {
|
||||
return true;
|
||||
return this.props.allowUpload;
|
||||
}
|
||||
|
||||
get message() {
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
</t>
|
||||
</FileUploader>
|
||||
</div>
|
||||
<button t-if="thread and thread.type === 'chatter'" class="o-mail-Composer-fullComposer btn fa fa-expand m-1 border-0 rounded-pill" title="Full composer" aria-label="Full composer" type="button" t-on-click="onClickFullComposer"/>
|
||||
<button t-if="props.showFullComposer and thread and thread.type === 'chatter'" class="o-mail-Composer-fullComposer btn fa fa-expand m-1 border-0 rounded-pill" title="Full composer" aria-label="Full composer" type="button" t-on-click="onClickFullComposer"/>
|
||||
</div>
|
||||
<t t-if="!extended" t-call="mail.Composer.sendButton"/>
|
||||
</div>
|
||||
|
||||
@@ -70,6 +70,7 @@ export class Message extends Component {
|
||||
static defaultProps = {
|
||||
hasActions: true,
|
||||
isInChatWindow: false,
|
||||
showDates: true,
|
||||
};
|
||||
static props = [
|
||||
"hasActions?",
|
||||
@@ -83,6 +84,8 @@ export class Message extends Component {
|
||||
"thread?",
|
||||
"messageSearch?",
|
||||
"className?",
|
||||
"showDates?",
|
||||
"isFirstMessage?"
|
||||
];
|
||||
static template = "mail.Message";
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
<div t-if="!props.squashed" class="o-mail-Message-avatarContainer position-relative bg-view">
|
||||
<img class="o-mail-Message-avatar w-100 h-100 rounded" t-att-src="authorAvatarUrl" t-att-class="authorAvatarAttClass"/>
|
||||
</div>
|
||||
<t t-elif="!message.is_transient">
|
||||
<small t-if="isActive" class="o-mail-Message-date text-muted opacity-50 ms-2">
|
||||
<t t-elif="!message.isTransient">
|
||||
<small t-if="isActive and props.showDates" class="o-mail-Message-date text-muted opacity-50 ms-2">
|
||||
<t t-esc="messageService.dateSimple(message)"/>
|
||||
</small>
|
||||
<div t-else="" class="ms-2">
|
||||
@@ -121,7 +121,7 @@
|
||||
</t>
|
||||
|
||||
<t t-name="mail.Message.actions">
|
||||
<div t-if="props.hasActions and message.hasActions" class="o-mail-Message-actions"
|
||||
<div t-if="props.hasActions and message.hasActions and !state.isEditing" class="o-mail-Message-actions"
|
||||
t-att-class="{
|
||||
'start-0 ms-3': isAlignedRight,
|
||||
'end-0 me-3': (env.inChatWindow or ui.isSmall) and !isAlignedRight,
|
||||
|
||||
@@ -32,6 +32,7 @@ export const PRESENT_THRESHOLD = 2500;
|
||||
export class Thread extends Component {
|
||||
static components = { Message, Transition, DateSection };
|
||||
static props = [
|
||||
"showDates?",
|
||||
"isInChatWindow?",
|
||||
"jumpPresent?",
|
||||
"thread",
|
||||
@@ -39,11 +40,18 @@ export class Thread extends Component {
|
||||
"messageToReplyTo?",
|
||||
"order?",
|
||||
"scrollRef?",
|
||||
"showEmptyMessage?",
|
||||
"showJumpPresent?",
|
||||
"messageActions?",
|
||||
];
|
||||
static defaultProps = {
|
||||
isInChatWindow: false,
|
||||
jumpPresent: 0,
|
||||
order: "asc",
|
||||
showDates: true,
|
||||
showEmptyMessage: true,
|
||||
showJumpPresent: true,
|
||||
messageActions: true
|
||||
};
|
||||
static template = "mail.Thread";
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<t t-name="mail.Thread">
|
||||
<t t-if="env.inChatter" t-call="mail.Thread.jumpPresent"/> <!-- chatter has its own scrollable, this ensures proper sticky showing -->
|
||||
<div class="o-mail-Thread position-relative flex-grow-1 d-flex flex-column overflow-auto" t-att-class="{ 'pb-4': !state.showJumpPresent }" t-ref="messages" tabindex="-1">
|
||||
<div class="o-mail-Thread position-relative flex-grow-1 d-flex flex-column overflow-auto" t-att-class="{ 'pb-4': props.showJumpPresent and !state.showJumpPresent }" t-ref="messages" tabindex="-1">
|
||||
<t t-if="!props.thread.isEmpty or props.thread.loadOlder or props.thread.hasLoadingFailed" name="content">
|
||||
<div class="d-flex flex-column position-relative flex-grow-1" t-att-class="{'justify-content-end': !env.inChatter and props.thread.type !== 'mailbox'}">
|
||||
<span class="position-absolute w-100 invisible" t-att-class="props.order === 'asc' ? 'bottom-0' : 'top-0'" t-ref="present-treshold" t-att-style="`height: Min(${PRESENT_THRESHOLD}px, 100%)`"/>
|
||||
@@ -18,7 +18,7 @@
|
||||
<t t-if="!env.inChatter" t-call="mail.Thread.jumpPresent"/>
|
||||
</t>
|
||||
<t t-foreach="props.order === 'asc' ? props.thread.nonEmptyMessages : [...props.thread.nonEmptyMessages].reverse()" t-as="msg" t-key="msg.id">
|
||||
<t t-if="msg.dateDay !== currentDay">
|
||||
<t t-if="msg.dateDay !== currentDay and props.showDates">
|
||||
<DateSection date="msg.dateDay" className="'pt-4'"/>
|
||||
<t t-set="currentDay" t-value="msg.dateDay"/>
|
||||
</t>
|
||||
@@ -39,6 +39,9 @@
|
||||
onParentMessageClick="() => msg.parentMessage and env.messageHighlight?.highlightMessage(msg.parentMessage, props.thread)"
|
||||
thread="props.thread"
|
||||
messageEdition="props.messageEdition"
|
||||
isFirstMessage="msg_first"
|
||||
hasActions="props.messageActions"
|
||||
showDates="props.showDates"
|
||||
/>
|
||||
<t t-set="prevMsg" t-value="msg"/>
|
||||
</t>
|
||||
@@ -53,7 +56,7 @@
|
||||
</div>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="o-mail-Thread-empty d-flex flex-column align-items-center justify-content-center p-4 text-muted fst-italic h-100">
|
||||
<div class="o-mail-Thread-empty d-flex flex-column align-items-center justify-content-center text-muted fst-italic h-100" t-att-class="{'p-4': props.showEmptyMessage}">
|
||||
<t t-if="props.thread.isLoaded">
|
||||
<t t-if="props.thread.isEmpty and props.thread.type === 'mailbox'">
|
||||
<t t-if="props.thread.id === 'inbox'">
|
||||
@@ -76,7 +79,7 @@
|
||||
Messages marked as read will appear in the history.
|
||||
</t>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-elif="props.showEmptyMessage">
|
||||
There are no messages in this conversation.
|
||||
</t>
|
||||
</t>
|
||||
@@ -86,7 +89,7 @@
|
||||
</t>
|
||||
|
||||
<t t-name="mail.Thread.jumpPresent">
|
||||
<span t-if="state.showJumpPresent" class="o-mail-Thread-jumpPresent position-sticky btn btn-link alert alert-info d-flex cursor-pointer align-items-center py-2 m-0" t-att-class="{ 'px-4': !env.inChatWindow, 'px-2': env.inChatWindow, 'top-0': props.order !== 'asc', 'bottom-0': props.order === 'asc' }" role="button" t-on-click="() => this.jumpToPresent()">
|
||||
<span t-if="props.showJumpPresent and state.showJumpPresent" class="o-mail-Thread-jumpPresent position-sticky btn btn-link alert alert-info d-flex cursor-pointer align-items-center py-2 m-0" t-att-class="{ 'px-4': !env.inChatWindow, 'px-2': env.inChatWindow, 'top-0': props.order !== 'asc', 'bottom-0': props.order === 'asc' }" role="button" t-on-click="() => this.jumpToPresent()">
|
||||
<span class="small">You're viewing older messages</span>
|
||||
<span class="flex-grow-1"/>
|
||||
<span class="fw-bolder small pe-2">Jump to Present</span>
|
||||
|
||||
@@ -6,7 +6,7 @@ import { patch } from "@web/core/utils/patch";
|
||||
|
||||
patch(Composer.prototype, {
|
||||
get placeholder() {
|
||||
if (this.thread && this.thread.model !== "discuss.channel") {
|
||||
if (this.thread && this.thread.model !== "discuss.channel" && !this.props.placeholder) {
|
||||
if (this.props.type === "message") {
|
||||
return _t("Send a message to followers…");
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user