changeset 6fa1d70fa8f2 in sao:default
details: https://hg.tryton.org/sao?cmd=changeset&node=6fa1d70fa8f2
description:
        Add expander on tree to fold or unfold selected rows

        issue10367
        review362441002
diffstat:

 CHANGELOG                     |    1 +
 images/tryton-unfold-less.svg |    1 +
 images/tryton-unfold-more.svg |    1 +
 src/view/tree.js              |  102 ++++++++++++++++++++++++++++++++++++-----
 4 files changed, 92 insertions(+), 13 deletions(-)

diffs (191 lines):

diff -r 3657026d8d01 -r 6fa1d70fa8f2 CHANGELOG
--- a/CHANGELOG Sun Sep 19 00:06:54 2021 +0200
+++ b/CHANGELOG Sun Sep 19 00:28:04 2021 +0200
@@ -1,3 +1,4 @@
+* Add expander on tree to fold or unfold selected rows
 * Support monetary and symbol field attributes
 * Support digits from relation field
 * Add accesskey to widgets and buttons
diff -r 3657026d8d01 -r 6fa1d70fa8f2 images/tryton-unfold-less.svg
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/images/tryton-unfold-less.svg     Sun Sep 19 00:28:04 2021 +0200
@@ -0,0 +1,1 @@
+<svg xmlns="http://www.w3.org/2000/svg"; height="24px" viewBox="0 0 24 24" 
width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M7.41 
18.59L8.83 20 12 16.83 15.17 20l1.41-1.41L12 14l-4.59 4.59zm9.18-13.18L15.17 4 
12 7.17 8.83 4 7.41 5.41 12 10l4.59-4.59z"/></svg>
\ No newline at end of file
diff -r 3657026d8d01 -r 6fa1d70fa8f2 images/tryton-unfold-more.svg
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/images/tryton-unfold-more.svg     Sun Sep 19 00:28:04 2021 +0200
@@ -0,0 +1,1 @@
+<svg xmlns="http://www.w3.org/2000/svg"; height="24px" viewBox="0 0 24 24" 
width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 
5.83L15.17 9l1.41-1.41L12 3 7.41 7.59 8.83 9 12 5.83zm0 12.34L8.83 15l-1.41 
1.41L12 21l4.59-4.59L15.17 15 12 18.17z"/></svg>
\ No newline at end of file
diff -r 3657026d8d01 -r 6fa1d70fa8f2 src/view/tree.js
--- a/src/view/tree.js  Sun Sep 19 00:06:54 2021 +0200
+++ b/src/view/tree.js  Sun Sep 19 00:28:04 2021 +0200
@@ -202,13 +202,30 @@
                 this.table.append(this.tfoot);
             }
 
-            this.columns.forEach(function(column) {
+            this.columns.forEach(function(column, i) {
                 col = jQuery('<col/>', {
                     'class': column.attributes.widget,
                 }).appendTo(this.colgroup);
                 th = jQuery('<th/>', {
                     'class': column.attributes.widget,
                 });
+                if ((i === 0) && this.children_field) {
+                    this.expander = jQuery('<img/>', {
+                        'tabindex': 0,
+                        'class': 'icon',
+                    });
+                    this.update_expander('more');
+                    this.expander.on('click keypress',
+                        Sao.common.click_press(this.unfold.bind(this)));
+                    Sao.common.ICONFACTORY.get_icon_url(
+                        'tryton-unfold-' + this.expander.action)
+                        .then(function(url) {
+                            this.expander.attr('src', url);
+                        }.bind(this));
+                    th.append(jQuery('<span>', {
+                        'class': 'expander',
+                    }).append(this.expander));
+                }
                 var label = jQuery('<label/>')
                     .text(column.attributes.string)
                     .attr('title', column.attributes.string);
@@ -264,6 +281,49 @@
             return (parseInt(this.attributes.editable || 0, 10) &&
                 !this.screen.attributes.readonly);
         },
+        unfold: function() {
+            if (!this.expander) {
+                return;
+            }
+            var action, unfold;
+            if (this.expander.action == 'more') {
+                unfold = function(row) {
+                    if (row.is_selected() && !row.is_expanded()) {
+                        row.expand_row();
+                    }
+                    row.rows.forEach(unfold);
+                };
+                action = 'less';
+            } else {
+                unfold = function(row) {
+                    if (row.is_selected() && row.is_expanded()) {
+                        row.collapse_row();
+                    }
+                    row.rows.forEach(unfold);
+                };
+                action = 'more';
+            }
+            this.rows.forEach(unfold);
+            this.update_expander(action);
+        },
+        update_expander: function(action) {
+            if (!this.expander) {
+                return;
+            }
+            if (action) {
+                this.expander.action = action;
+            }
+            Sao.common.ICONFACTORY.get_icon_url(
+                'tryton-unfold-' + this.expander.action)
+                .then(function(url) {
+                    this.expander.attr('src', url);
+                }.bind(this));
+            if (jQuery.isEmptyObject(this.selected_records)) {
+                this.expander.css('visibility', 'hidden');
+            } else {
+                this.expander.css('visibility', 'visible');
+            }
+        },
         sort_model: function(e){
             var column = e.data;
             var arrow = column.arrow;
@@ -807,7 +867,9 @@
                     add_row.bind(this));
         },
         redraw: function(selected, expanded) {
-            return redraw_async(this.rows, selected, expanded);
+            return redraw_async(this.rows, selected, expanded).then(function() 
{
+                this.update_selection();
+            }.bind(this));
         },
         switch_: function(path) {
             this.screen.row_activate();
@@ -1019,6 +1081,7 @@
             } else {
                 this.select_changed(null);
             }
+            this.update_expander(value? 'more' : null);
             this.update_sum();
         },
         update_selection: function() {
@@ -1036,6 +1099,7 @@
                 // Set checked to go first unchecked after first click
                 this.selection.prop('checked', true);
             }
+            this.update_expander();
         },
         get_selected_paths: function() {
             var selected_paths = [];
@@ -1511,21 +1575,27 @@
         },
         toggle_row: function() {
             if (this.is_expanded()) {
-                this.update_expander(false);
-                this.tree.expanded.delete(this);
-                this.collapse_children();
+                this.collapse_row();
             } else {
-                if (this.tree.n_children(this) > Sao.config.limit) {
-                    this.tree.record = this.record;
-                    this.tree.screen.switch_view('form');
-                } else {
-                    this.update_expander(true);
-                    this.tree.expanded.add(this);
-                    this.expand_children();
-                }
+                this.expand_row();
             }
             return false;
         },
+        expand_row: function() {
+            if (this.tree.n_children(this) > Sao.config.limit) {
+                this.tree.record = this.record;
+                this.tree.screen.switch_view('form');
+            } else {
+                this.update_expander(true);
+                this.tree.expanded.add(this);
+                this.expand_children();
+            }
+        },
+        collapse_row: function() {
+            this.update_expander(false);
+            this.tree.expanded.delete(this);
+            this.collapse_children();
+        },
         update_expander: function(expanded) {
             var icon;
             if (expanded) {
@@ -1564,6 +1634,7 @@
                     }).map(function(row) {
                         return row.el;
                     }));
+                    this.tree.update_selection();
                 }.bind(this));
             }.bind(this));
         },
@@ -1638,6 +1709,11 @@
             this.set_selection(is_selected);
             if (is_selected) {
                 this.tree.select_changed(this.record);
+                if (this.is_expanded()) {
+                    this.tree.update_expander('less');
+                } else if (this.expander.css('visibility') == 'visible') {
+                    this.tree.update_expander('more');
+                }
             } else {
                 this.tree.select_changed(
                         this.tree.selected_records[0] || null);

Reply via email to