Přejít na obsah
Menu
You need to be registered to interact with the community.
This question has been flagged

Hello,


I'm currently working on version 18 of Odoo. I've only been using the tool for a few weeks. I discovered the ‘Binary’ field which allows you to import files. Once a file has been loaded, several icons appear. One of them is a bin for deleting the file. I'd like to have a dialogue box asking for confirmation that I'm sure I want to delete the file. I've managed to do this in the source code by modifying it. But to be cleaner and more modular, it would be better to have a custom module that would allow me to do this. Except that no matter how hard I try, nothing works. I don't necessarily get errors. When I do have errors, I manage to correct them. In addition to this, I use another module called ‘Binary Field Attachment Preview’ from Pysquad Informatics LLP which allows me to view the files. I don't know whether there might be some sort of conflict between the modules.


Thanks for your help!



Here's the source code modified as I want it, with confirmation:

import { registry } from "@web/core/registry";

import { useService } from "@web/core/utils/hooks";

import { isBinarySize, toBase64Length } from "@web/core/utils/binary";

import { download } from "@web/core/network/download";

import { standardFieldProps } from "../standard_field_props";

import { FileUploader } from "../file_handler";

import { _t } from "@web/core/l10n/translation";

import { Component, xml } from "@odoo/owl";


import { Dialog } from "@web/core/dialog/dialog";


export const MAX_FILENAME_SIZE_BYTES = 0xFF;  // filenames do not exceed 255 bytes on Linux/Windows/MacOS


export class BinaryField extends Component {

    static template = "web.BinaryField";

    static components = {

        FileUploader,

    };

    static props = {

        ...standardFieldProps,

        acceptedFileExtensions: { type: String, optional: true },

        fileNameField: { type: String, optional: true },

    };

    static defaultProps = {

        acceptedFileExtensions: "*",

    };


    setup() {

        this.notification = useService("notification");

        this.dialog = useService("dialog");

    }


    get fileName() {

        return (

            this.props.record.data[this.props.fileNameField] ||

            this.props.record.data[this.props.name] ||

            ""

        ).slice(0, toBase64Length(MAX_FILENAME_SIZE_BYTES));

    }


    update({ data, name }) {

        const { fileNameField, record } = this.props;

        const changes = { [this.props.name]: data || false };

        if (fileNameField in record.fields && record.data[fileNameField] !== name) {

            changes[fileNameField] = name || '';

        }

        return this.props.record.update(changes);

    }


    getDownloadData() {

        return {

            model: this.props.record.resModel,

            id: this.props.record.resId,

            field: this.props.name,

            filename_field: this.fileName,

            filename: this.fileName || "",

            download: true,

            data: isBinarySize(this.props.record.data[this.props.name])

                ? null

                : this.props.record.data[this.props.name],

        };

    }


    onClickDelete() {

        this.dialog.add(ConfirmDeleteDialog, {

            onConfirmCallback: () => this.update({}),

        });        

    }    


    async onFileDownload() {

        await download({

            data: this.getDownloadData(),

            url: "/web/content",

        });

    }

}


export class ListBinaryField extends BinaryField {

    static template = "web.ListBinaryField";

}


export const binaryField = {

    component: BinaryField,

    displayName: _t("File"),

    supportedOptions: [

        {

            label: _t("Accepted file extensions"),

            name: "accepted_file_extensions",

            type: "string",

        },

    ],

    supportedTypes: ["binary"],

    extractProps: ({ attrs, options }) => ({

        acceptedFileExtensions: options.accepted_file_extensions,

        fileNameField: attrs.filename,

    }),

};


export const listBinaryField = {

    ...binaryField,

    component: ListBinaryField,

};


class ConfirmDeleteDialog extends Component {

    static template = xml`

        <Dialog title="'Confirmation de suppression'">

            <div>

                Êtes-vous sûr de vouloir supprimer ce fichier ?

            </div>

            <t t-set-slot="footer">

                <button class="btn btn-danger" t-on-click="onConfirm">Supprimer</button>

                <button class="btn btn-secondary" t-on-click="props.close">Annuler</button>

            </t>

        </Dialog>

    `;

    static components = { Dialog };

    static props = ['close', 'onConfirmCallback'];


    onConfirm() {

        this.props.onConfirmCallback(); // Appel du callback

        this.props.close(); // Fermeture manuelle du dialog

    }

}




registry.category("fields").add("binary", binaryField);

registry.category("fields").add("list.binary", listBinaryField);



<?xml version="1.0" encoding="UTF-8"?>

<templates xml:space="preserve">


    <t t-name="web.BinaryField">

        <t t-if="!props.readonly">

            <t t-if="props.record.data[props.name]">

                <div class="w-100 d-inline-flex gap-1">

                    <FileUploader

                        acceptedFileExtensions="props.acceptedFileExtensions"

                        onUploaded.bind="update"

                    >

                        <t name="download" t-if="props.record.resId and !props.record.dirty">

                            <button

                                class="btn btn-link btn-sm lh-1 fa fa-download o_download_file_button"

                                data-tooltip="Download"

                                aria-label="Download"

                                t-on-click="onFileDownload"

                            >

                            </button>

                        </t>

                        <t t-set-slot="toggler">

                            <input type="text" class="o_input" t-att-value="fileName" readonly="readonly" />

                            <button

                                class="btn btn-link btn-sm lh-1 fa fa-pencil o_select_file_button"

                                data-tooltip="Edit"

                                aria-label="Edit"

                            >

                            </button>

                        </t>

                        <button

                            class="btn btn-link btn-sm lh-1 fa fa-trash o_clear_file_button"

                            data-tooltip="Clear"

                            aria-label="Clear"

                            t-on-click="onClickDelete"

                        />

                        <!-- </button> -->

                    </FileUploader>

                </div>

            </t>

            <t t-else="">

                <label class="o_select_file_button btn btn-primary">

                    <FileUploader

                        acceptedFileExtensions="props.acceptedFileExtensions"

                        onUploaded.bind="update"

                    >

                        <t t-set-slot="toggler">

                            Upload your file

                        </t>

                    </FileUploader>

                </label>

            </t>

        </t>

        <t t-elif="props.record.resId and props.record.data[props.name]">

            <a class="o_form_uri" href="#" t-on-click.prevent="onFileDownload">

                <span class="fa fa-download me-2" />

                <t t-if="fileName" t-esc="fileName" />

            </a>

        </t>

    </t>


    <t t-name="web.ListBinaryField" t-inherit="web.BinaryField">

        <xpath expr="//label[hasclass('o_select_file_button')]" position="replace">

            <label class="o_select_file_button btn btn-sm btn-link p-0">

                <FileUploader

                    acceptedFileExtensions="props.acceptedFileExtensions"

                    onUploaded.bind="update"

                >

                    <t t-set-slot="toggler">

                        <i class="fa fa-upload fa-fw"/> Upload your file

                    </t>

                </FileUploader>

            </label>

        </xpath>

    </t>


</templates>



Avatar
Zrušit
Nejlepší odpověď

Hai,

I have made a custom widget for this purpose. In addition to this it consist of additional feature too. Please check it out. https://apps.odoo.com/apps/modules/16.0/cbu_advance_m2m_binary_widget

Avatar
Zrušit
Autor Nejlepší odpověď

I succeeded by using the Odoo JS patch which modifies the basic widget.

Avatar
Zrušit
Related Posts Odpovědi Zobrazení Aktivita
1
kvě 25
539
2
čvn 25
451
2
úno 23
9143
0
čvc 16
4460
2
zář 22
5191