[IMP] mail: introduce AutocompleteInputView (step 2)

This commit moves some business logic from component AutocompleteInput
To model AutocompleteInputView, as a step to move further to having essentially
all business code in models.

Having code in models is desirable to have very maintainable code, thanks to
robust and declarative code with an ORM-like architecture.

Task-2817076

closes odoo/odoo#89077

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
This commit is contained in:
Alexandre Kühn
2022-04-19 20:37:43 +02:00
parent d4816d740e
commit e1b037dc4c
11 changed files with 73 additions and 43 deletions
@@ -57,6 +57,13 @@ export class AutocompleteInput extends Component {
$(this.root.el).autocomplete('destroy');
}
/**
* @returns {AutocompleteInputView}
*/
get autocompleteInputView() {
return this.messaging && this.messaging.models['AutocompleteInputView'].get(this.props.localId);
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
@@ -154,8 +161,6 @@ Object.assign(AutocompleteInput, {
defaultProps: {
isFocusOnMount: false,
isHtml: false,
placeholder: '',
onFocusin: () => {},
},
props: {
customClass: {
@@ -174,10 +179,7 @@ Object.assign(AutocompleteInput, {
type: Boolean,
optional: true,
},
onFocusin: {
type: Function,
optional: true,
},
localId: String,
onHide: {
type: Function,
optional: true,
@@ -2,7 +2,7 @@
<templates xml:space="preserve">
<t t-name="mail.AutocompleteInput" owl="1">
<input class="o_AutocompleteInput" t-attf-class="{{ className }}" t-on-blur="_onBlur" t-on-focusin="props.onFocusin" t-on-keydown="_onKeydown" t-att-placeholder="props.placeholder" t-ref="root"/>
<input class="o_AutocompleteInput" t-attf-class="{{ className }}" t-on-blur="_onBlur" t-on-focusin="autocompleteInputView.onFocusin" t-on-keydown="_onKeydown" t-att-placeholder="autocompleteInputView.placeholder" t-ref="root"/>
</t>
</templates>
@@ -40,10 +40,9 @@
</span>
<AutocompleteInput
className="'o_ChatWindow_newMessageFormInput'"
placeholder="chatWindow.newMessageFormInputPlaceholder"
localId="chatWindow.newMessageAutocompleteInputView.localId"
select="_onAutocompleteSelect"
source="_onAutocompleteSource"
onFocusin="chatWindow.onFocusInNewMessageFormInput"
inputRef="_inputRef"
/>
</div>
@@ -12,7 +12,6 @@ export class Discuss extends LegacyComponent {
setup() {
this._updateLocalStoreProps();
// bind since passed as props
this._onMobileAddItemHeaderInputSelect = this._onMobileAddItemHeaderInputSelect.bind(this);
this._onMobileAddItemHeaderInputSource = this._onMobileAddItemHeaderInputSource.bind(this);
useUpdate({ func: () => this._update() });
this._onHideMobileAddItemHeader = this._onHideMobileAddItemHeader.bind(this);
@@ -93,25 +92,6 @@ export class Discuss extends LegacyComponent {
this.discussView.discuss.clearIsAddingItem();
}
/**
* @private
* @param {Event} ev
* @param {Object} ui
* @param {Object} ui.item
* @param {integer} ui.item.id
*/
_onMobileAddItemHeaderInputSelect(ev, ui) {
if (!this.discussView) {
return;
}
const discuss = this.discussView.discuss;
if (discuss.isAddingChannel) {
discuss.handleAddChannelAutocompleteSelect(ev, ui);
} else {
discuss.handleAddChatAutocompleteSelect(ev, ui);
}
}
/**
* @private
* @param {Object} req
@@ -33,8 +33,8 @@
className="'o_Discuss_mobileAddItemHeaderInput'"
isFocusOnMount="true"
isHtml="discussView.discuss.isAddingChannel"
placeholder="discussView.discuss.isAddingChannel ? discussView.discuss.addChannelInputPlaceholder : discussView.discuss.addChatInputPlaceholder"
select="_onMobileAddItemHeaderInputSelect"
localId="discussView.mobileAddItemHeaderAutocompleteInputView.localId"
select="discussView.onMobileAddItemHeaderInputSelect"
source="_onMobileAddItemHeaderInputSource"
onHide="_onHideMobileAddItemHeader"
/>
@@ -31,9 +31,9 @@
<AutocompleteInput
className="'o_DiscussSidebarCategory_addingItemInput flex-grow-1'"
customClass="category === messaging.discuss.categoryChannel ? 'o_DiscussSidebarCategory_newChannelAutocompleteSuggestions' : False"
localId="category.addingItemAutocompleteInputView.localId"
isFocusOnMount="true"
isHtml="category === messaging.discuss.categoryChannel ? true : False"
placeholder="category.newItemPlaceholderText"
select="category.onAddItemAutocompleteSelect"
source="category.onAddItemAutocompleteSource"
onHide="category.onHideAddingItem"
@@ -21,7 +21,6 @@ export class MessagingMenu extends Component {
this._onMobileNewMessageInputSelect = this._onMobileNewMessageInputSelect.bind(this);
this._onMobileNewMessageInputSource = this._onMobileNewMessageInputSource.bind(this);
this._onClickCaptureGlobal = this._onClickCaptureGlobal.bind(this);
this._onHideMobileNewMessage = this._onHideMobileNewMessage.bind(this);
onMounted(() => this._mounted());
onWillUnmount(() => this._willUnmount());
}
@@ -67,13 +66,6 @@ export class MessagingMenu extends Component {
this.messagingMenu.close();
}
/**
* @private
*/
_onHideMobileNewMessage() {
this.messagingMenu.toggleMobileNewMessage();
}
/**
* @private
* @param {Event} ev
@@ -43,10 +43,10 @@
className="'o_MessagingMenu_mobileNewMessageInput'"
customClass="id + '_mobileNewMessageInputAutocomplete'"
isFocusOnMount="true"
placeholder="messagingMenu.mobileNewMessageInputPlaceholder"
localId="messagingMenu.mobileNewMessageAutocompleteInputView.localId"
select="_onMobileNewMessageInputSelect"
source="_onMobileNewMessageInputSource"
onHide="_onHideMobileNewMessage"
onHide="messagingMenu.onHideMobileNewMessage"
/>
</t>
</div>
@@ -1,7 +1,8 @@
/** @odoo-module **/
import { registerModel } from '@mail/model/model_core';
import { one } from '@mail/model/model_field';
import { attr, one } from '@mail/model/model_field';
import { clear } from '@mail/model/model_field_command';
registerModel({
name: 'AutocompleteInputView',
@@ -11,6 +12,40 @@ registerModel({
'discussViewOwnerAsMobileAddItemHeader',
'messagingMenuOwnerAsMobileNewMessageInput',
]],
recordMethods: {
/**
* @param {FocusEvent} ev
*/
onFocusin(ev) {
if (this.chatWindowOwnerAsNewMessage) {
this.chatWindowOwnerAsNewMessage.onFocusInNewMessageFormInput(ev);
return;
}
},
/**
* @private
* @returns {string}
*/
_computePlaceholder() {
if (this.chatWindowOwnerAsNewMessage) {
return this.chatWindowOwnerAsNewMessage.newMessageFormInputPlaceholder;
}
if (this.discussViewOwnerAsMobileAddItemHeader) {
if (this.discussViewOwnerAsMobileAddItemHeader.discuss.isAddingChannel) {
return this.discussViewOwnerAsMobileAddItemHeader.discuss.addChannelInputPlaceholder;
} else {
return this.discussViewOwnerAsMobileAddItemHeader.discuss.addChatInputPlaceholder;
}
}
if (this.discussSidebarCategoryOwnerAsAddingItem) {
return this.discussSidebarCategoryOwnerAsAddingItem.newItemPlaceholderText;
}
if (this.messagingMenuOwnerAsMobileNewMessageInput) {
return this.messagingMenuOwnerAsMobileNewMessageInput.mobileNewMessageInputPlaceholder;
}
return clear();
},
},
fields: {
chatWindowOwnerAsNewMessage: one('ChatWindow', {
inverse: 'newMessageAutocompleteInputView',
@@ -28,5 +63,8 @@ registerModel({
inverse: 'mobileNewMessageAutocompleteInputView',
readonly: true,
}),
placeholder: attr({
compute: '_computePlaceholder',
}),
},
});
@@ -59,6 +59,22 @@ registerModel({
}
mailbox.open();
},
/**
* @param {Event} ev
* @param {Object} ui
* @param {Object} ui.item
* @param {integer} ui.item.id
*/
onMobileAddItemHeaderInputSelect(ev, ui) {
if (!this.exists()) {
return;
}
if (this.discuss.isAddingChannel) {
this.discuss.handleAddChannelAutocompleteSelect(ev, ui);
} else {
this.discuss.handleAddChatAutocompleteSelect(ev, ui);
}
},
/**
* @private
* @returns {FieldCommand}
@@ -42,6 +42,9 @@ registerModel({
}
this.toggleOpen();
},
onHideMobileNewMessage() {
this.update({ isMobileNewMessageToggled: false });
},
/**
* Toggle the visibility of the messaging menu "new message" input in
* mobile.