[REF] hr_expense, lunch, mail: change patch to mixin
Before this commit, a patch was used to modify some classes in place but these classes were declared some lines just before the patch. This commit replaces those patches by mixins, it's a better way to provide a same extension to multiple classes as the extension is done by the language. Task: 3410198 Part-of: odoo/odoo#125716
This commit is contained in:
@@ -4,9 +4,9 @@ import { useBus, useService } from '@web/core/utils/hooks';
|
||||
|
||||
const { useRef, useEffect, useState } = owl;
|
||||
|
||||
export const ExpenseDocumentDropZone = {
|
||||
export const ExpenseDocumentDropZone = (T) => class ExpenseDocumentDropZone extends T {
|
||||
setup() {
|
||||
this._super();
|
||||
super.setup();
|
||||
this.dragState = useState({
|
||||
showDragZone: false,
|
||||
});
|
||||
@@ -31,31 +31,31 @@ export const ExpenseDocumentDropZone = {
|
||||
},
|
||||
() => [document.querySelector('.o_content')]
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
highlight(ev) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.dragState.showDragZone = true;
|
||||
},
|
||||
}
|
||||
|
||||
unhighlight(ev) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.dragState.showDragZone = false;
|
||||
},
|
||||
}
|
||||
|
||||
async onDrop(ev) {
|
||||
ev.preventDefault();
|
||||
await this.env.bus.trigger("change_file_input", {
|
||||
files: ev.dataTransfer.files,
|
||||
});
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export const ExpenseDocumentUpload = {
|
||||
export const ExpenseDocumentUpload = (T) => class ExpenseDocumentUpload extends T {
|
||||
setup() {
|
||||
this._super();
|
||||
super.setup();
|
||||
this.actionService = useService('action');
|
||||
this.notification = useService('notification');
|
||||
this.orm = useService('orm');
|
||||
@@ -67,11 +67,11 @@ export const ExpenseDocumentUpload = {
|
||||
this.fileInput.el.files = ev.detail.files;
|
||||
await this.onChangeFileInput();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
uploadDocument() {
|
||||
this.fileInput.el.click();
|
||||
},
|
||||
}
|
||||
|
||||
async onChangeFileInput() {
|
||||
const params = {
|
||||
@@ -87,7 +87,7 @@ export const ExpenseDocumentUpload = {
|
||||
throw new Error(attachments.error);
|
||||
}
|
||||
this.onUpload(attachments);
|
||||
},
|
||||
}
|
||||
|
||||
async onUpload(attachments) {
|
||||
const attachmentIds = attachments.map((a) => a.id);
|
||||
@@ -100,5 +100,5 @@ export const ExpenseDocumentUpload = {
|
||||
|
||||
const action = await this.orm.call('hr.expense', 'create_expense_from_attachments', ["", attachmentIds]);
|
||||
this.actionService.doAction(action);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,15 +4,15 @@ import { useService } from "@web/core/utils/hooks";
|
||||
|
||||
const { onMounted, onPatched, useRef } = owl;
|
||||
|
||||
export const ExpenseMobileQRCode = {
|
||||
export const ExpenseMobileQRCode = (T) => class ExpenseMobileQRCode extends T {
|
||||
setup() {
|
||||
this._super();
|
||||
super.setup();
|
||||
this.root = useRef('root');
|
||||
this.actionService = useService('action');
|
||||
|
||||
onMounted(this.bindAppsIcons);
|
||||
onPatched(this.bindAppsIcons);
|
||||
},
|
||||
}
|
||||
|
||||
bindAppsIcons() {
|
||||
const apps = this.root.el.querySelectorAll('.o_expense_mobile_app');
|
||||
@@ -24,7 +24,7 @@ export const ExpenseMobileQRCode = {
|
||||
for (const app of apps) {
|
||||
app.addEventListener('click', handler);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
handleClick(ev) {
|
||||
ev.preventDefault();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/** @odoo-module */
|
||||
|
||||
import { registry } from '@web/core/registry';
|
||||
import { patch } from '@web/core/utils/patch';
|
||||
|
||||
import { ExpenseDashboard } from '../components/expense_dashboard';
|
||||
import { ExpenseMobileQRCode } from '../mixins/qrcode';
|
||||
@@ -11,12 +10,9 @@ import { kanbanView } from '@web/views/kanban/kanban_view';
|
||||
import { KanbanController } from '@web/views/kanban/kanban_controller';
|
||||
import { KanbanRenderer } from '@web/views/kanban/kanban_renderer';
|
||||
|
||||
export class ExpenseKanbanController extends KanbanController {}
|
||||
patch(ExpenseKanbanController.prototype, 'expense_kanban_controller_upload', ExpenseDocumentUpload);
|
||||
export class ExpenseKanbanController extends ExpenseDocumentUpload(KanbanController) {}
|
||||
|
||||
export class ExpenseKanbanRenderer extends KanbanRenderer {}
|
||||
patch(ExpenseKanbanRenderer.prototype, 'expense_kanban_renderer_qrcode', ExpenseMobileQRCode);
|
||||
patch(ExpenseKanbanRenderer.prototype, 'expense_kanban_renderer_qrcode_dzone', ExpenseDocumentDropZone);
|
||||
export class ExpenseKanbanRenderer extends ExpenseDocumentDropZone(ExpenseMobileQRCode(KanbanRenderer)) {}
|
||||
ExpenseKanbanRenderer.template = 'hr_expense.KanbanRenderer';
|
||||
|
||||
export class ExpenseDashboardKanbanRenderer extends ExpenseKanbanRenderer {}
|
||||
|
||||
@@ -5,7 +5,6 @@ import { ExpenseMobileQRCode } from '../mixins/qrcode';
|
||||
import { ExpenseDocumentUpload, ExpenseDocumentDropZone } from '../mixins/document_upload';
|
||||
|
||||
import { registry } from '@web/core/registry';
|
||||
import { patch } from '@web/core/utils/patch';
|
||||
import { useService } from '@web/core/utils/hooks';
|
||||
import { listView } from "@web/views/list/list_view";
|
||||
|
||||
@@ -14,7 +13,7 @@ import { ListRenderer } from "@web/views/list/list_renderer";
|
||||
|
||||
const { onWillStart } = owl;
|
||||
|
||||
export class ExpenseListController extends ListController {
|
||||
export class ExpenseListController extends ExpenseDocumentUpload(ListController) {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.orm = useService('orm');
|
||||
@@ -81,11 +80,8 @@ export class ExpenseListController extends ListController {
|
||||
}
|
||||
}
|
||||
}
|
||||
patch(ExpenseListController.prototype, 'expense_list_controller_upload', ExpenseDocumentUpload);
|
||||
|
||||
export class ExpenseListRenderer extends ListRenderer {}
|
||||
patch(ExpenseListRenderer.prototype, 'expense_list_renderer_qrcode', ExpenseMobileQRCode);
|
||||
patch(ExpenseListRenderer.prototype, 'expense_list_renderer_qrcode_dzone', ExpenseDocumentDropZone);
|
||||
export class ExpenseListRenderer extends ExpenseDocumentDropZone(ExpenseMobileQRCode(ListRenderer)) {}
|
||||
ExpenseListRenderer.template = 'hr_expense.ListRenderer';
|
||||
|
||||
export class ExpenseDashboardListRenderer extends ExpenseListRenderer {}
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
import { useBus, useService } from "@web/core/utils/hooks";
|
||||
|
||||
export const LunchRendererMixin = {
|
||||
export const LunchRendererMixin = (T) => class LunchRendererMixin extends T {
|
||||
setup() {
|
||||
this._super(...arguments);
|
||||
super.setup(...arguments);
|
||||
|
||||
this.action = useService("action");
|
||||
useBus(this.env.bus, 'lunch_open_order', (ev) => this.openOrderLine(ev.detail.productId));
|
||||
},
|
||||
}
|
||||
|
||||
openOrderLine(productId, orderId) {
|
||||
let context = {};
|
||||
@@ -36,5 +36,5 @@ export const LunchRendererMixin = {
|
||||
this.action.doAction(action, {
|
||||
onClose: () => this.env.bus.trigger('lunch_update_dashboard')
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/** @odoo-module */
|
||||
|
||||
import { patch } from '@web/core/utils/patch';
|
||||
import { registry } from '@web/core/registry';
|
||||
|
||||
import { kanbanView } from '@web/views/kanban/kanban_view';
|
||||
@@ -19,8 +18,7 @@ export class LunchKanbanRecord extends KanbanRecord {
|
||||
}
|
||||
}
|
||||
|
||||
export class LunchKanbanRenderer extends KanbanRenderer {}
|
||||
patch(LunchKanbanRenderer.prototype, 'lunch_kanban_renderer_mixin', LunchRendererMixin);
|
||||
export class LunchKanbanRenderer extends LunchRendererMixin(KanbanRenderer) {}
|
||||
|
||||
LunchKanbanRenderer.template = 'lunch.KanbanRenderer';
|
||||
LunchKanbanRenderer.components = {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/** @odoo-module */
|
||||
|
||||
import { patch } from '@web/core/utils/patch';
|
||||
import { registry } from '@web/core/registry';
|
||||
|
||||
import { listView } from '@web/views/list/list_view';
|
||||
@@ -12,12 +11,11 @@ import { LunchRendererMixin } from '../mixins/lunch_renderer_mixin';
|
||||
import { LunchSearchModel } from './search_model';
|
||||
|
||||
|
||||
export class LunchListRenderer extends ListRenderer {
|
||||
export class LunchListRenderer extends LunchRendererMixin(ListRenderer) {
|
||||
onCellClicked(record, column) {
|
||||
this.openOrderLine(record.resId);
|
||||
}
|
||||
}
|
||||
patch(LunchListRenderer.prototype, 'lunch_list_renderer_mixin', LunchRendererMixin);
|
||||
|
||||
LunchListRenderer.template = 'lunch.ListRenderer';
|
||||
LunchListRenderer.components = {
|
||||
|
||||
@@ -3,36 +3,24 @@
|
||||
import { escape } from "@web/core/utils/strings";
|
||||
|
||||
/**
|
||||
* This mixin gathers a few methods that are used to handle emojis.
|
||||
* Adds a span with a CSS class around chains of emojis in the message for styling purposes.
|
||||
* The input is first passed through 'escape' to prevent unwanted injections into the HTML
|
||||
*
|
||||
* It's currently used to format text and wrap the emojis around <span class="o_mail_emoji"> to make them look nicer
|
||||
* Sequences of emojis are wrapped instead of individual ones to prevent compound emojis
|
||||
* such as 👩🏿 = 👩 + 🏿 [dark skin tone character] from being separated.
|
||||
*
|
||||
* This will only match characters that have a different presentation from normal text, unlike ®
|
||||
* For alternatives, see: https://www.unicode.org/reports/tr51/#Emoji_Properties_and_Data_Files
|
||||
*
|
||||
* @param {String} message a text message to format
|
||||
*/
|
||||
export default {
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
export function formatText(message) {
|
||||
message = escape(message);
|
||||
message = message.replaceAll(
|
||||
/(\p{Emoji_Presentation}+)/gu,
|
||||
"<span class='o_mail_emoji'>$1</span>"
|
||||
);
|
||||
message = message.replace(/(?:\r\n|\r|\n)/g, "<br>");
|
||||
|
||||
/**
|
||||
* Adds a span with a CSS class around chains of emojis in the message for styling purposes.
|
||||
* The input is first passed through 'escape' to prevent unwanted injections into the HTML
|
||||
*
|
||||
* Sequences of emojis are wrapped instead of individual ones to prevent compound emojis
|
||||
* such as 👩🏿 = 👩 + 🏿 [dark skin tone character] from being separated.
|
||||
*
|
||||
* This will only match characters that have a different presentation from normal text, unlike ®
|
||||
* For alternatives, see: https://www.unicode.org/reports/tr51/#Emoji_Properties_and_Data_Files
|
||||
*
|
||||
* @param {String} message a text message to format
|
||||
*/
|
||||
_formatText(message) {
|
||||
message = escape(message);
|
||||
message = message.replaceAll(
|
||||
/(\p{Emoji_Presentation}+)/gu,
|
||||
"<span class='o_mail_emoji'>$1</span>"
|
||||
);
|
||||
message = message.replace(/(?:\r\n|\r|\n)/g, "<br>");
|
||||
|
||||
return message;
|
||||
},
|
||||
};
|
||||
return message;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
/* @odoo-module */
|
||||
|
||||
import MailEmojisMixin from "@mail/js/emojis_mixin";
|
||||
import { EmojisFieldCommon } from "@mail/views/web/fields/emojis_field_common/emojis_field_common";
|
||||
|
||||
import { useRef } from "@odoo/owl";
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
import { patch } from "@web/core/utils/patch";
|
||||
import { CharField, charField } from "@web/views/fields/char/char_field";
|
||||
|
||||
/**
|
||||
* Extension of the FieldChar that will add emojis support
|
||||
*/
|
||||
export class EmojisCharField extends CharField {
|
||||
export class EmojisCharField extends EmojisFieldCommon(CharField) {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.targetEditElement = useRef("input");
|
||||
@@ -20,8 +18,6 @@ export class EmojisCharField extends CharField {
|
||||
}
|
||||
}
|
||||
|
||||
patch(EmojisCharField.prototype, "emojis_char_field_mail_mixin", MailEmojisMixin);
|
||||
patch(EmojisCharField.prototype, "emojis_char_field_field_mixin", EmojisFieldCommon);
|
||||
EmojisCharField.template = "mail.EmojisCharField";
|
||||
EmojisCharField.components = { ...CharField.components };
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { useRef } from "@odoo/owl";
|
||||
/*
|
||||
* Common code for EmojisTextField and EmojisCharField
|
||||
*/
|
||||
export const EmojisFieldCommon = {
|
||||
export const EmojisFieldCommon = (T) => class EmojisFieldCommon extends T {
|
||||
/**
|
||||
* Create an emoji textfield view to enable opening an emoji popover
|
||||
*/
|
||||
@@ -38,5 +38,5 @@ export const EmojisFieldCommon = {
|
||||
position: "bottom",
|
||||
}
|
||||
);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
/* @odoo-module */
|
||||
|
||||
import MailEmojisMixin from "@mail/js/emojis_mixin";
|
||||
import { EmojisFieldCommon } from "@mail/views/web/fields/emojis_field_common/emojis_field_common";
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
import { patch } from "@web/core/utils/patch";
|
||||
import { TextField, textField } from "@web/views/fields/text/text_field";
|
||||
|
||||
/**
|
||||
* Extension of the FieldText that will add emojis support
|
||||
*/
|
||||
export class EmojisTextField extends TextField {
|
||||
export class EmojisTextField extends EmojisFieldCommon(TextField) {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.targetEditElement = this.textareaRef;
|
||||
@@ -18,8 +16,6 @@ export class EmojisTextField extends TextField {
|
||||
}
|
||||
}
|
||||
|
||||
patch(EmojisTextField.prototype, "emojis_char_field_mail_mixin", MailEmojisMixin);
|
||||
patch(EmojisTextField.prototype, "emojis_text_field_field_mixin", EmojisFieldCommon);
|
||||
EmojisTextField.template = "mail.EmojisTextField";
|
||||
EmojisTextField.components = { ...TextField.components };
|
||||
|
||||
|
||||
+10
-13
@@ -5,7 +5,6 @@ import { useAssignUserCommand } from "@mail/views/web/fields/assign_user_command
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
import { TagsList } from "@web/core/tags_list/tags_list";
|
||||
import { patch } from "@web/core/utils/patch";
|
||||
import { usePopover } from "@web/core/popover/popover_hook";
|
||||
import { browser } from "@web/core/browser/browser";
|
||||
import { AvatarCardPopover } from "@mail/discuss/web/avatar_card/avatar_card_popover";
|
||||
@@ -22,9 +21,9 @@ import {
|
||||
export class Many2ManyAvatarUserTagsList extends TagsList {}
|
||||
Many2ManyAvatarUserTagsList.template = "mail.Many2ManyAvatarUserTagsList";
|
||||
|
||||
const userChatter = {
|
||||
const WithUserChatter = (T) => class UserChatterMixin extends T {
|
||||
setup() {
|
||||
this._super(...arguments);
|
||||
super.setup(...arguments);
|
||||
this.openChat = useOpenChat(this.relation);
|
||||
if (this.props.withCommand) {
|
||||
useAssignUserCommand();
|
||||
@@ -34,11 +33,11 @@ const userChatter = {
|
||||
});
|
||||
this.openTimeout = false;
|
||||
this.lastOpenedId = 0;
|
||||
},
|
||||
}
|
||||
|
||||
getTagProps(record) {
|
||||
return {
|
||||
...this._super(...arguments),
|
||||
...super.getTagProps(...arguments),
|
||||
onImageClicked: () => this.openChat(record.resId),
|
||||
openCard: (ev) => {
|
||||
if (this.env.isSmall || this.relation !== "res.users") {
|
||||
@@ -62,15 +61,15 @@ const userChatter = {
|
||||
delete this.openTimeout;
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
export class Many2ManyTagsAvatarUserField extends Many2ManyTagsAvatarField {
|
||||
}
|
||||
}
|
||||
|
||||
export class Many2ManyTagsAvatarUserField extends WithUserChatter(Many2ManyTagsAvatarField) {
|
||||
static components = {
|
||||
...Many2ManyTagsAvatarField.components,
|
||||
TagsList: Many2ManyAvatarUserTagsList,
|
||||
};
|
||||
}
|
||||
patch(Many2ManyTagsAvatarUserField.prototype, "mail/fields/web", userChatter);
|
||||
|
||||
export const many2ManyTagsAvatarUserField = {
|
||||
...many2ManyTagsAvatarField,
|
||||
@@ -84,7 +83,7 @@ export class KanbanMany2ManyAvatarUserTagsList extends KanbanMany2ManyTagsAvatar
|
||||
static template = "mail.KanbanMany2ManyAvatarUserTagsList";
|
||||
}
|
||||
|
||||
export class KanbanMany2ManyTagsAvatarUserField extends KanbanMany2ManyTagsAvatarField {
|
||||
export class KanbanMany2ManyTagsAvatarUserField extends WithUserChatter(KanbanMany2ManyTagsAvatarField) {
|
||||
static template = "mail.KanbanMany2ManyTagsAvatarUserField";
|
||||
static components = {
|
||||
...KanbanMany2ManyTagsAvatarField.components,
|
||||
@@ -94,7 +93,6 @@ export class KanbanMany2ManyTagsAvatarUserField extends KanbanMany2ManyTagsAvata
|
||||
return !this.props.readonly;
|
||||
}
|
||||
}
|
||||
patch(KanbanMany2ManyTagsAvatarUserField.prototype, "mail/fields/web", userChatter);
|
||||
export const kanbanMany2ManyTagsAvatarUserField = {
|
||||
...kanbanMany2ManyTagsAvatarField,
|
||||
component: KanbanMany2ManyTagsAvatarUserField,
|
||||
@@ -102,7 +100,7 @@ export const kanbanMany2ManyTagsAvatarUserField = {
|
||||
};
|
||||
registry.category("fields").add("kanban.many2many_avatar_user", kanbanMany2ManyTagsAvatarUserField);
|
||||
|
||||
export class ListMany2ManyTagsAvatarUserField extends ListMany2ManyTagsAvatarField {
|
||||
export class ListMany2ManyTagsAvatarUserField extends WithUserChatter(ListMany2ManyTagsAvatarField) {
|
||||
static template = "mail.ListMany2ManyTagsAvatarUserField";
|
||||
static components = {
|
||||
...ListMany2ManyTagsAvatarField.components,
|
||||
@@ -113,7 +111,6 @@ export class ListMany2ManyTagsAvatarUserField extends ListMany2ManyTagsAvatarFie
|
||||
return this.props.record.data[this.props.name].records.length === 1 || !this.props.readonly;
|
||||
}
|
||||
}
|
||||
patch(ListMany2ManyTagsAvatarUserField.prototype, "mail/fields/web", userChatter);
|
||||
|
||||
export const listMany2ManyTagsAvatarUserField = {
|
||||
...listMany2ManyTagsAvatarField,
|
||||
|
||||
+8
-11
@@ -5,7 +5,6 @@ import { useAssignUserCommand } from "@mail/views/web/fields/assign_user_command
|
||||
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
import { registry } from "@web/core/registry";
|
||||
import { patch } from "@web/core/utils/patch";
|
||||
import {
|
||||
Many2OneAvatarField,
|
||||
many2OneAvatarField,
|
||||
@@ -16,9 +15,9 @@ import { usePopover } from "@web/core/popover/popover_hook";
|
||||
import { browser } from "@web/core/browser/browser";
|
||||
import { AvatarCardPopover } from "@mail/discuss/web/avatar_card/avatar_card_popover";
|
||||
|
||||
const userChatter = {
|
||||
const WithUserChatter = (T) => class extends T {
|
||||
setup() {
|
||||
this._super(...arguments);
|
||||
super.setup(...arguments);
|
||||
this.openChat = useOpenChat(this.relation);
|
||||
if (this.props.withCommand) {
|
||||
useAssignUserCommand();
|
||||
@@ -27,14 +26,14 @@ const userChatter = {
|
||||
closeOnHoverAway: true,
|
||||
});
|
||||
this.openTimeout = false;
|
||||
},
|
||||
}
|
||||
|
||||
onClickAvatar() {
|
||||
const id = this.props.record.data[this.props.name][0] ?? false;
|
||||
if (id !== false) {
|
||||
this.openChat(id);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
openCard(ev) {
|
||||
if (this.env.isSmall || this.relation !== "res.users") {
|
||||
@@ -51,15 +50,15 @@ const userChatter = {
|
||||
});
|
||||
}
|
||||
}, 350);
|
||||
},
|
||||
}
|
||||
|
||||
clearTimeout() {
|
||||
browser.clearTimeout(this.openTimeout);
|
||||
delete this.openTimeout;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export class Many2OneAvatarUserField extends Many2OneAvatarField {
|
||||
export class Many2OneAvatarUserField extends WithUserChatter(Many2OneAvatarField) {
|
||||
static template = "mail.Many2OneAvatarUserField";
|
||||
static props = {
|
||||
...Many2OneAvatarField.props,
|
||||
@@ -68,7 +67,6 @@ export class Many2OneAvatarUserField extends Many2OneAvatarField {
|
||||
withCommand: { type: Boolean, optional: true },
|
||||
};
|
||||
}
|
||||
patch(Many2OneAvatarUserField.prototype, "mail/fields/web", userChatter);
|
||||
|
||||
export const many2OneAvatarUserField = {
|
||||
...many2OneAvatarField,
|
||||
@@ -85,7 +83,7 @@ export const many2OneAvatarUserField = {
|
||||
|
||||
registry.category("fields").add("many2one_avatar_user", many2OneAvatarUserField);
|
||||
|
||||
export class KanbanMany2OneAvatarUserField extends KanbanMany2OneAvatarField {
|
||||
export class KanbanMany2OneAvatarUserField extends WithUserChatter(KanbanMany2OneAvatarField) {
|
||||
static template = "mail.KanbanMany2OneAvatarUserField";
|
||||
static props = {
|
||||
...KanbanMany2OneAvatarField.props,
|
||||
@@ -101,7 +99,6 @@ export class KanbanMany2OneAvatarUserField extends KanbanMany2OneAvatarField {
|
||||
return props;
|
||||
}
|
||||
}
|
||||
patch(KanbanMany2OneAvatarUserField.prototype, "mail/fields/web", userChatter);
|
||||
|
||||
export const kanbanMany2OneAvatarUserField = {
|
||||
...kanbanMany2OneAvatarField,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* @odoo-module */
|
||||
|
||||
import EmojiMixin from "@mail/js/emojis_mixin";
|
||||
import { formatText } from "@mail/js/emojis_mixin";
|
||||
|
||||
QUnit.module("emojis mixin");
|
||||
|
||||
@@ -8,5 +8,5 @@ QUnit.test("Emoji formatter handles compound emojis", (assert) => {
|
||||
const testString = "👩🏿test👩🏿👩t👩";
|
||||
const expectedString =
|
||||
"<span class='o_mail_emoji'>👩🏿</span>test<span class='o_mail_emoji'>👩🏿👩</span>t<span class='o_mail_emoji'>👩</span>";
|
||||
assert.deepEqual(EmojiMixin._formatText(testString), expectedString);
|
||||
assert.deepEqual(formatText(testString), expectedString);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user