changeset 0f2f964ccb27 in sao:default
details: https://hg.tryton.org/sao?cmd=changeset;node=0f2f964ccb27
description:
        Add link button

        issue9051
        review280841002
diffstat:

 CHANGELOG        |    1 +
 src/board.js     |    7 ++-
 src/model.js     |    2 +
 src/sao.less     |    3 +
 src/tab.js       |    1 +
 src/view/form.js |  155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 168 insertions(+), 1 deletions(-)

diffs (249 lines):

diff -r 505aa0836b25 -r 0f2f964ccb27 CHANGELOG
--- a/CHANGELOG Sun Apr 12 23:21:08 2020 +0200
+++ b/CHANGELOG Mon Apr 13 12:21:55 2020 +0200
@@ -1,3 +1,4 @@
+* Support link button on form
 * Add URL for the current export
 * Add option to export listed records
 * Set treeview header sticky on top
diff -r 505aa0836b25 -r 0f2f964ccb27 src/board.js
--- a/src/board.js      Sun Apr 12 23:21:08 2020 +0200
+++ b/src/board.js      Mon Apr 13 12:21:55 2020 +0200
@@ -34,6 +34,7 @@
 
             this.context = context;
             this.actions = [];
+            this.state_widgets = [];
             this.el = jQuery('<div/>', {
                 'class': 'board'
             });
@@ -46,9 +47,13 @@
             this.actions_prms = jQuery.when.apply(jQuery, actions_prms);
         },
         reload: function() {
-            for (var i = 0; i < this.actions.length; i++) {
+            var i;
+            for (i = 0; i < this.actions.length; i++) {
                 this.actions[i].display();
             }
+            for (i = 0; i < this.state_widgets.length; i++) {
+                this.state_widgets[i].set_state(null);
+            }
         }
     });
 
diff -r 505aa0836b25 -r 0f2f964ccb27 src/model.js
--- a/src/model.js      Sun Apr 12 23:21:08 2020 +0200
+++ b/src/model.js      Mon Apr 13 12:21:55 2020 +0200
@@ -544,6 +544,7 @@
             this._timestamp = null;
             this.resources = null;
             this.button_clicks = {};
+            this.links_counts = {};
             this.state_attrs = {};
             this.autocompletion = {};
             this.exception = false;
@@ -1242,6 +1243,7 @@
             this._changed = {};
             this._timestamp = null;
             this.button_clicks = {};
+            this.links_counts = {};
         },
         _check_load: function(fields) {
             if (!this.get_loaded(fields)) {
diff -r 505aa0836b25 -r 0f2f964ccb27 src/sao.less
--- a/src/sao.less      Sun Apr 12 23:21:08 2020 +0200
+++ b/src/sao.less      Mon Apr 13 12:21:55 2020 +0200
@@ -621,6 +621,9 @@
         text-align: left;
         text-align: start;
     }
+    .form-link {
+        display: none;
+    }
 }
 
 @media screen and (max-width: @screen-xs-max) {
diff -r 505aa0836b25 -r 0f2f964ccb27 src/tab.js
--- a/src/tab.js        Sun Apr 12 23:21:08 2020 +0200
+++ b/src/tab.js        Mon Apr 13 12:21:55 2020 +0200
@@ -1351,6 +1351,7 @@
                         action = this.board.actions[i];
                         action.screen.tab = this;
                     }
+                    this.board.reload();
                 }.bind(this));
                 this.content.append(this.board.el);
             }.bind(this));
diff -r 505aa0836b25 -r 0f2f964ccb27 src/view/form.js
--- a/src/view/form.js  Sun Apr 12 23:21:08 2020 +0200
+++ b/src/view/form.js  Mon Apr 13 12:21:55 2020 +0200
@@ -95,6 +95,11 @@
             this.view.state_widgets.push(button);
             this.container.add(button, attributes);
         },
+        _parse_link: function(node, attributes) {
+            var link = new Sao.View.Form.Link(attributes);
+            this.view.state_widgets.push(link);
+            this.container.add(link, attributes);
+        },
         _parse_image: function(node, attributes) {
             var image = new Sao.View.Form.Image_(attributes);
             this.view.state_widgets.push(image);
@@ -884,6 +889,156 @@
         }
     });
 
+    Sao.View.Form.Link = Sao.class_(Sao.View.Form.StateWidget, {
+        class_: 'form-link',
+        init: function(attributes) {
+            Sao.View.Form.Link._super.init.call(this, attributes);
+            this.el = jQuery('<button/>', {
+                'class': this.class_ + ' btn btn-link',
+            });
+            if (attributes.icon) {
+                var img = jQuery('<img/>', {
+                    'class': 'icon',
+                }).prependTo(this.el);
+                Sao.common.ICONFACTORY.get_icon_url(attributes.icon)
+                    .done(function(url) {
+                        img.attr('src', url);
+                    });
+            }
+            this.label = jQuery('<div/>').appendTo(this.el);
+            this._current = null;
+        },
+        get action_id() {
+            return parseInt(this.attributes.id, 10);
+        },
+        set_state: function(record) {
+            Sao.View.Form.Link._super.set_state.call(this, record);
+            if (this.el.css('display') == 'none') {
+                return;
+            }
+            var data = {},
+                context = {},
+                pyson_ctx = {};
+            if (record) {
+                data = {
+                    model: record.model.name,
+                    id: record.id,
+                    ids: [record.id],
+                };
+                context = record.get_context();
+                pyson_ctx = {
+                    active_model: record.model.name,
+                    active_id: record.id,
+                    active_ids: [record.id],
+                };
+                this._current = record.id;
+            } else {
+                this._current = null;
+            }
+            pyson_ctx.context = context;
+            this.el.off('click');
+            this.el.click([data, context], this.clicked.bind(this));
+            var action = Sao.rpc({
+                'method': 'model.ir.action.get_action_value',
+                'params': [this.action_id, context],
+            }, Sao.Session.current_session, false);
+            this.label.text(action.rec_name);
+
+            var decoder = new Sao.PYSON.Decoder(pyson_ctx);
+            var domain = decoder.decode(action.pyson_domain);
+            if (action.pyson_search_value) {
+                domain = [domain, decoder.decode(action.pyson_search_value)];
+            }
+            var tab_domains = action.domains
+                .filter(function(d) {
+                    return d[2];
+                }).map(function(d) {
+                    var name = d[0],
+                        domain = d[1];
+                    return [name, decoder.decode(domain)];
+                });
+            var counter;
+            if (record && record.links_counts[this.action_id]) {
+                counter = record.links_counts[this.action_id];
+                this.set_label(action.rec_name, tab_domains, counter);
+            } else {
+                if (tab_domains.length) {
+                    counter = tab_domains.map(function() {
+                        return 0;
+                    });
+                } else {
+                    counter = [0];
+                }
+                if (record) {
+                    record.links_counts[this.action_id] = counter;
+                }
+                var current = this._current;
+                if (tab_domains.length) {
+                    tab_domains.map(function(d, i) {
+                        var tab_domain = d[1];
+                        Sao.rpc({
+                            'method': (
+                                'model.' + action.res_model + '.search_count'),
+                            'params': [
+                                ['AND', domain, tab_domain], context],
+                        }, Sao.Session.current_session).then(function(value) {
+                            this._set_count(
+                                value, i, current, counter,
+                                action.rec_name, tab_domains);
+                        }.bind(this));
+                    }, this);
+                } else {
+                    Sao.rpc({
+                        'method': (
+                            'model.' + action.res_model + '.search_count'),
+                        'params': [domain, context],
+                    }, Sao.Session.current_session).then(function(value) {
+                        this._set_count(
+                            value, 0, current, counter,
+                            action.rec_name, tab_domains);
+                    }.bind(this));
+                }
+            }
+        },
+        _set_count: function(value, idx, current, counter, name, domains) {
+            if (current != this._current) {
+                return;
+            }
+            counter[idx] = value;
+            this.set_label(name, domains, counter);
+        },
+        set_label: function(name, domains, counter) {
+            this.label.text(name);
+            if (domains.length) {
+                domains.map(function(d, i) {
+                    var name = d[0];
+                    this.label.append(name + ' ');
+                    jQuery('<span/>', {
+                        'class': 'badge',
+                    }).text(counter[i]).appendTo(this.label);
+                }, this);
+            } else {
+                this.label.append(' ');
+                jQuery('<span/>', {
+                    'class': 'badge',
+                }).text(counter[0]).appendTo(this.label);
+            }
+            if (this.attributes.empty === 'hide') {
+                var non_empty = counter.filter(function(number) {
+                    return number != 0;
+                });
+                if (non_empty.length) {
+                    this.el.show();
+                } else {
+                    this.el.hide();
+                }
+            }
+        },
+        clicked: function(evt) {
+            Sao.Action.execute(this.action_id, evt.data[0], evt.data[1], true);
+        },
+    });
+
     Sao.View.Form.Image_ = Sao.class_(Sao.View.Form.StateWidget, {
         class_: 'form-image_',
         init: function(attributes) {

Reply via email to