Odoo 15 - overwrite .js file in Owl framework (Chatter Component)

270 views Asked by At

I want to overwrite chatter.js (module: mail/static/src/components/chatter/chatter.js) in odoo 15. I want to add there user_chatter_status so, this how look my modified file :

/** @odoo-module **/

import { registerMessagingComponent } from "@mail/utils/messaging_component";
import { useUpdate } from "@mail/component_hooks/use_update/use_update";
import { useComponentToModel } from "@mail/component_hooks/use_component_to_model/use_component_to_model";
import { useRefToModel } from "@mail/component_hooks/use_ref_to_model/use_ref_to_model";
var rpc = require("web.rpc");
const { Component } = owl;
const { useRef } = owl.hooks;

export class Chatter extends Component {
  /**
   * @override
   */
  constructor(...args) {
    super(...args);
    useUpdate({ func: () => this._update() });
    useComponentToModel({
      fieldName: "component",
      modelName: "mail.chatter",
      propNameAsRecordLocalId: "chatterLocalId",
    });
    useRefToModel({
      fieldName: "threadRef",
      modelName: "mail.chatter",
      propNameAsRecordLocalId: "chatterLocalId",
      refName: "thread",
    });
    /**
     * Reference of the scroll Panel (Real scroll element). Useful to pass the Scroll element to
     * child component to handle proper scrollable element.
     */
    this._scrollPanelRef = useRef("scrollPanel");
    this.getScrollableElement = this.getScrollableElement.bind(this);
  }
  async willStart() {
    await super.willStart();
    this.users = await this.fetchUsers();
    console.log(this.users);
  }

  async fetchUsers() {
    const model = "res.users.chatter";
    const domain = [
      "&",
      ["user", "=", this.chatter.env.session.uid],
      ["model_name", "=", this.chatter.thread.model],
    ];
    const fields = [];
    const data = await this.env.services.rpc({
      model: model,
      method: "search_read",
      args: [domain, fields],
    });
    return data;
  }

  //--------------------------------------------------------------------------
  // Public
  //--------------------------------------------------------------------------

  /**
   * @returns {mail.chatter}
   */
  get chatter() {
    return (
      this.messaging &&
      this.messaging.models["mail.chatter"].get(this.props.chatterLocalId)
    );
  }
  get user_chatter_status() {
    return this.users;
  }

  /**
   * @returns {Element|undefined} Scrollable Element
   */
  getScrollableElement() {
    if (!this._scrollPanelRef.el) {
      return;
    }
    return this._scrollPanelRef.el;
  }

  //--------------------------------------------------------------------------
  // Private
  //--------------------------------------------------------------------------

  /**
   * @private
   */
  _notifyRendered() {
    this.trigger("o-chatter-rendered", {
      attachments: this.chatter.thread.allAttachments,
      thread: this.chatter.thread.localId,
    });
  }

  /**
   * @private
   */
  _update() {
    if (!this.chatter) {
      return;
    }
    if (this.chatter.thread) {
      this._notifyRendered();
    }
  }
}

Object.assign(Chatter, {
  props: {
    chatterLocalId: String,
  },
  template: "mail.Chatter",
});

registerMessagingComponent(Chatter);

original file:

/** @odoo-module **/

import { registerMessagingComponent } from '@mail/utils/messaging_component';
import { useUpdate } from '@mail/component_hooks/use_update/use_update';
import { useComponentToModel } from '@mail/component_hooks/use_component_to_model/use_component_to_model';
import { useRefToModel } from '@mail/component_hooks/use_ref_to_model/use_ref_to_model';

const { Component } = owl;
const { useRef } = owl.hooks;

export class Chatter extends Component {

    /**
     * @override
     */
    constructor(...args) {
        super(...args);
        useUpdate({ func: () => this._update() });
        useComponentToModel({ fieldName: 'component', modelName: 'mail.chatter', propNameAsRecordLocalId: 'chatterLocalId' });
        useRefToModel({ fieldName: 'threadRef', modelName: 'mail.chatter', propNameAsRecordLocalId: 'chatterLocalId', refName: 'thread' });
        /**
         * Reference of the scroll Panel (Real scroll element). Useful to pass the Scroll element to
         * child component to handle proper scrollable element.
         */
        this._scrollPanelRef = useRef('scrollPanel');
        this.getScrollableElement = this.getScrollableElement.bind(this);
    }

    //--------------------------------------------------------------------------
    // Public
    //--------------------------------------------------------------------------

    /**
     * @returns {mail.chatter}
     */
    get chatter() {
        return this.messaging && this.messaging.models['mail.chatter'].get(this.props.chatterLocalId);
    }

    /**
     * @returns {Element|undefined} Scrollable Element
     */
    getScrollableElement() {
        if (!this._scrollPanelRef.el) {
            return;
        }
        return this._scrollPanelRef.el;
    }

    //--------------------------------------------------------------------------
    // Private
    //--------------------------------------------------------------------------

    /**
     * @private
     */
    _notifyRendered() {
        this.trigger('o-chatter-rendered', {
            attachments: this.chatter.thread.allAttachments,
            thread: this.chatter.thread.localId,
        });
    }

    /**
     * @private
     */
    _update() {
        if (!this.chatter) {
            return;
        }
        if (this.chatter.thread) {
            this._notifyRendered();
        }
    }

}

Object.assign(Chatter, {
    props: {
        chatterLocalId: String,
    },
    template: 'mail.Chatter',
});

registerMessagingComponent(Chatter);

I try to overwrite adding to manifest.py:

"assets": {
        "web.assets_backend": [
            "freshdesk-connector/static/src/components/chatter/chatter.js",
        ],

but have an error :

UncaughtPromiseError
Uncaught Promise > There already is a registered component with the name "Chatter"

I try also to use patch but this not work for me (i think i use this bad, because I'm 'dummy' from .js).

So the main questions is:

  1. Is it possible to overwrite whole .js file, if yes how to do this.
  2. How to use patch method to overwrite Chatter component ?
1

There are 1 answers

1
Kenly On BEST ANSWER

You can unregister the old chat component before registering the new Chatter

Example:


import { Chatter as OldChatter } from "@mail/components/chatter/chatter";
import { registerMessagingComponent, unregisterMessagingComponent } from "@mail/utils/messaging_component";

// ...

unregisterMessagingComponent(OldChatter);
registerMessagingComponent(Chatter);