LittleMountainPrinting / one2many_owl_renderer

0 stars 0 forks source link

Widget cannot save/commit changes #1

Open PhilDL opened 1 year ago

PhilDL commented 1 year ago

Hi 👋

This is a complicated problem but we could simplify it: You are using an OWL Renderer while the original Renderers for the FieldX2Many implementations are legacy JS renderers (the old way of writing Odoo JS).

For example, some hardcoded logic is inside the original Odoo FieldX2Many implementation.

You are extending FieldOne2Many that is extending FieldX2Many. This FieldX2Many class contains the logic that handles if changes should be "committed" :

    /**
     * A x2m field can only be saved if it finished the edition of all its rows.
     * On parent view saving, we have to ask the x2m fields to commit their
     * changes, that is confirming the save of the in-edition row or asking the
     * user if he wants to discard it if necessary.
     *
     * @override
     * @returns {Promise}
     */
    commitChanges: function () {
        // Here you will have multiple problems, first your "viewType" is undefined and then you don't have the method
        // getEditableRecordID, you also don't have commitChanges
        var self = this;
        var inEditionRecordID =
            this.renderer &&
            this.renderer.viewType === "list" &&
            this.renderer.getEditableRecordID();
        if (inEditionRecordID) {
            return this.renderer.commitChanges(inEditionRecordID).then(function () {
                return self._saveLine(inEditionRecordID);
            });
        }
        return this._super.apply(this, arguments);
    },

You can see the original code in odoo/addons/web/static/src/js/fields/relational_fields.js, line 1159

So you actually have more custom logic to write to be able to extend FieldOne2Many, from your module this.renderer is RendererWrapper that wraps around your OWL component. That's the way Odoo deals with legacy JS using new OWL widgets. So you will have a lot of methods to create manually to have a logic similar to FieldOne2Many.

I think you have 2 ways of tackling this big problem:

Anyway, both paths will require some work. I am sorry I can't help more than that but I don't have too much availability. I will keep a look here if you have any other questions.

denris commented 1 year ago

Thanks, you basically confirmed my suspicions, but I wanted to make sure I wasn't missing something/going down the wrong path. :slightly_smiling_face: (I am a fairly experienced Odoo backend developer, but am just starting to get into the JS side of things) I did a fair amount of digging myself and thought that that is the method I need to get to trigger. However, because of the RendererWrapper I could not get it to work. We would like to move to v16 in the not too distant future so I was hoping it would be less work to port, when the time comes, if I used OWL.

I actually started on the Legacy renderer route shortly before I emailed you because I was starting to think that may just be my best option.

My very first attempt was to acutally make an OWL widget...however, in v14 they don't have a pre-made widget for X2manys and that seems like a pile of work to replicate from scratch.

As much as I would like to go with OWL, at this point I am thinking a legacy renderer is probably the lest complex...would you agree?

PhilDL commented 1 year ago

Yes for your specific case I agree, the legacy renderer is the less complex option. And since your widget seems to have behavior similarities to the X2manys you will benefit from that extension.

Odoo 14 came out in a weird state for the JavaScript land with these backward and forward compatibility layers, you will have an easier time in Odoo 16.