• odoo14在tree、kanban视图上添加dashboard


    效果图:

    实现代码:js:view的类型原来1个js给拆分成了4个: view, controller, renderer, model

    1、viewAbstractView的子类,这是工厂类:类需要解析 arch字段并设置其它3个类

    2、Renderer 渲染器,来自 AbstractRenderer:负责在用户界面中展示数据;

    3、Controller一个控制器 (来看AbstractController):用于协调、与网页客户端对话

    4、Model一个模型 (来自 AbstractModel):用于和服务端对话、加载数据并处理数据

    步骤:一、二、三、四案例

    一、MVCR:

    var MapController = AbstractController.extend({});
    var MapRenderer = AbstractRenderer.extend({});
    var MapModel = AbstractModel.extend({});

    var MapView = AbstractView.extend({
      config: {
        Model: MapModel,
        Controller: MapController,
        Renderer: MapRenderer,
      },
    });

    二、告知网页客户端视图名称和实际类之间的映射。
    var viewRegistry = require('web.view_registry');
    viewRegistry.add('helpdesk_dashboard', HelpdeskDashboardView);

    三、现在我们需要告知网页客户端指定的 ir.ui.view需要使用我们的新类。注意这是一个网页客户端的具体考虑。

    从服务端的视角来看,我们还是对应看板视图。这么做的相应方式是通过对框架的根节点使用特殊属性js_class

    <record id="helpdesk_team_view_kanban" model="ir.ui.view" >
    ...
      <field name="arch" type="xml">
      <kanban js_class="helpdesk_dashboard">
    ...
    </kanban>
    </field>
    </record>

    案例:

    odoo.define('purchase.dashboard', function (require) {
    "use strict";
    
    /**
     * This file defines the Purchase Dashboard view (alongside its renderer, model
     * and controller). This Dashboard is added to the top of list and kanban Purchase
     * views, it extends both views with essentially the same code except for
     * _onDashboardActionClicked function so we can apply filters without changing our
     * current view.
     */
    
    var core = require('web.core');

    //这里是列表视图上的扩展:导入的模块
    var ListController = require('web.ListController'); var ListModel = require('web.ListModel'); var ListRenderer = require('web.ListRenderer'); var ListView = require('web.ListView');

    //这里是kanban视图上的扩展:
    var KanbanController = require('web.KanbanController'); var KanbanModel = require('web.KanbanModel'); var KanbanRenderer = require('web.KanbanRenderer'); var KanbanView = require('web.KanbanView');
    var SampleServer = require('web.SampleServer');
    //注册模块
    var view_registry = require('web.view_registry'); var QWeb = core.qweb; // Add mock of method 'retrieve_dashboard' in SampleServer, so that we can have // the sample data in empty purchase kanban and list view let dashboardValues; SampleServer.mockRegistry.add('purchase.order/retrieve_dashboard', () => { return Object.assign({}, dashboardValues); }); //-------------------------------------------------------------------------- // List View //-------------------------------------------------------------------------- //渲染renderer var PurchaseListDashboardRenderer = ListRenderer.extend({ events:_.extend({}, ListRenderer.prototype.events, { 'click .o_dashboard_action': '_onDashboardActionClicked', }), /** * @override * @private * @returns {Promise} */ _renderView: function () { var self = this; return this._super.apply(this, arguments).then(function () { var values = self.state.dashboardValues; var purchase_dashboard = QWeb.render('purchase.PurchaseDashboard', { values: values, }); self.$el.prepend(purchase_dashboard); }); }, /** * @private * @param {MouseEvent} */ _onDashboardActionClicked: function (e) { e.preventDefault(); var $action = $(e.currentTarget); this.trigger_up('dashboard_open_action', { action_name: $action.attr('name')+"_list", action_context: $action.attr('context'), }); }, });

    //模型 model
    var PurchaseListDashboardModel = ListModel.extend({ /** * @override */ init: function () { this.dashboardValues = {}; this._super.apply(this, arguments); }, /** * @override */ __get: function (localID) { var result = this._super.apply(this, arguments); if (_.isObject(result)) { result.dashboardValues = this.dashboardValues[localID]; } return result; }, /** * @override * @returns {Promise} */ __load: function () { return this._loadDashboard(this._super.apply(this, arguments)); }, /** * @override * @returns {Promise} */ __reload: function () { return this._loadDashboard(this._super.apply(this, arguments)); }, /** * @private * @param {Promise} super_def a promise that resolves with a dataPoint id * @returns {Promise -> string} resolves to the dataPoint id */ _loadDashboard: function (super_def) { var self = this; var dashboard_def = this._rpc({ model: 'purchase.order', method: 'retrieve_dashboard', }); return Promise.all([super_def, dashboard_def]).then(function(results) { var id = results[0]; dashboardValues = results[1]; self.dashboardValues[id] = dashboardValues; return id; }); }, });
    //控制器:controller
    var PurchaseListDashboardController = ListController.extend({ custom_events: _.extend({}, ListController.prototype.custom_events, { dashboard_open_action: '_onDashboardOpenAction', }), /** * @private * @param {OdooEvent} e */ _onDashboardOpenAction: function (e) { return this.do_action(e.data.action_name, {additional_context: JSON.parse(e.data.action_context)}); }, });
    //视图 view
    var PurchaseListDashboardView = ListView.extend({ config: _.extend({}, ListView.prototype.config, { Model: PurchaseListDashboardModel, Renderer: PurchaseListDashboardRenderer, Controller: PurchaseListDashboardController, }), });




    //-------------------------------------------------------------------------- // Kanban View //-------------------------------------------------------------------------- var PurchaseKanbanDashboardRenderer = KanbanRenderer.extend({ events:_.extend({}, KanbanRenderer.prototype.events, { 'click .o_dashboard_action': '_onDashboardActionClicked', }), /** * @override * @private * @returns {Promise} */ _render: function () { var self = this; return this._super.apply(this, arguments).then(function () { var values = self.state.dashboardValues; var purchase_dashboard = QWeb.render('purchase.PurchaseDashboard', { values: values, }); self.$el.prepend(purchase_dashboard); }); }, /** * @private * @param {MouseEvent} */ _onDashboardActionClicked: function (e) { e.preventDefault(); var $action = $(e.currentTarget); this.trigger_up('dashboard_open_action', { action_name: $action.attr('name')+"_kanban", action_context: $action.attr('context'), }); }, }); var = KanbanModel.extend({ /** * @override */ init: function () { this.dashboardValues = {}; this._super.apply(this, arguments); }, /** * @override */ __get: function (localID) { var result = this._super.apply(this, arguments); if (_.isObject(result)) { result.dashboardValues = this.dashboardValues[localID]; } return result; }, /** * @override * @returns {Promise} */ __load: function () { return this._loadDashboard(this._super.apply(this, arguments)); }, /** * @override * @returns {Promise} */ __reload: function () { return this._loadDashboard(this._super.apply(this, arguments)); }, /** * @private * @param {Promise} super_def a promise that resolves with a dataPoint id * @returns {Promise -> string} resolves to the dataPoint id */ _loadDashboard: function (super_def) { var self = this; var dashboard_def = this._rpc({ model: 'purchase.order', method: 'retrieve_dashboard', }); return Promise.all([super_def, dashboard_def]).then(function(results) { var id = results[0]; dashboardValues = results[1]; self.dashboardValues[id] = dashboardValues; return id; }); }, }); var PurchaseKanbanDashboardController = KanbanController.extend({ custom_events: _.extend({}, KanbanController.prototype.custom_events, { dashboard_open_action: '_onDashboardOpenAction', }), /** * @private * @param {OdooEvent} e */ _onDashboardOpenAction: function (e) { return this.do_action(e.data.action_name, {additional_context: JSON.parse(e.data.action_context)}); }, });
    通过VIEW来设置它
    var PurchaseKanbanDashboardView = KanbanView.extend({ config: _.extend({}, KanbanView.prototype.config, { Model: PurchaseKanbanDashboardModel, Renderer: PurchaseKanbanDashboardRenderer, Controller: PurchaseKanbanDashboardController, }), });
    //视图类型和实际类之间的映射需要进行更新 view_registry.add(
    'purchase_list_dashboard', PurchaseListDashboardView); view_registry.add('purchase_kanban_dashboard', PurchaseKanbanDashboardView); return { PurchaseListDashboardModel: PurchaseListDashboardModel, PurchaseListDashboardRenderer: PurchaseListDashboardRenderer, PurchaseListDashboardController: PurchaseListDashboardController, PurchaseKanbanDashboardModel: PurchaseKanbanDashboardModel, PurchaseKanbanDashboardRenderer: PurchaseKanbanDashboardRenderer, PurchaseKanbanDashboardController: PurchaseKanbanDashboardController }; });

    Dashboard的page的xml

    <?xml version="1.0" encoding="UTF-8"?>
    <templates>
        <!-- This template is for a table at the top of purchase views that shows some KPIs. -->
        <t t-name="purchase.PurchaseDashboard">
            <div class="o_purchase_dashboard container">
            <div class="row">
                <div class="col-sm-5">
                <table class="table table-sm">
                    <!-- thead needed to avoid list view rendering error for some reason -->
                    <thead>
                        <tr>
                        <!-- can't use th tag due to list rendering error when no values in list... -->
                            <td class="o_text">
                                <div>All RFQs</div>
                            </td>
    <td class="o_main o_dashboard_action" title="All Draft RFQs" name="purchase.purchase_action_dashboard" context='{"search_default_draft_rfqs": true}'> <a href="#"><t t-esc="values['all_to_send']"/><br/>To Send</a> </td> <td class="o_main o_dashboard_action" title="All Waiting RFQs" name="purchase.purchase_action_dashboard" context='{"search_default_waiting_rfqs": true}'> <a href="#"><t t-esc="values['all_waiting']"/><br/>Waiting</a> </td> <td class="o_main o_dashboard_action" title="All Late RFQs" name="purchase.purchase_action_dashboard" context='{"search_default_late_rfqs": true}'> <a href="#"><t t-esc="values['all_late']"/><br/>Late</a> </td> </tr> </thead> <tbody> <tr> <td class="o_text"> <div>My RFQs</div> </td> <td class="o_main o_dashboard_action" title="My Draft RFQs" name="purchase.purchase_action_dashboard" context='{"search_default_draft_rfqs": true, "search_default_my_purchases": true}'> <a href="#"><t t-esc="values['my_to_send']"/></a> </td> <td class="o_main o_dashboard_action" title="My Waiting RFQs" name="purchase.purchase_action_dashboard" context='{"search_default_waiting_rfqs": true, "search_default_my_purchases": true}'> <a href="#"><t t-esc="values['my_waiting']"/></a> </td> <td class="o_main o_dashboard_action" title="My Late RFQs" name="purchase.purchase_action_dashboard" context='{"search_default_late_rfqs": true, "search_default_my_purchases": true}'> <a href="#"><t t-esc="values['my_late']"/></a> </td> </tr> </tbody> </table></div> <div class="col-sm-7"> <table class="table table-sm"> <!-- thead needed to avoid list view rendering error for some reason --> <thead> <tr> <!-- can't use th tag due to list rendering error when no values in list... --> <td class="o_text">Avg Order Value (<t t-esc="values['company_currency_symbol']"/>)</td> <td><span><t t-esc="values['all_avg_order_value']"/></span></td> <td class="o_text">Purchased Last 7 Days (<t t-esc="values['company_currency_symbol']"/>)</td> <td><span><t t-esc="values['all_total_last_7_days']"/></span></td> </tr> </thead> <tbody> <tr> <td class="o_text">Lead Time to Purchase</td> <td><span><t t-esc="values['all_avg_days_to_purchase']"/> &#160;Days</span></td> <td class="o_text">RFQs Sent Last 7 Days</td> <td><span><t t-esc="values['all_sent_rfqs']"/></span></td> </tr> </tbody> </table></div> </div></div> </t> </templates>

    导入js

    <?xml version="1.0"?>
    <odoo>
        <template id="assets_backend" name="purchase assets" inherit_id="web.assets_backend">
            <xpath expr="." position="inside">
                <link rel="stylesheet" type="text/scss" href="/purchase/static/src/scss/purchase.scss"/>
                <script type="text/javascript" src="/purchase/static/src/js/purchase_dashboard.js"></script>
            </xpath>
           
        </template>
    
    
    </odoo>

    最后引用:

                    <kanban class="o_kanban_mobile" js_class="purchase_kanban_dashboard" sample="1"></kanban>


              <tree  class="o_kanban_mobile" js_class="purchase_kanban_dashboard" sample="1"></tree>
     
    心有猛虎,细嗅蔷薇
  • 相关阅读:
    连通域搜索
    识别深色浅色
    新年,博客搬家了!!!
    C++11 —— 使用 thread 实现线程池
    自己实现的网络字节序转换函数
    GUI 编程 —— QT 的 QSlider 鼠标点击定位问题
    单生产者/单消费者 的 FIFO 无锁队列
    用模板类特化的方式实现工厂模式
    C++11 —— 简易的旋转锁类
    C++11 —— 获取 tuple 参数列表中指定数据类型的索引位置
  • 原文地址:https://www.cnblogs.com/1314520xh/p/14533780.html
Copyright © 2020-2023  润新知