100 Commits
Author SHA1 Message Date
Alexandre Kühn 6944eb3118 [FIX] mail: make chatter flex in Documents app
The chatter in documents was not flex, which made it take a lot
of space without any wrapping. As a result, usually chatter took
all the screen and content was massively overflowing, resulting
in poor UX.

This was caused by a specific stylerule in documents with chatter
that made sense in a earlier version of chatter CSS, but this
is no longer needed.

Also we actually want to reuse most style of chatter in form view.
This commit adds `o-mail-ChatterContainer` classname on same
HTML node as `o-mail-Form-Chatter` and adapts style, so that
Document can set this classname to reuse style.

opw-3681435

closes odoo/odoo#161940

Related: odoo/enterprise#60772
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2024-04-22 11:51:24 +00:00
Alexandre Kühn 51b0834044 [FIX] mail: discuss quick search with custom named chat
Before this commit, when a DM chat had a custom name, the
search was not taking it into account.

Steps to reproduce:
- Log in as Mitchell Admin
- Open a DM chat with Marc Demo in Discuss app
- Rename conversation to "Test"
- Open more than 20 chat/channels (can create 20 channels)
- type "Test" in the quick search of discuss app sidebar
=> The DM chat with Marc Demo is not visible in filtered sidebar.

This happens because the quick search was relying on `thread.name`,
which actually only matches exactly the UI when this is the name
of a channel or when a group chat is explictly named.

The actual thread field used that matches textual name of thread
is `thread.displayName`, and this field is synced with custom DM
chat if any.

closes odoo/odoo#161540

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2024-04-11 16:43:22 +00:00
Alexandre Kühn 0aae1ae147 [FIX] mail: opening chat with deleted new message should mark as read
Before this commit, when a user of in chat posted a message and
deleted it, all other users kept the chat as unread.

Steps to reproduce:
- Connect as Admin and March Demo
- Send a message to Admin as Demo in DM chat
- Demo deletes this message
- Marc opens the chat
=> the unread counter is 1 and cannot be removed

This happens because when a message is deleted, there's still a
trace of it but the message is empty. However, empty messages could
not be candidate of setting the last message being seing by a member,
thus members were unable to mark the chat as read until someone else
posted a newer message (and did not delete it).

This commit fixes the issue by taking empty messages into account for
setting last message message of member, which allow to mark thread as
read even when newer messages have been deleted.

opw-3764410

closes odoo/odoo#158943

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2024-03-25 11:43:40 +00:00
Alexandre Kühn 885ae723d7 [FIX] im_livechat: mention partner in full composer should not crash
Making a mention in full composer when `im_livechat` is installed
was making the following crash:

```
TypeError: Cannot read properties of undefined (reading 'type')
    at SuggestionService.fetchSuggestions
```

Steps to reproduce:
- install module `im_livechat`
- open contacts app form view
- open full composer (e.g. Log note => expand icon)
- type @ + a character
=> throws error above

This happens because `SuggestionService` methods can optionally pass
a thread, but livechat overrides wrongfully assume they were always
provided.
This commit fixes the issue with optional chaining, taking into
account it's optional.

No test because full composer doesn't work in unit tests, tours
require adding steps blindly and I've already wasted too much time
to no avail.

closes odoo/odoo#156773

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2024-03-06 17:48:16 +00:00
Alexandre Kühn dca2921252 [FIX] mail: correctly display Logged in as in public page
`getLoggedInAsText` is a function, due to missing brackets
the function content was dumped instead of evaluation of function.

opw-3701333

closes odoo/odoo#151600

X-original-commit: 4ce21a4207a9dd7047a6b5ec9c447f9e48ca199c
Signed-off-by: Matthieu Stockbauer (tsm) <tsm@odoo.com>
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2024-01-29 23:16:19 +00:00
Alexandre Kühn 17a3a84aaa [FIX] mail: fold discuss app category when no conversation selected
Before this commit, when no conversation was selected in the
Discuss app, folding a category such as "Channels" results in
a crash.

This happens because `store.discuss.thread` is `undefined`, so it
must be properly guarded in the template of discuss sidebar category.

closes odoo/odoo#150828

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2024-01-24 12:30:09 +00:00
Alexandre Kühn e5d7c4fef2 [FIX] mail: squashed message don't grow on mousehover
Before this commit, when a message without bubble layout
is squashed (e.g. with `/who` command twice in a channel),
mouse-hovering on the squashed message pushed increased the
height of the message.

This happens because the sidebar of squashed message contains
the date and it uses 12-hour format with AM/PM.

This design requires cautious use of content in the sidebar,
and had 24-hour format to make it work. A recent refactoring
changed it to 12-hour format as localization was a better concern.
However, the UI is not designed for it, and there's not much value
in having 12-hour format rather than 24-hour format. Indeed,
users assume AM if no AM/PM is shown, except if hour is greater
than 12 which is quite obvious the current time.

12-hour format is best for some users, but we can't have it without
overhauling parts of the UI which is not worth it at the time of
this commit. Therefore using 24-hour format is the better tradeoff.

Also took the opportunity of this PR to better align the date and
seen indicator in squashed message sidebar.

Task-3637270

closes odoo/odoo#150369

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2024-01-23 04:41:44 +00:00
Alexandre Kühn 9b3a0b4aa0 [FIX] mail: no crash on edit message in mobile
Before this commit, editing a message in message in a conversation
and then pressing on the paper plane icon was throwing the following
error:

```
TypeError: null is not an object (evaluating 'thread.model')
@_sendMessage
```

This happens because this button was in "send" message mode rather
than in edit mode. Since we cannot post a message while editing a
message, the crash happens because composer is not related to thread
but the message.

This button is not visible in desktop mode, and user should use
suggested keyboard shortcuts or click on links to either save edit or
discard it. In mobile, these interactions are not intuitive.

This commit fixes the issue by keeping the paper-plane button while
editing in mobile but it acts as "save". The labels to save/discard
was not appropriate in mobile, so it has been turned to a simple
button to discard editing.

opw-3670482

closes odoo/odoo#148918

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2024-01-20 02:42:54 +00:00
Alexandre Kühn 8b5f8dea8b [FIX] mail: open chat window from home menu reliably
Before this commit, opening chat window from messaging menu
might not work.

Step to reproduce:
- open Discuss app
- Go to home menu
- Reload the page
- Click on Messaging Menu
- Click on chat item to open chat
=> Chat window is not open

This happens because when in the home menu from Discuss app
in background page reload, the URL contains the Discuss app
menu_id, but the action is "menu" rather the action id. This
difference is crucial to distinct discuss app being actively
open or it's in the background from home menu. The latter
should NOT consider Discuss app being open.

This is not a problem when opening/closing Discuss app, because
the mounting/unmounting of the Discuss app component is good
enough to detect that. However, with page reload, the way to
detect Discuss app being open from URL was only relying on `menu_id`
instead of `action` value.

This commit fixes the issue by checking `active_id` of discuss app
rather than `menu_id`, as `active_id` is 100% reliable whereas
`menu_id` is not. The problem with home menu is one example among
many other cases (e.g. page reload in channel settings form view).

closes odoo/odoo#149969

Related: odoo/enterprise#54638
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2024-01-19 05:20:52 +00:00
Alexandre Kühn c22fa19636 [FIX] mail: new message notif on channel only with needaction
Before this commit, any new message in a channel of type "channel"
was automatically opening a chat window and showing new message
counter in tab title when out-of-focus.

This behaviour is only intended for important messages. In chat
(group chat, DM chat, livechat), all new messages are considered
as important so this is good. However, for channels, these are
intended for communication with many users, and we only want to
notify on messages that are explicitly flagged as "needaction".
As a reminder, message are needaction through `@mention` or
reply-to for example.

This commit fixes the issue by limiting notifying out-of-focus of
new messages in channel "channel" to only needaction. Also the
auto-opening of chat window as a consequence from this new message
is also limited to needaction messages.

closes odoo/odoo#149943

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2024-01-19 01:36:08 +00:00
Alexandre Kühn 9f24bb72ec [FIX] mail: discuss jump to present scrolls reliably
Before this commit, when looking at old messages of a message,
clicking on "Jump to present" was frequently not scrolling to
most recent message.

This happens because loading messages is not immediate, and thread
UI has some heuristics to adjust scrolls that were working against
scrolling to present when the RPC to load messages around present
is not immediate.

This commit fixes the issue by handling the actual scroll to present
in the same workflow as all other scroll adjustments. Also the logic
for adjusting scrolls requires immediate scrolling, hence this commit
has to remove smooth scrolling to comply with current scroll
adjustment techniques.

closes odoo/odoo#149915

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2024-01-18 23:10:28 +00:00
Alexandre Kühn 52d34b69d6 [REV] mail: revert fix line break in customer rating feedback
This reverts commit 185adf6fb487fa260bb6dfe985638bc545de7fa2.

The change was made to "fix" line breaks with rating feedback in
helpdesk. However, it's not ok to apply `inline` display layout
for all non-user made message body, as usual block display is
expected for html tags like `<div>` or `<p>`.

The correct fix should be to remove these unwanted `<br>` in the
feedback rating messages. We don't know how they appeared, but
this is a specific minor issue in helpdesk rating, so reverting
the fix is a higher priority.

closes odoo/odoo#149570

X-original-commit: 1ba04da76f391cd4543a8d3b1e6dbecf6a2cb558
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2024-01-16 22:40:02 +00:00
Alexandre Kühn 5912e7b761 [FIX] mail: 'Logged _in_ as' on welcome page
Label of guest name on public discuss welcome page
was gramatically incorrect. It should be "Logged in as"
rather than "Logged as".

Also took the opportunity to properly translate the label.

closes odoo/odoo#149187

X-original-commit: 9463c787e7804e5c2c525b9ecc096ee067f0dd3d
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2024-01-12 12:50:36 +00:00
Alexandre Kühn c755f1763e [FIX] mail: no quick action on attachment on small device
When a message had more than 1 attachment, it was not possible
to preview the attachment on a mobile device.

This happens because the hover buttons for delete/download the
file took the whole clickable area of attachment to see the preview.

To enable quick actions in mobile, this require non-trivial UI
tweaking. To match behaviour of version 16.0, these quick-actions
have been disabled in mobile.

opw-3664795

closes odoo/odoo#148091

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2024-01-04 13:54:53 +00:00
Alexandre Kühn dc18313d42 [FIX] l10n_ke_edi_tremol:tests: freeze test to 2023
These test rely on default generated name of account invoice
that contains the year, e.g. `INV2023`. These tests were passing
in 2023 but no longer on January 1 2024.

closes odoo/odoo#147873

X-original-commit: 94f093c9ae532eb12ef17dc0f37dc5da64a6d7ed
Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2024-01-03 10:58:06 +00:00
Alexandre Kühn e5e01b884e [PERF] mail: faster opening of messaging menu
Before this commit, when many channels were pinned in Discuss,
the messaging menu took a while to open and render all items.

This happens because `fetchPreviews()` and `inbox.fetchNewMessages()`
were inserting data for each thread and message. This meant computed
and sorted fields were called with that many objects.

This commit improves the performances by wrapping all of it in an
update cycle transaction, so that computed and sorted fields are
invoked only once at the end of the update cycle.

With `contacts` installed, populate `medium`:
- Before this commit: 1min.
- With this commit:   2sec. (30x faster)

closes odoo/odoo#145980

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-12-14 17:57:00 +00:00
Alexandre Kühn ad45817435 [PERF] mail: no memoryerror from slow load_message_failures
Earlier PR improved ACLs in Discuss [1].

Route `/mail/load_message_failures` was made in non-sudo as to take
ACLs into account, so that we don't get mail failures that we don't
have access [2]

However, checking ACLs on `mail.message` from `search` on
`mail.notification` is very slow [3], to the point where the RPC
takes minutes and results in a `memoryerror`.

Ideally we should have non-sudo and make checking ACLs more
performant. As a quick fix in a stable version, we revert to using
`sudo`, which results in same quick results as before.

[1]: https://github.com/odoo/odoo/pull/138330
[2]: https://github.com/odoo/odoo/pull/138330/files#diff-6be51f3695e69474a19cf6857370c8bb9b529a15d568952258cec9a0ae519fc4R23
[3]: https://github.com/odoo/odoo/blob/17.0/addons/mail/models/res_partner.py#L251

closes odoo/odoo#146184

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-12-13 17:12:02 +00:00
Alexandre Kühn 10c9a55e50 [FIX] mail: invoke onAdd/onDelete hooks on inverse relational field
Before this commit, when adding on a many relational field with an
inverse, the `onAdd()` hook was not triggered on the inverse:

On the inverse, the `addNoinv` and `deleteNoinv` are invoked on
inverse. We forgot to invoke these hooks in these functions.

closes odoo/odoo#144999

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-12-05 22:40:41 +00:00
Alexandre Kühn a59c36731f [FIX] mail: lazy fields not properly recomputed
When a lazy field was computed on-the-fly by a getter and later
the field had its dependencies changed, the field was not
recomputed.

This happens because in this condition, the field is immediately
recomputed, and the code was always clearing the "in-need" flags
when recomputing the field.

This commit fixes the issue by preserving these "in-need" flags
at the end of the update cycle. Note that there's no way to detect
reactive "unread", so a lazy field will keep its "in-need" at least
for an extra update cycle.

Also transition of field flag "on-need" becoming `true` and field
was already "in-need" was not correctly computing/sorting the field.
This commit also fixes this issue.

Part-of: odoo/odoo#144999
2023-12-05 22:40:41 +00:00
Alexandre Kühn 3e443edcf9 [FIX] mail: insert data in relational field
Before this commit, when a record was identified by relational
fields, we couldn't insert this record by passing data rather than
the records.

We should be able to insert records and data in the models, so
passing data should be ok.

This commit fixes this issue by backporting some code of improvements
and fixes from master. Note that the internal code of model is
written for retrocompatibility, so some added features like
store.Model in diff is ok.

Part-of: odoo/odoo#144999
2023-12-05 22:40:41 +00:00
Alexandre Kühn 0761b4299e [FIX] mail: field.onAdd/Delete & record.delete at end of update cycle
Before this commit, the onAdd/onDelete hooks of fields and the
deletion of record was performed immediately. The main drawback was
that `this` and the record being added or deleted from a relational
field was in an intermediate state.

For example, if the record to be added had some computed fields,
the code executed by the `onAdd` hook was reading the field before
it was computed.

This commit fixes the issue by moving the execution of field hooks
`onAdd` and `onDelete` at the end of the update cycle on records,
after the compute methods.

Part-of: odoo/odoo#144999
2023-12-05 22:40:41 +00:00
Alexandre Kühn 2080f8fb18 [FIX] mail: self-author on 'Creating a new record...' message
Before this commit, when a record is in draft, the chatter message
"Creating a new record..." shown no author.

The intended showing is to display current user as author of this
message. Persona model requires `id` and `type`, the latter to
determine whether the persona is a guest or partner. Only the
id of current user was provided, so it was not enough to determine
the appropriate `Persona`.

closes odoo/odoo#144864

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-12-04 17:47:34 +00:00
Alexandre Kühn 0c998ef1cd [PERF] mail: faster load of discuss at init messaging
- Messaging menu was slow when there are many mail failures
- Discuss app is slow whenever there are many pinned threads
- Initial page load was slow when pinned threads were group chats
  with hundreds of members

All these performance issue come from aggressively eager call
to reactive callbacks, which `onChange()` and `compute()` were
relying on.

This commits fixes the performance issue with:
- Update cycle in `@mail/record`, which calls eager computed fields
  and onChange at the end of an update transaction in discuss models,
  so that computation is called only once rather than many times
  (while only the later value matter)
- Add support for lazy computed fields (which they are by default),
  so that computed fields are only computed when needed.
- Add support for sorted many fields, which also follow the update
  cycle and eager/lazy mode of field. This makes sorting operation
  on many fields efficient and preserves eventual correctness of
  expected order of items in these relational fields.

With module `contacts` installed and populate `--size="medium"`,
init_messaging and mail_failures took 12sec. for Mitchell Admin.
With this commit, this has been reduced to 1sec.

closes odoo/odoo#143382

Related: odoo/enterprise#51410
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-11-28 21:21:04 +00:00
Alexandre Kühn fbcab1fccc [FIX] mail: missing spacing in Messaging Menu 'New Message'
Follow-up of [1]

PR above made several improvements to Messaging Menu, especially
in mobile.

By mistake, it removes the spacing between "All"|"Chats"|"Channels"
and "New Message" in desktop.

This commit re-adds this spacing with `div.flex-grow-1`.

[1]: https://github.com/odoo/odoo/pull/140405

closes odoo/odoo#142186

Signed-off-by: Matthieu Stockbauer (tsm) <tsm@odoo.com>
2023-11-15 15:03:58 +00:00
Alexandre Kühn d68488db7d [FIX] mail: several slight messaging menu improvements
Before this commit, the Messaging Menu had the following issues:

- Header is too large;
- Header color in dark theme is too white;
- Important notifications (= needactions) are not highlighted enough
  compared to muted notifications;
- Notification body and title looked too alike;
  => title should be more visible than content
- Mouse-hovering on notification items breaks background-inherit
  style of avatar and IM status;
  => side-effect of `list-group-item-action`
- Desktop: Header items slightly move when changing selection;
  => comes from `fw-bolder`
- Desktop: mark as read button was too small and not visible enough;
- Mobile: too many borders, and they are too strong;
  => undesirable dropdown style
- Mobile: Messaging Menu had poor "New message" button link whereas
  Discuss app has nice "Start a conversation" button;
- Mobile: "Start a conversation" button is not shown on livechat tab;
- Mobile: when menu is open while Discuss app is open in background,
  it's unclear whether the messaging menu is open or not;
  => missing background highlight on Messaging Menu toggler
- Mobile: State of Mobile Discuss App was not synced properly when
  using Messaging Menu at the same time;
  => e.g. unselected tab
- Mobile: Discuss app and Messaging Menu were not properly aligned;
  => Messaging Menu did not offset position based on systray navbar
  height
- Mobile: active navbar item was not highlighted enough, especially
  in white theme;
- "OdooBot has a suggestion" is shown on all tabs instead of only
  in "All" tab like "OdooBot has a request";

This commit fixes all the above issues.
Some styling issues were also affecting the Activity Menu, such as
borders and highlighted open state. This commit applies these
few improvements on the Activity Menu too.

closes odoo/odoo#140405

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-11-07 19:32:15 +00:00
Alexandre Kühn f65699dbd1 [FIX] mail: OdooBot has a request notif should not be muted
Before this commit, the "OdooBot has a request" notification in the
Messaging Menu -- which suggest to enable push notifications -- had
a muted style, which looks as if the item is unimportant and was
read by the current user.

This is an important notification, at an equivalent level of
importance than needaction notifications. This was already
highlighted by this item contributing to the global Messaging Menu
counter.

This commit fixes the issue by not muting this notification. To do
so, it enhances prop `muted` on `NotificationItem` component:
- 0 (default): the notif is unmuted
- 1: the notif is slightly muted
- 2: the notif is hard-muted

0/1 are equivalent to the different muted style of notification in
16.4, while `muted: 2` shows a hard-muted notification when the user
choose to manually mute a channel, as to not receive any notification
from it.

Some logic related to "mark as read"/"counter" logic has been moved
to this muted prop concern, as not all notification that have mark
as read or a counter necessarily must be muted, e.g. with "OdooBot
has a request".

Task-3566799

closes odoo/odoo#140380

X-original-commit: c60fdbb25b38899ceeb89e76abc35c3474ce1f5b
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-10-31 14:40:56 +00:00
Alexandre Kühn bef68e577a [FIX] mail: center avatar with composer with a single line
Before this commit, the avatar next to composer in Discuss app
had the top aligned with the top of the text input of composer.
The avatar is smaller than the input, and the text in the input
is centered, so the alignment looks off.

This commit fixes the issue by offseting the avatar so that
when the composer has only 1 line, the avatar is vertically centered
with the input.

Note that this alignment should be fixed, i.e. if the input field has
more than 1 line, we want to keep the avatar in the same place, hence
why the avatar is just statically offset.

Also align composer avatar with message list, by removing the
`align-justify: self` that was moving avatar slightly towards the
discuss app sidebar.

closes odoo/odoo#140398

X-original-commit: 5fe4297f3d1a988ae65617c177046a223bc62890
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-10-30 21:50:48 +00:00
Alexandre Kühn a74691949c [FIX] mail: same discuss badge color as systray in dark theme
Dark-mode colors have been adapted from MILK redesign in 16.3 [1].
Discuss badge colors were changed in 16.4 to match systray color [2].
Commit [1] adapted them to use primary color instead of intended
sytray color. Removing the override of style fixes the issue, as the
base style in `core.scss` (white theme) works in both themes.

[1]: https://github.com/odoo/odoo/pull/130991
[2]: https://github.com/odoo/odoo/pull/122946

closes odoo/odoo#140300

X-original-commit: b46bded27349acd311682846c0a0416ce4898882
Signed-off-by: Didier Debondt (did) <did@odoo.com>
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-10-30 16:41:51 +00:00
Alexandre Kühn 7cf86921b4 [FIX] mail: click on messaging menu item should not rename thread
Before this commit, when opening a thread in the Discuss app and
changing to another active thread from the Messaging Meu in the
systray, the new thread was mistakenly renamed to the previous
active thread name.

This happens because the component `AutoresizeInput`, which is used
to show the thread name in the header of Discuss app, also allows to
rename the thread. The code to trigger rename was too naïve, in that
a click away was considered as a rename operation on the current
thread.

This commit fixes the issue by triggering the editing of the value
in the `AutoresizeInput` component only when the click away happens
while the input had focus. The click in messaging menu will not
trigger it as the input is not focused.

Task-3570377

closes odoo/odoo#140208

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-10-30 16:41:46 +00:00
Alexandre Kühn 05f434c222 [FIX] mail: show original format of email message in white theme
Before this commit, messages of type email had their style initially
altered on the UI to match the theme, notably the background and font
color. To see the original format, a floating button
"Show Original Format" was shown in the top-right corner of these
messages.

The main problem with this button is that most email messages do not
have a different visual between altered and non-altered, so this
button felt useless most of the time. Also, the original style of
email message is a annoyance in dark theme but not in white theme.

This commit removes the presence on the button and the style of
email message is now based on the chosen theme:
- white theme: always show the original style of the email
- dark theme: always show a slightly altered style of the email

This commit also fixes a bug where message of type `email_outgoing`
were not properly considered as email messages. To fix this issue,
`message.type === "email"` has been replaced with
`message.type.includes("email")` to also take these messages into
account.

Task-3573855

closes odoo/odoo#140176

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-10-28 01:18:30 +00:00
Alexandre Kühn b3c231b1b2 [FIX] mail,*: markup chatbot livechat message
calendar, im_livechat

Before this commit, messages in chatbot conversation were not
properly markup. This comes from changes from [1] that added
trusted insert. Original code in `Record.insert()` makes a model
insertion of the data using the `html` flag. Patches must not
override `static insert()` as only the super call is affected by
the provided `html` flag. For patches to take account of it, they
must instead patch `_insert`, with `_` prefix, which is internally
called by original `Record.insert()`.

In addition:
- `static insert` allows array of data while `static _insert` works
  with data on single record. Patches were designed with data on
  single record, so some code were not working properly
- Signature of `static insert` has been overloaded with new option
  `html: true`, so patches must propagate it. They were only
  propagating `data` and omitting the 2nd paramater, which results
  in omitting provided `html` thus falling back to `html: false`,
  resulting to non-escaping message body

This commit fixes all model patches to override `static _insert`
instead of `static insert`.

[1]: https://github.com/odoo/odoo/pull/139501

closes odoo/odoo#140064

Related: odoo/enterprise#49718
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-10-27 16:09:34 +00:00
Alexandre Kühn af3d6bf4a6 [IMP] mail: chat window dropdown show active background
Before this commit, when the command dropdown was open by clicking
on avatar/chat window header name, the clickable area was the same
as the rest of chat window header.

As a result, the dropdown was shown without some UI to help see the
toggler that is responsible from this dropdown.

This commit highlights the toggler of dropdown when it is open, so
that it looks nicer when the dropdown is open as we clearly see the
toggler of this dropdown.

closes odoo/odoo#139920

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-10-27 13:02:18 +00:00
Alexandre Kühn 47be118fb1 [FIX] mail: message reply-to click area should match cursor feedback
Before this commit, when a message is a reply to another message,
the whole row of the message reply-to was clickable to highlight the
reply-to message.

This is ok when the click happens on the actual reply-to message
above the message, but when the content of the reply-to message
is short, the click area extends to more than the "clickable" cursor
show, so that click on thread view hightlights the reply-to message
when it shouldn't.

The `cursor-pointer` style was already correctly shown only the the
actual part of the reply-to message. But the `t-on-click` was more
generous and considered the whole row in the thread view.

This commit fixes the issue by matching the `t-on-click` with the
intentional clickable area, matching the `cursor-pointer` that was
correct.

closes odoo/odoo#139906

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-10-27 11:35:08 +00:00
Alexandre Kühn b88ecba36f [IMP] mail: improve label of button to toggle style of email message
Before this commit, when a message is of type email, the button to
toggle between adjusted content style with webclient theme and the
original email style was labelled "Show Original Email" and
"Don't show original Email".

This label is confusing, as it gives the impression that this button
opens a new screen or removes a UI element. This button only alters
the visual of the message, that is the style, so the label should
be better worded to tell that.

This commit rename the label to "Show Original/Custom Format", so that
it's clearer what this button actually does.

closes odoo/odoo#139901

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-10-27 11:35:06 +00:00
Alexandre Kühn 38d35c1ac6 [REF] mail: have author in notification formatter
So that `Message.insert()` in JS becomes trivial, as it doesn't have
to infer the author of message to current user.

closes odoo/odoo#139501

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-10-26 13:41:16 +00:00
Alexandre Kühn eae6943021 [IMP] mail: RecordList auto-call unimplemented array method
This allows to support many unimplemented array methods, such
as `Array.prototype.findLast()`.

Part-of: odoo/odoo#139501
2023-10-26 13:41:16 +00:00
Alexandre Kühn c9a3b335d8 [REF] mail: remove mail/utils/arrays
This utils file was added because removing item in JS based on
item content sucks, so some higher-order functions were introduced
to ease it slightly.

As many of its uses has been replaced with `RecordList.delete()`
where data is uniquely linked to a model, in the end the functions
were only used once. These functions have been moved to the only file
that still use them, so that we don't encourage using them.

Part-of: odoo/odoo#139501
2023-10-26 13:41:16 +00:00
Alexandre Kühn f97012e0ed [REF] mail: support multi-data insertion in discuss model
Before this commit, when having an array of data to insert
in a model, we had to iterate and insert data item on by one:
```js
messageDataList.forEach(data => this.store.Message.insert(data));
```

With this commit, we can simply insert the array of data to
insert:
```js
this.store.Message.insert(messageDataList);
```

This helps simplifying the business code further, less LOCs is
usually better!

Part-of: odoo/odoo#139501
2023-10-26 13:41:16 +00:00
Alexandre Kühn c0da919697 [REF] mail: discuss model html field and trusted insert
This commit allows to define html fields in discuss models,
so that when insert is trusted they are automatically markup.

By default, all model insert are untrusted. To make a trusted
insertion, we should pass 2nd parameter `{ html: true }` to
an `insert()` method. The param is intentionally named `html`
instead of `trusted`, so that it triggers ci/security for
reviewers awareness.

It's still possible to immediately assign a markup on the html
fields, like before.

This changes simplifies the code, so that we don't have to dissect
model data everytime and make sure all bits are properly markup.
The dissect operation added many LOCs and we frequently missed to
markup the data in some flows. Being able to flag html fields at
model definition and flagging an insert safe keeps the security
concern while helping properly markup-ing all the data.

Part-of: odoo/odoo#139501
2023-10-26 13:41:16 +00:00
Alexandre Kühn 46e3594118 [REF] mail: introduce Record.attr() on discuss JS models
In preparation to simplify mail.record/insert processing
(Message.body markup)

Part-of: odoo/odoo#139501
2023-10-26 13:41:15 +00:00
Alexandre Kühn 954d7a6b4a [FIX] im_livechat: no crash in safari with livechat chatbot
Before this commit, when using a livechat chatbot from visitor
and selecting a chatbot option, there was the following traceback:

```
UncaughtPromiseError > SyntaxError
Uncaught Promise > JSON Parse error: Unterminated string
SyntaxError: JSON Parse error: Unterminated string
parse@[native code]
updateSession
```

This happens because the session cookie had incorrect format for its
content. This was caused by a history prop whose content had the
character "→". When setting the cookie, the stringified object is
only partially inserted until this "→", which made the content
non-JSON parseable as the string is incomplete.

This commit fixes the issue by replacing all occurrences of the
character "→" by a whitespace, so that the setting of the cookie
works and insert the whole stringified object as intended.

Note that this "→" is used for data that is not used in the context
of livechat chatbot for the visitor, therefore this alteration of
the content has functionally no effect.

opw-3527969

closes odoo/odoo#139606

X-original-commit: 64efe60f92679767af769125ce7515ca3fff8c49
Signed-off-by: Matthieu Stockbauer (tsm) <tsm@odoo.com>
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-10-25 03:59:10 +00:00
Alexandre Kühn 09592c25fd [REF] mail: replace Partner/Guest to Persona in mail.record/insert
As a step to simplify model insert from python. All data are
formatted in a way to make data insert trivial in JS models.

closes odoo/odoo#138760

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-10-23 20:07:29 +00:00
Alexandre Kühn 39e56939fd [REF] mail: simplify naming in internal of mail records
- `__invs__`/`RecordInverses` have been renamed to
  `__uses__`/`RecordUses`, so that it's more clearly separated
  from inverse fields. While they are some overlap in concepts,
  they require different datastructures so it's best to keep
  different implementations for the time being.
- `list.__addInverse__(r)`/`list.__deleteInverse__(r)` have been
  replaced to `r.__uses__.add(list)`/`r.__uses__.delete(list)`.
  Again change of wording "inverse" to "uses" like before, but
  also it feels more natural for uses as low-level concept to
  expose function on object where the uses are tracked, i.e. on
  the record, rather than functions in RecordList like before.
- Remove useless `__` prefix/suffix and/or only keep `_` prefix
  for `store` and `__addNoInv`/`__deleteNoInv`, for improved
  code readability
- Renamed `__list__` and `__map__` datastructures to `data`,
  again for improved code readability.
- Replaced some `Map<>` to `Object<>`, so that accessors are
  easier to read in code with `[]` rather than `.set()`/`.get()`,
  especially with code formatter that produces more LOCs than
  necessary with the latter. Note that the affected dict,
  `__computes__` and `__rels__` are set up at model and record
  setup, so they do not change shape after that, so using Object
  should not be a performance issue.

Part-of: odoo/odoo#138760
2023-10-23 20:07:29 +00:00
Alexandre Kühn 3cb14377c7 [REF] mail:tests: more discuss model tests
This helps spot a few bugs in the code.

Part-of: odoo/odoo#138760
2023-10-23 20:07:29 +00:00
Alexandre Kühn 4d63a477bb [REF] mail: Remove deadcode about Record.__atomic__
Part-of: odoo/odoo#138760
2023-10-23 20:07:29 +00:00
Alexandre Kühn 416e05b210 [REF] mail:tests: add/delete on record fields with inverse
Some test coverage on model with inverses, especially on deletion
that are not frequently functionally covered by tests.

To make test coverage on very specific on models and relational
fields with inverses, store service has been refactored so we can
test the store without Persona/Thread/Message models and all related
services and behaviours.

Part-of: odoo/odoo#138760
2023-10-23 20:07:29 +00:00
Alexandre Kühn 9a127407c7 [REF] mail: rename model NotificationGroup to Failure
Name was hard to grasp what it means, when in practice it refers to
showing discuss failures in messaging menu. The "group" part just
refers to a failure being conceptually uniquely defined so that it
sometimes group notifications together as a single failure entry
in the messaging menu.

This rename will help simplifying insert flow with this model.

[REF] mail: slightly simplify Notification.insert()

Format `persona` so it can be immediately inserted in JS model.

[REF] mail: simply Notification/Failure.insert

[REF] mail: introduce computed fields on discuss models

Some models have no concept in server, so the formatted data require
specific handling to make some client-side specific models. This is
notably the case with `Failure` model, which is used to group
failure notifications per model for the specific showing in UI.

In order to simplify update so they consists to simply adding data
from server, these models should be inserted automatically depending
on changes from inserted data. Since these models come from
relational fields that must be computed outside of server data, we
add support to computed fields: such relational fields can have their
value automatically computed based on the state of the current
record.

[REF] mail: remove Record.atomically and Record.onChange

These were added to reactive seeing intermediate state in models,
which were caused by `RecordList.sort()`.

This commit removes them and adapt specifically `RecordList.sort()`
so intermediate states during sort is not exposed in the actual
value of the many field.

Part-of: odoo/odoo#138760
2023-10-23 20:07:29 +00:00
Alexandre Kühn a479a0bba6 [FIX] hr, mail: no crash on empty member.persona
Steps to reproduce:
- install `hr_homeworking`
- connect as Mitchell Admin
- make a private chat with Marc Demo
- `@mention` Marc Demo
=> crash (cannot read name of undefined (reading persona))

This happens because a spread record was inserted in model,
and in this scenario the record list in data can be the exact same
as the record list used in the model. The internal code of assigning
a many list is to `clear()` and then `push()` from data, but if the
data mutates from the `clear()`, then the `push()` does nothing and
the resulting relation is emptied.

This commit fixes the issue by keeping a copy of collection before
`clear()` so that push applies on original data that is intended by
insert.

This commit also adapt code in hr to not use spread record to insert
Persona. While it works with the fix, it's simpler to just update the
appropriate field and also more efficient, because spread a record
has to process all fields as an insert, wasting CPU time.

closes odoo/odoo#139143

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-10-19 17:01:15 +00:00
Alexandre Kühn 86c713117b [FIX] mail: do not save command 'ADD.noinv' during rel insert
Before this commit, some relational fields in records had
the command `[["ADD.noinv"]]` as value. This is a command and
it should have been feed by a model (pre)insert, but the
resulting value of the field should never be a command: it's
always a RecordList (one-size RecordList when a Record.one).

This happens because the RecordList tracks the owner, i.e. the
record that owns the RecordList value in the relation, but the
owner was not properly proxified.

Indeed, all models are wrapped in a proxy, so that they managed
delete/get/assign on relational fields. To feed command like
"ADD.noinv". the receiver MUST be the proxy in order to be feed
properly, otherwise the assignment with command sets the command
as the actual value on the field. This is precisely what happens.

This commit fixes the issue by properly passing the proxified owner
to the RecordList, so that `ADD.noinv` command works as expected.

---------------

This changes unveiled some mishandling of the inverse, notably
during deletion of the record: the deletion must not insert record
with `ADD.noinv`, otherwise the inverse record is added, and this
is prone to infinite loops. To properly managed deletion, a new
internal command `DELETE.noinv` is used to delete the record without
syncing the inverse field, again to prevent infinite loops like with
`ADD.noinv`.

Part-of: odoo/odoo#139143
2023-10-19 17:01:15 +00:00
Alexandre Kühn 743d8cd8c1 [FIX] hr: 'Open Profile' should open public employee form
Before this commit, when an internal user attempted to open
profile of a user from dropdown menu of private chat window
with that user, there was crash.

Steps to reproduce:
- install `test_l10n_be_hr_payroll_account` with demo data
- connect as Laurie Poiret
- Open chat window with Marc Demo
- Click chat window header => "Open Profile"

It happens because the action to open the profile was attempting
to open "hr.employee" form, which require specific access rights
(hr manager). The current user is not necessarily an hr manager,
so the action fails.

This commit fixes the issue by opening the public form view of the
employee, which is accessible to all internal users.

opw-3555889

closes odoo/odoo#139134

X-original-commit: bdce8c72cd06cb783973beb62382bfd8a8ae249e
Signed-off-by: Matthieu Stockbauer (tsm) <tsm@odoo.com>
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-10-19 04:31:55 +00:00
Alexandre Kühn 882fc6d147 [REV] website_livechat: fix tour failing nondeterministically
This reverts https://github.com/odoo/odoo/pull/138582 as it was
preventing merging anything on runbot. Another fix is planned for
this tour at a later date.

closes odoo/odoo#138980

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-10-17 21:19:06 +00:00
Alexandre Kühn 631ae1c4d8 [REF] mail: simplify JS discuss models further
- Remove "channel" field in thread formatter.
- Pass `type` for all persona formatters.
- Remove some snake_case to camelCase conversions.
- Add support for inverse fields in discuss JS models.

Details:

1. [REF] mail: remove field 'channel' in thread formatter

This field was used for channel-specific fields, which made
sense when there was a dedicated Channel model that was modeled
with composition with Thread.

To simplify formatter of threads, it's best to flatten props
so that channel-specific fields are immediately available on
thread model. This will improve insertion of data with Threads.

This commit also makes the following other changes:

- remove `discuss.channel/legacy_insert` to use
   `mail.record/insert` instead.

- Introduce `toData()` on record, which is helpful to have record
  in data format e.g. to pass as a JSON.stringifiable object.

2. [REF] mail: slightly simplify Message.insert from notif

The handling of `mail.record/insert` for Message was handling
transition from starred non-empty message to starred empty message.

To simplify all record insert from server formatted data, the notif
data is just inserted in Message. The adjustment of starred counter
is managed at model level.

This is a prerequisite to significantly simplify all
`mail.record/insert` handling.

3. [REF] mail: rename 'res.users.settings' notifications

Before this commit, notifications related to changes of user
settings were using named notification `mail.record/insert`.

This named notification should be only used for Discuss data that
should be inserted in models. `res.users.settings` is not integrated
in Discuss model, thus it has no reason to use this named
notification.

This commit rename the notification name to `res.users.settings` for
these specific notifications. This prepares simplification on
handling any `mail.record/insert` notifications that should simply
call `Record.insert()`

4. [REF] mail: make dedicate notif for Thread/fold_state

This was using named notif "mail.record/insert", which should
be used to immediately insert data in models. This is however
a dedicated notification to imperatively manager chat window
state based on timing of receiving thread data.

This may eventually become a `mail.record/insert` in the future,
but right now it's much simpler to define it as its own named
notification, in preparation to simplify `mail.record/insert`
notifications handling.

5. [REF] mail: remove Channel in mail.record/insert

This is replaced by `Thread`, so that these data can be
immediately inserted in Thread model.

6. [REF] mail: simplify slightly Attachment.update()

Now that data containing commands is supported, we could
just assign with the command rather than destructure and pick
the dict data part.

7. [REF] mail: introduce assignIn() utils

This function helps reduce LOCs from using the "in" conditional
in sequence:
```js
if (a in data) {
	this[a] = data[a];
}
if (b in data) {
	this[b] = data[b];
}
if (c in data) {
	this[c] = data[c];
}
```

To simply:
```js
assignIn(this, data, [a, b, c]);
```

8. [REF] mail: remove snake_case to camelCase conversion in models

They exist for the sake of keeping Python code snake_case and
JS camelCase. While it's good that each language have a community
that prefer syntax convention, when a codebase uses both languages
and they should work with the same data, it's not great to convert
snake_case to camelCase and vice-versa all the time.

Since server has authority over the data, the server chooses the
format for the keys. Most of them are snake_cased, therefore this
is usually the one we pick.

9. [REF] mail: rename Message.messageReactionGroups to Message.reactions

Easier to read, and matches relation name in JS model

10. [REF] mail: remove explicit assign of some many relations in Message

This reduce amount of custom code in insert(), in preparation to make
all models behave the same in response to inserting data.

11. [REF] mail: rename Thread.customName to Thread.channel_custom_name

To match server data field name, and avoid useless conversion in JS.

12. [REF] mail: simplify Message.insert for recipients

Have formatted data contain `type: "partner"` so it can be assigned
in relational field without adding `type: "partner"` manually in JS.

13. [REF] mail: introduce inverse field in discuss models

With this commit, fields in different models can be linked
together, so that one is mirror of the other field.

This simplifies some `onAdd`/`onDelete` that were added to
sync such fields, and this also simplifies insertion in
relational fields for discuss models that are identified
by records, such as the `MessageReactions` that is identified
by the message and the emoji.

14. [REF] mail: rename CannedResponse.name to 'source'

To make JS model and server data more alike.

15. [REF] mail: remove assignDefined in Persona model

So that eventually all model inserts use `Object.assign()`.

16. [REF] mail: remove 'last_message_id' from channel_info

At some point it was used to display last message in messaging menu.
This is already covered by `channel_fetch_preview` when opening the
messaging menu for the 1st time, so passing `last_message_id` in
channel_info is obsolete.

closes odoo/odoo#137750

Related: odoo/enterprise#48484
Signed-off-by: Matthieu Stockbauer (tsm) <tsm@odoo.com>
2023-10-13 11:46:13 +00:00
Alexandre Kühn b42bcb25b2 [FIX] mail: style mention without @extend
Follow-up of https://github.com/odoo/odoo/pull/132701

`@extend` was used to reuse classnames intended for styling,
such as `.btn`. However, this has the side-effect to increase
specificity on these classnames, which results in breaking style
on the website where the specificity on `.btn` must not change.

This commit fixes the issue by using a mixin rather than
`@extend`. Since using these mixins are not equivalent, we took
the opportunity to slightly improve the constrast of text color
and background.

closes odoo/odoo#138108

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-10-10 12:35:05 +00:00
Alexandre Kühn 6ffea84866 [FIX] mail: make call invitation work from recent discuss model REF
Discuss model data that had commands have been simplified by [1].
Notably some `unlink` were replaced by `False` and or `DELETE`.

Some code in Discuss calls was still expecting receiving command data
in of `DELETE` while data received has become `false`. As a result,
the state of ringing threads and showing call invitation card was not
working.

This commit fixes the issue by relying on recent improvements that
commands can be passed immediately as data to relational fields [2].

Code in Discuss call still have some coupling between fields whenever
some records are either added to or removed from a field. Hooks
`onAdd` and `onDelete` on relational fields are added to support
these cases.

[1]: https://github.com/odoo/odoo/pull/136308
[2]: https://github.com/odoo/odoo/pull/137341

closes odoo/odoo#137540

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-10-04 20:52:41 +00:00
Alexandre Kühn b1edee9a84 [REF] mail: simplify discuss model insert code
1. simplify message reaction formatter (personas)

Data was formatted to have "partners" and "guests" entries, both
of which contribute to personas.

To avoid some post-processing of data in JS, it's best to format
data to immediately include type of persona.

2. include "guestAuthor" in "author" data of message

Discuss models in JS group partners and guests into a single model
Persona, to make feature works regardless on whether user is
authenticated or not.

This commit simplifies code by removing data guestAuthor in message
formatted data, and instead author contains author data in all cases,
whether the author is a partner or guest.

3. simplify insert (remove id, redundant with preinsert)

Also rename Follower.isActive to Follower.is_active, for
even simpler Follower.insert()

closes odoo/odoo#137276

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-10-04 19:40:19 +00:00
Alexandre Kühn e4b7217fc3 [FIX] mail: remove message reaction was not working
Follow-up PR of https://github.com/odoo/odoo/pull/136308

Commit above simplified code in discuss models so code applies
on records than properties on records. For example, instead of
juggling between persona local id and persona, some code can simply
keep logic on persona without leaking local id.

However the improvements are iterative, and more improvements are
needed to stop using local id. Some code still need local ids.
Commit above mistakenly converts a local id to persona on some code
that still work in terms of local id. As a result, message reactions
were not working properly, notably when adding a new reaction using
click on an existing message reaction of someone else.

There was also a bug in implementation in mock server which made the
test not working. This commit fixes this issue too.

Task-3523101

closes odoo/odoo#136940

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-10-03 22:11:52 +00:00
Alexandre Kühn 9a70545913 [REF] mail: support passing commands as data of relational field
This significantly eases processing command data on relational field
received from server.

closes odoo/odoo#137341

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-10-03 20:17:47 +00:00
Alexandre Kühn 3b251d6d66 [REF] mail: turn Composer.rawMentions into relational fields
This field contained 2 sets with partner and channel ids.
It's easier and safer to reason in terms of records rather
than properties on records.

Part-of: odoo/odoo#137341
2023-10-03 20:17:47 +00:00
Alexandre Kühn b526078ae9 [REF] mail: set data immediately on discuss model relational field
With this commit, instead of `Record.insert()` before setting
relation with records, we can immediately pass record data.
For example:
```js
message.author = { id: 3, type: "partner", name: "Admin" };
thread.messages.add({ id: 10, body: "some-text-content" })
```

This is supported on all relational fields that define a target
model.

To make this work while drastically avoiding cyclic dependencies
in code, whenever data have to be inserted in relation, they are
pre-inserted with essential data, and then they are fully inserted
after being registered in the relation.

closes odoo/odoo#136539

Related: odoo/enterprise#47854
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-10-02 11:42:55 +00:00
Alexandre Kühn 485bcb82bf [REF] mail: make store service a model
This simplifies managing relations on the store, and gives
incentive to define them there instead of another prop that
is a record, e.g. `discuss`.

Part-of: odoo/odoo#136539
2023-10-02 11:42:55 +00:00
Alexandre Kühn 98491e3b43 [REF] mail: store all discuss models in Record.records as object
In preparation to improve insert in relational field with data, so
that there's less risk for cyclic code execution (hint: there'll be
a preinsert).

closes odoo/odoo#136308

Related: odoo/enterprise#47777
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-09-27 13:11:58 +00:00
Alexandre Kühn bef4069195 [IMP] mail: introduce RecordList.add() in discuss model relations
This method pushes the provided record if it's not in the record
list, otherwise it does nothing. This works a bit like `add()` on
Sets.

Part-of: odoo/odoo#136308
2023-09-27 13:11:58 +00:00
Alexandre Kühn 22ed4ec268 [REF] mail: rename commands in discuss model data
Relational data in server formatter are:
- for one relation: None/false or object
- for many relations: list of objects or list of commands

The commands were:
- 'insert': to add a new item in a relational field
- 'unlink': to remove an item from a relational field
- 'insert-and-unlink': to remove an item from a relational field
- 'clear': to remove all items from relational field

There was a slight nuance between 'unlink' and 'insert-and-unlink'
at some point, but it becomes irrelevant with current code of model.
The name of the commands were hard to grasp what they actually mean
for the many relations.

This commit improves it by renaming 'insert' by 'ADD' and the 2
'unlink' commands by 'DELETE'. This makes it more apparent that
the data in 'ADD' refers to data of record to add in the relation,
while 'DELETE' refers to data of record to delete from the relation.
The 'clear' has been replaced by `False` value instead of a command.

Part-of: odoo/odoo#136308
2023-09-27 13:11:58 +00:00
Alexandre Kühn 8d78065886 [REF] mail: turn Thread.transientMessages into relational field
Part-of: odoo/odoo#136308
2023-09-27 13:11:58 +00:00
Alexandre Kühn 87f605aa90 [REF] mail: turn 'store.ringingThreads' into relational field
Part-of: odoo/odoo#136308
2023-09-27 13:11:58 +00:00
Alexandre Kühn 08c751a9e3 [REF] mail: turn Thread.rtcSessions into relational field
Part-of: odoo/odoo#136308
2023-09-27 13:11:58 +00:00
Alexandre Kühn 1af1b3e96a [REF] mail: remove unnecessary getters in thread
Also turn `invitedMembers` into relational field

Part-of: odoo/odoo#136308
2023-09-27 13:11:58 +00:00
Alexandre Kühn d97ffb0dde [REF] mail, *: turn store.discuss into a model
This allows to define categories as also models, which allow
to register list of threads as relational fields, which in turn
simplify code readability and maintainability of these relational
data.

Part-of: odoo/odoo#136308
2023-09-27 13:11:58 +00:00
Alexandre Kühn 603cd70ecc [REF] mail: move service.update() to discuss models
These `update()` functions are specific to a discuss record,
so it's best to be defined in the model rather than another
service.

Part-of: odoo/odoo#136308
2023-09-27 13:11:58 +00:00
Alexandre Kühn 20710a6850 [IMP] mail: group List() and Set() into single many relation
`RecordSet` relations were rare and not worth having them. Turning
them into `RecordList` has no drawbacks.

To simplify many relations to a single relational field,
`Record.List()` was renamed to `Record.many()`, and `Record.Set()`
has been removed.

closes odoo/odoo#134884

Related: odoo/enterprise#47745
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-09-21 23:54:21 +00:00
Alexandre Kühn 18078c546e [IMP] mail: properly type discuss models
- Split d.ts files in `@types` folders that are close to
  where the definitions of model & patches.
- Update jsdocs of discuss models to be fully type, including
  model patches

When defining a new discuss model or a patch, should define a
`@types/models.d.ts` file. It must make use of module `models`
to define interface with model name:

```ts
declare module "models" {
    import { Thread as ThreadClass } from "./thread_model";

    export interface Thread extends ThreadClass {}

    // necessary to propagate types to relations
    export Models {
        "Thread": Thread,
    }
}
```

When defining a patch, should also define a `@types/models.d.ts`
to augment the interface of the model at hand:

```js
patch(Thread.prototype, {
    setup() {
        this.pinnedMessages = Record.Set("Messages");
    }
});
```
```ts
declare module "models" {
    import { Message } from "models";

    export interface Thread {
        pinnedMessages: Set<Messages>,
    }
}
```

Part-of: odoo/odoo#134884
2023-09-21 23:54:21 +00:00
Alexandre Kühn b71e1fd22d [IMP] mail: add relational fields on patch of discuss model
With the introduction of relational fields on discuss models,
which makes it easier to manage relations between discuss records,
we are incentivized to define all discuss relations in the models.

Some services managed relations with their own datastructure.
For example, pin_message service uses some Maps and Sets to model
messages pinned on channels. This is cumbersome to manage deletion
of records by hand... And also the name of attributes in the service
are too long, which shows they are not placed in the right context
(= in a dedicated service rather than in models).

This commit turn these relational data in pin_message service into
new relational fields on Thread and Message models.

```js
patch(Thread.prototype, {
    setup() {
        this.pinnedMessages = Thread.Set("Messages");
    },
});
```

For type inference of the discuss model patches, we rely on module
augmentation of TypeScript with interfaces: we define an interface
for the patch of a given model, and we combine the type of this
"patch" interface with the original Model type in the listing of
Models types:

```ts
declare module "models" {

	import { Persona } from "./persona";
	import { Thread } from "./thread";

    export interface Models {
    	"Message": Message,
        "Thread": Thread & Partial<Thread_Patch>,
    }

    export interface Thread_Patch {
        pinnedMessages: RecordSet<Models["Message"]>
    }
}
```

That way, whenever we use a record e.g. from a one relational field,
we have proper typing for the patches:

```js
class Message {
	originThread = Record.one("Thread");
}

message.originThread; // Thread & Partial<Thread_Patch>
message.originThread.pinnedMessages; // RecordList<Messages>
```

So whenever you adapt a discuss model patch or add a new one, make
sure to register new props in an interface of "models". Other devs
will be grateful towards you!

------

Note that the previous implementation of Relational fields on discuss
models was not robust enough with patching, notably with the
implementation details of `@web/patch()` function. Instead of using
`Object.defineProperty` on the model class prototype of each
relational field, we now use a proxy. This prevents the proxy hook
to be shadowed by the patches. This also allows to support a new way
to delete `Record.one()` relations with the `delete` keyword.

Part-of: odoo/odoo#134884
2023-09-21 23:54:21 +00:00
Alexandre Kühn 4023d523cc [IMP] mail: introduce many relations on discuss models
Introduce many relation by means of `Record.List()` and
`Record.Set()`. `Record.List` makes a data-structure similar
to JS Arrays, whereas `Record.Set` makes a data-structure similar
to JS Sets. Instead of storing objects, they store local ids
of records.

Note that some methods that return a collection return a native
collection, not a record collection. For example,
`RecordList.filter()` returns an array, not a `RecordList`.
This allow limiting using these special collections only when
handling relations, not collections in general.

Also note that the `Record.List` and `Record.Set` both accept either
native collection or record collection as setter argument.

```js
class Thread extends Record {
	messages = Record.List("Messages");
	followers = Record.Set("Follower");
}
// ...
thread.messages = messages;
thread.messages.push(message);
thread.messages.filter((msg) => !msg.isEmpty);
thread.followers.add(follower);
```

These relations allow to normalize discuss store further, improve
code readability with simpler field names, and also prepare for
future improvements on models such as simpler python formatters,
simpler Record.insert flows, relational fields that automatically
reflect on record deletion, etc.

Part-of: odoo/odoo#134884
2023-09-21 23:54:21 +00:00
Alexandre Kühn 355b586970 [REF] mail: introduce Record.one() relational field on model.
This allow storing only the local id internally, and there are
automatic `get`/`set` to get the related record. This prepares
support of record deletion that would automatically delete
all relational fields, in a follow-up PR.

```js
class Message {
    author = one("Persona");
}
```

Relational fields can be used to uniquely identify records:

```js
class ChatWindow {
    static id = "thread";
    thread = one("Thread");
}
```

Part-of: odoo/odoo#134884
2023-09-21 23:54:21 +00:00
Alexandre Kühn c191f94b43 [IMP] website: enable livechat button in website preview
The livechat button was disabled in website preview because
its implementation could not properly handle being in an iframe
inside the backend [1].

With the public livechat code being refactored to use discuss code,
this is no longer a problem, so the livechat button can be present
again. This also makes previewing the website more correct: the
livechat button is actual present on the website, so hiding it was
a lie.

By re-enabling the livechat button, this also allow to remove the
test coverage by a tour, which was sometimes failing on runbot due
to tour being small and doing `im_livechat/init` rpc after the end
of the tour.

[1]: https://github.com/odoo/odoo/commit/e86c1ce94a148745d58ac38e408e1bc947978670

runbot-24631

closes odoo/odoo#135913

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-09-20 18:19:50 +00:00
Alexandre Kühn 7d5442eef1 [FIX] website_livechat:tests: fix chatbot ui tour nightly build fail
Follow-up of https://github.com/odoo/odoo/pull/135378

Commit above fixed a potential issue where guests may eventually have
many livechats, so finding the livechat thread just by
`type: livechat` is not enough. To be more specific, it relies on
livechat session stored in cookie.

However, when there's no livechat session, there's no id stored in
cookie. The livechat thread uses a `TEMPORARY_ID`. Fix above forgot
to handle this part, thus the getter was failing when there's no
persistent livechat session.

closes odoo/odoo#135442

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-09-14 11:22:58 +00:00
Alexandre Kühn 4e79a9ec0b [FIX] mail: do not autoscroll attachment box when initially open
Before this commit, when a form view choose to open attachment box
initially and chatter is at bottom, opening the form view was
scrolling down to the attachment box.

The auto-scroll to opened attachment box is desirable when the
user explicitly interact with the attachment button, to show
the attachments. However, it should not be triggered when opening
the form.

This commit fixes the issue by limiting auto-scroll to attachment
box only when explicitly chosen by the user.

closes odoo/odoo#135234

X-original-commit: 7415e24a918ab06d2902bb68932878619d623019
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-09-13 04:37:07 +00:00
Alexandre Kühn d064d3728d [FIX] mail: do not autoscroll attachment box when initially open
Before this commit, when a form view choose to open attachment box
initially and chatter is at bottom, opening the form view was
scrolling down to the attachment box.

The auto-scroll to opened attachment box is desirable when the
user explicitly interact with the attachment button, to show
the attachments. However, it should not be triggered when opening
the form.

This commit fixes the issue by limiting auto-scroll to attachment
box only when explicitly chosen by the user.

closes odoo/odoo#135205

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-09-13 04:37:02 +00:00
Alexandre Kühn f3614a4b5b [FIX] mail: smaller thumbnails in attachment list
Before this commit, when showing list of attachments in a message
or attachment box, the images were too big. This made it hard to
see other content due to the big size of the images.

This commit fixes the issue by reducing the size of image previews
when in context of many attachments. When a message has a single
image, it keeps showing a big preview of this image.

Also slightly reduce size of images in attachment box, as they were
also too big.

closes odoo/odoo#134941

X-original-commit: cf2069e0f7cd36c4d2b3bcc79fdde7e0425e2e52
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-09-11 11:53:53 +00:00
Alexandre Kühn 640a11a56e [FIX] mail: jump to pinned message from notification
Before this commit, when pinning an old message from thread,
then page reload then click on pinned message link in
notification message in thread at time of pinning message,
it fails to jump to the pinned message.

This happens because the message is not in the store, therefore
it attempts to jump to message `undefined`, which doesn't exist.

This commit fixes the issue by inserting the message before
attempting the highlighting that will jump to the message.

closes odoo/odoo#134818

X-original-commit: 70769963d240add98ed2ee231412201434a825ba
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-09-08 13:45:41 +00:00
Alexandre Kühn 27919caad7 [FIX] mail: auto-close attachment box when no attachments
Before this commit, when opening a record with some attachments
and attachment box is open, switching to a record without any
attachment shows the attachment box open.

This is a problem because the attachment box is designed to only
be open when there are some attachments. The toggler for showing
attachment box is instead an "upload file" button when the record
has no attachment. This means that the open attachment box in those
records without any attachment cannot be toggled off.

This commit fixes the issue by automatically closing attachment box
when the record has no attachments.

Task-3493374

closes odoo/odoo#134771

X-original-commit: ab678ea7618ca1aee5a6ab31b2de59c87fcce32c
Signed-off-by: Matthieu Stockbauer (tsm) <tsm@odoo.com>
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-09-08 09:47:09 +00:00
Alexandre Kühn d139240161 [FIX] mail: search in emoji picker should scroll top
Before this commit, when opening emoji picker and scrolling down
then making search, the scroll position was not reset to top.

This gave the impression that the search was incorrect, because
the most likely desired emoji is at the very top but was not visible
when searching in this condition.

This commit fixes the issue by enforcing scrolling top in emoji
picker content when the search term is updated.

Task-3493611

closes odoo/odoo#134675

X-original-commit: 7999ae51c51e24eea15edb8f08b2e35db4a774ad
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-09-08 08:29:59 +00:00
Alexandre Kühn c5ece6ccc1 [FIX] mail: discuss sidebar quick search case-insensitive
Before this commit, quick search in discuss sidebar (shown when
more than 20 conversations) was case-sensitive. For example,
when a channel was named "R&D" and user types "r", the channel
was not found.

This commit fixes the issue by making search case-insensitive.

Task-3485254
opw-3445747

closes odoo/odoo#134603

X-original-commit: 02e5af467b6058ea0933255c8f0c4e8dab17f31d
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-09-07 11:46:12 +00:00
Alexandre Kühn 90679836ff [FIX] mail: properly show name of discuss channel
Follow-up of https://github.com/odoo/odoo/pull/130821

`name_get` has been deprecated for `display_name`. In old `name_get`,
when the record had no display_name (`convert(rec._rec_name)` returns
`False`) then the fallback was empty string `""`. This has been
changed with default `_compute_display_name`, to instead show
`<rec._name>,<rec.id>`.

Discuss channel `display_name` was relying on this "" fallback
somehow: even though `rec._rec_name == ""`, `convert("") == False`,
thus fallback "" cancels out to "". The value "" for name is
intentional and necessary in discuss channels for the good working
of some other fallbacks UI, e.g. group chat concats member names.
With the recent changes of `_compute_display_name` default fallback,
it showed `discuss.channel,10` instead of "".

Steps to reproduce:
- Log in as Mitchell Admin
- Open Discuss app
- Click "Start a meeting"
=> expected: shows group chat name "Mitchell Admin"
=> result: shows group chat name "discuss.channel,10"

This commit fixes the issue by removing reliance on `display_name`
for discuss channels: it always uses `name`, thus showing taking into
account `""` as it needs for fallbacks like in group chat when it
has no name.

Task-3493629

closes odoo/odoo#134531

X-original-commit: 5592fc107790c910910c2719ede04a86910dc79f
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-09-06 14:42:21 +00:00
Alexandre Kühn eb673674b6 [FIX] im_livechat:tests: less TestImLivechatSupportPage crashes
Before this commit, sometimes this test crash with the following log
on runbot:

```
Trying to set result to failed (None) but found the future settled (<Future at 0x7fdd859df910 state=finished returned bool>)
```

This problem usually happens when some RPCs are triggered after the
end of the test. This test on livechat support page is small and just
checks that there are no issues in loading JS modules. We do not care
on RPCs triggered from auto-opening of livechat that may result to
this error on runbot.

This commit disables console logging after the test, so that it won't
fail if it passes the check on loading JS files.

closes odoo/odoo#134234

Related: odoo/enterprise#46849
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-09-06 11:50:55 +00:00
Alexandre Kühn 78fcad9176 [FIX] mail: properly type static methods of discuss models
Before this commit, static methods on discuss models like `.get()`
or `.new()` where not properly documented.

The superclass `Record` documents `@returns`, but jsdoc failed to
deduce these static methods return subclass instances. We tried to
find a way to define things once in `Record` and let typedoc deduce
things automatically without overriding in each models just for the
sake of type. However typedoc still sucks in 2023 despite requests
for improvements to support this specific case since 2016, 7 years
ago.

This commit fixes the issue by overriding static method in all discuss
models so that the `@returns` is properly documented.

closes odoo/odoo#134316

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-09-06 05:53:46 +00:00
Alexandre Kühn 43882882eb [REF] mail: simplify record deletion in discuss store
Deletion of record requires removing the record entry
in `records`, and it was cumbersome to make a long expression
each time we want to remove the record from this object.
```js
// before
delete this.store.Model.records[record.localId];
// after
record.delete();
```

closes odoo/odoo#134008

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-09-04 10:56:08 +00:00
Alexandre Kühn d94f7e534a [REF] mail: simplify code of Record.insert() when new record
- automatically add `_store` on the record
- automatically register in `records` and return reactive when
  `records` is a obj (array => should keep doing it manually)

Part-of: odoo/odoo#134008
2023-09-04 10:56:08 +00:00
Alexandre Kühn a775b239ed [REF] mail: introduce id & get() on all discuss models
1. Introduce `static id` to all models, to uniquely identify
   a record in a model. This allows normalizing discuss store
   for all models, which helps as preparation for managing
   record deletion. Can also be combined

```js
class Message {
    static id = "id";
    id;
}
class Thread {
    static id = AND("model", "id");
}
```

2. Introduce `Model.get()` to easily get a record of model
   from data that can identify the record. This prevent leaking
   the way the record are stored in `records`, as now all records
   are indexed by localId, and localId is technical detail.

```js
Message.get(messageId);
Thread.get({ model: "discuss.channel", id: 1 });
```

Part-of: odoo/odoo#134008
2023-09-04 10:56:08 +00:00
Alexandre Kühn 6bb13754ac [REF] mail: simplify discuss model register
This was bothersome to export/import the registry and manually add
the model, by providing the model name and the model class.

```js
// before
modelRegistry.add(Model.name, Model);
// after
Model.register();
```

closes odoo/odoo#133658

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-08-31 17:27:50 +00:00
Alexandre Kühn 02ca218e3c [REF] mail: remove code in model constructor
In preparation to improvements in models.
Some implementation techniques will want to `new Model()`
without any side-effects.

Part-of: odoo/odoo#133658
2023-08-31 17:27:50 +00:00
Alexandre Kühn a770d7aa33 [REF] mail: add missing 'Model.insert()' in store
That way all models are in store with a relatively similar shape.
Any improvements on models will apply to all of them.

Part-of: odoo/odoo#133658
2023-08-31 17:27:50 +00:00
Alexandre Kühn 13b852d2e2 [REF] mail: move imp of service.insert() to Model.insert()
In preparation to clean code of models, e.g. by simplifying model
insertion and reducing side-effects in record insertion.

This commit moves the implementation of the `insert()` in discuss
services to the models, and drop support of the service methods
`insert()`. The only way to insert a model is through the store
entry, e.g. `store.Thread.insert()`.

closes odoo/odoo#133509

Related: odoo/enterprise#46499
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-08-30 23:45:41 +00:00
Alexandre Kühn 78c2dba93f [FIX] mail: show full company logo in avatar of message
Before this commit, avatar url of author of message always had
style `.o_object_fit_cover`, which makes a nice crop when
ratio of image does not match ratio of the `img`.

When the author of message is a company, it shows the logo of the
company, and it doesn't look nice to crop it.

This commit fixes the issue by using `.o_object_fit_contain` for
avatar of company, so that the logo is fully visible.
When displaying the avatar of a partner whose `is_company` is
undefined, the data is group-fetched, in order for models to
eventually know the value of `is_company` and use the correct
desirable showing.

Task-3381748

closes odoo/odoo#133311

X-original-commit: 48194366f2364e2eb9d99dc4fb71e2de83d8f7a2
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-08-29 12:36:01 +00:00
Alexandre Kühn 1c7a4449c1 [REF] mail: remove custom useService() hooks in discuss
They existed solely for typedoc and wrapping `useState()`.
- Typedoc is managed by `useService()` and `services.d.ts`.
- `useState()` is a minimal code in component, and is actually
  more useful as explicitly visible in component.

closes odoo/odoo#133202

Related: odoo/enterprise#46327
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-08-28 20:14:40 +00:00
Alexandre Kühn 8c983c17f5 [REF] mail: remove unused discuss services in services/components
Part-of: odoo/odoo#133202
2023-08-28 20:14:40 +00:00
Alexandre Kühn 5c2093f2a2 [REF] mail: redirect model insert in store
Part-of: odoo/odoo#133202
2023-08-28 20:14:40 +00:00
Alexandre Kühn 5a91d3e5c8 [REF] mail: change shape of store model records
In preparation of code cleaning of models in store.
Entries in store are allocated per model, using the model name.
Records of a model can be accessed from `store[ModelName].records`.

Part-of: odoo/odoo#133202
2023-08-28 20:14:40 +00:00
Alexandre Kühn 15d6f2f9b4 [FIX] mail: can use full composer in reply-to from mailbox
Before this commit, when replying to a message from mailbox
in the Discuss app (e.g. Inbox or History) and then clicking
on the "Full Composer" button, there was the following crash:

```
Invalid res_ids ['history'] (type <class 'str'>)
```

This happens because the full composer button was attempting to open
the full composer on the mailbox at hand, e.g. 'history', instead of
the document related to the message, i.e. the origin thread of the
message.

The code of this button assumes that it's only visible when viewing
the message in the origin thread. In this case, the shown thread
(`props.composer.thread`) matches the origin thread (`thread`) of
message. This is always the case except in mailboxes, so using
`props.composer.thread` is erroneous in mailboxes.

This commit fixes the issue by correctly opening the full composer of
the document related to the message, by using `thread` instead of
`props.composer.thread`, which is the origin thread of the message.

Also make full composer button rounded (`mx-1` => `m-1`)

opw-3453680

closes odoo/odoo#132910

X-original-commit: 69d1776513a5eff06fca84bc070c4678b84829ed
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-08-28 11:24:37 +00:00
Alexandre Kühn 0c3e66340d [FIX] mail: properly compare discuss models with toRaw
Before this commit, discuss models were compared with object
reference, e.g. `thread_1 === thread_2`.

This is unsafe with `owl.reactive()`, because it wraps the objects
in a Proxy, and different proxies may map to a same raw object.

This commit fixes the issue by defining `.eq()` and `.in()` methods
on discuss models, which makes comparison on raw value rather than
proxy/reactive one.

This PR also introduce "not" variants, e.g. `.notEq()`, which eases
readability by having "not" and "eq" next to each other.
These "not" variants must be used without optional chaining,
otherwise this gives the opposite result. For example:

```js
const [t1, t2] = [Thread.insert()];
t1 === t1     // true (OK)
t1.eq(t1)     // true (OK)
t1.notEq(t1)  // false (OK)
t2?.notEq(t1) // undefined => falsy (notOk)
!t2?.eq(t1)   // true (OK)
```

closes odoo/odoo#133065

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-08-25 12:21:03 +02:00