Skip to content

Commit 2d55b01

Browse files
author
Zachary (zavan)
committed
[FIX] mail : fix chatter suggestions position
# How to reproduce - Go into any form view of a model with a chatter (e.g. Quotation) - Add multiple long log notes. You need to be able to scroll enough to not see the last log note - Click edit on the last log note - Scroll down to the bottom # The problem An empty rectangle is displayed next to the log note in edit mode. # Cause The rectangle comes from the NavigableList Component, which is the list that displays suggestions when typing things like "@" or "#" : https://github.com/odoo/odoo/blob/1fd44c3bb11a79d5b6aa72bf7de5a83e6c45be46/addons/mail/static/src/core/common/composer.xml#L137 This components uses the `usePostion()` hook, which purpose is to try to find the most appropriate place to put the element. It will try different postions (e.g. on the left, below, above, etc.) and will pick the most appropriate one. It will then adjust the element's style to position it correctly. It is possible to ask for a preferred position using the options given to the hook. This position will be prioritized over the others if it is suitable. In the case of the NavigableList of the chatter, we give it either 'bottom-fit' or the 'top-fit' positions, wich means it will prefer to be displayed above or below the message : https://github.com/odoo/odoo/blob/dd84309df7fd39e9e97ed02d135d25b211085135/addons/mail/static/src/core/common/composer.js#L449-L459 But in our case, when we scroll back up, the position of the rectangle stays on the left, even though the below space is available. That is because of this commit that introduced a memorization of the last solution : odoo@b2b8d2d https://github.com/odoo/odoo/blob/f2434aac74324a65ccd81aa18c7b0e8318e59fde/addons/web/static/src/core/position/position_hook.js#L59-L61 This means that when we scroll down, the bottom positions fails and so the left one is defaulted to. Since the position is memorized, it stays on the left. The issue with this left position is that another commit introduced some logic that made it so if the position is not "top" or "bottom", then we set the element's height to some value : odoo@702748e https://github.com/odoo/odoo/blob/f2434aac74324a65ccd81aa18c7b0e8318e59fde/addons/web/static/src/core/position/utils.js#L120-L124 And setting the height of the NavigableList makes it so it displayed even when there are no suggestions inside, because the hiding mechanism of the suggestion list relies on the fact that when there are no suggestions, the div is empty and has no height, so it is hidden. # Propose solution We introduce a settings in the options that will allow to skip the memorization of the last position. Since the left position will never be set in the options, no height will be defined. opw-6172407 closes odoo#269769 X-original-commit: d6c5dc6 Signed-off-by: Bastien Fafchamps (bafa) <bafa@odoo.com> Signed-off-by: Zachary Vanvlasselaer (zavan) <zavan@odoo.com>
1 parent 24e33e6 commit 2d55b01

3 files changed

Lines changed: 7 additions & 2 deletions

File tree

addons/mail/static/src/core/common/composer.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,7 @@ export class Composer extends Component {
553553
},
554554
isLoading: !!searchTerm && loading,
555555
options: [],
556+
rememberPosition: false,
556557
};
557558
if (!this.hasSuggestions) {
558559
return props;

addons/mail/static/src/core/common/navigable_list.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export class NavigableList extends Component {
2424
options: types.array(types.object()),
2525
"optionTemplate?": types.string(),
2626
"position?": types.string(),
27+
"rememberPosition?": types.boolean(),
2728
},
2829
{
2930
closeOnSelect: true,
@@ -49,7 +50,7 @@ export class NavigableList extends Component {
4950
this.close();
5051
});
5152
// position and size
52-
usePosition("root", () => this.props.anchorRef?.(), { position: this.props.position });
53+
usePosition("root", () => this.props.anchorRef?.(), { position: this.props.position, rememberPosition: this.props.rememberPosition });
5354
useLayoutEffect(
5455
() => {
5556
this.open();

addons/web/static/src/core/position/position_hook.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import { EventBus, onWillDestroy } from "@odoo/owl";
1212
* @property {(popperElement: HTMLElement, solution: PositioningSolution) => void} [onPositioned]
1313
* callback called when the positioning is done.
1414
* @typedef {ComputePositionOptions & UsePositionOptionsExtensionType} UsePositionOptions
15+
* @property {boolean} [rememberPosition=true]
16+
* keep the last position as the preferred one
1517
*
1618
* @typedef PositioningControl
1719
* @property {() => void} lock prevents further positioning updates
@@ -42,6 +44,7 @@ export const POSITION_BUS = Symbol("position-bus");
4244
* control object to lock/unlock the positioning.
4345
*/
4446
export function usePosition(popperRef, getTarget, options = {}) {
47+
const rememberPosition = options.rememberPosition ?? true;
4548
// Transitional shim (Owl 2 -> 3): `popperRef` may be either a legacy
4649
// ref-name string (resolved through `useRef`) or an Owl 3 signal (a
4750
// function returning the element). Resolve "the current popper element"
@@ -67,7 +70,7 @@ export function usePosition(popperRef, getTarget, options = {}) {
6770
const repositionOptions = omit(options, "onPositioned");
6871
const solution = reposition(popperEl, targetEl, repositionOptions);
6972
// Don't memorize center position because it's a fallback that we don't want to keep if possible
70-
if (solution.direction !== "center") {
73+
if (rememberPosition && solution.direction !== "center") {
7174
options.position = `${solution.direction}-${solution.variant}`; // memorize last position
7275
}
7376
options.onPositioned?.(popperEl, solution);

0 commit comments

Comments
 (0)