changeset e596254259df in sao:default
details: https://hg.tryton.org/sao?cmd=changeset;node=e596254259df
description:
        Add list-form view

        issue8185
        review255091002
diffstat:

 CHANGELOG             |    1 +
 Gruntfile.js          |    1 +
 src/sao.less          |    9 ++-
 src/screen.js         |   11 ++-
 src/view.js           |   25 +++++---
 src/view/calendar.js  |    4 +-
 src/view/form.js      |    4 +-
 src/view/graph.js     |    4 +-
 src/view/list_form.js |  147 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/view/tree.js      |    4 +-
 10 files changed, 186 insertions(+), 24 deletions(-)

diffs (378 lines):

diff -r dadc99547af6 -r e596254259df CHANGELOG
--- a/CHANGELOG Mon Apr 08 10:14:39 2019 +0200
+++ b/CHANGELOG Mon Apr 08 15:06:36 2019 +0200
@@ -1,3 +1,4 @@
+* Add list-form view
 * Support HTML widget
 * Use locale format for data export
 * Add day view on calendar
diff -r dadc99547af6 -r e596254259df Gruntfile.js
--- a/Gruntfile.js      Mon Apr 08 10:14:39 2019 +0200
+++ b/Gruntfile.js      Mon Apr 08 15:06:36 2019 +0200
@@ -16,6 +16,7 @@
       'src/view/tree.js',
       'src/view/graph.js',
       'src/view/calendar.js',
+      'src/view/list_form.js',
       'src/action.js',
       'src/common.js',
       'src/window.js',
diff -r dadc99547af6 -r e596254259df src/sao.less
--- a/src/sao.less      Mon Apr 08 10:14:39 2019 +0200
+++ b/src/sao.less      Mon Apr 08 15:06:36 2019 +0200
@@ -65,6 +65,7 @@
 }
 
 .table-row-variant(selected, @state-info-bg);
+.list-group-item-variant(selected, @state-info-bg, @state-info-text);
 
 .tab-form, .tab-board {
     nav.toolbar {
@@ -188,6 +189,12 @@
     }
 }
 
+.list-form {
+    overflow-y: auto;
+    -moz-user-select: none;
+    -webkit-user-select: none;
+}
+
 .treeview {
     -moz-user-select: none;
     -webkit-user-select: none;
@@ -417,7 +424,7 @@
         }
     }
     .form-one2many-content, .form-many2many-content {
-        .treeview {
+        .treeview, .list-form {
             min-height: 100px;
             max-height: 300px;
         }
diff -r dadc99547af6 -r e596254259df src/screen.js
--- a/src/screen.js     Mon Apr 08 10:14:39 2019 +0200
+++ b/src/screen.js     Mon Apr 08 15:06:36 2019 +0200
@@ -864,8 +864,8 @@
             for (field in fields) {
                 this.group.model.fields[field].views.add(view_id);
             }
-            var view_widget = Sao.View.parse(this, xml_view, 
view.field_childs);
-            view_widget.view_id = view_id;
+            var view_widget = Sao.View.parse(
+                this, view_id, view.type, xml_view, view.field_childs);
             this.views.push(view_widget);
 
             return view_widget;
@@ -1249,7 +1249,7 @@
             var view = this.current_view;
             view.set_value();
             this.set_cursor(false, false);
-            if (~['tree', 'form'].indexOf(view.view_type) &&
+            if (~['tree', 'form', 'list-form'].indexOf(view.view_type) &&
                     this.current_record && this.current_record.group) {
                 var group = this.current_record.group;
                 var record = this.current_record;
@@ -1278,7 +1278,7 @@
             var view = this.current_view;
             view.set_value();
             this.set_cursor(false, false);
-            if (~['tree', 'form'].indexOf(view.view_type) &&
+            if (~['tree', 'form', 'list-form'].indexOf(view.view_type) &&
                     this.current_record && this.current_record.group) {
                 var group = this.current_record.group;
                 var record = this.current_record;
@@ -1456,7 +1456,8 @@
         set_cursor: function(new_, reset_view) {
             if (!this.current_view) {
                 return;
-            } else if (~['tree', 'form'].indexOf(this.current_view.view_type)) 
{
+            } else if (~['tree', 'form', 'list-form'].indexOf(
+                    this.current_view.view_type)) {
                 this.current_view.set_cursor(new_, reset_view);
             }
         },
diff -r dadc99547af6 -r e596254259df src/view.js
--- a/src/view.js       Mon Apr 08 10:14:39 2019 +0200
+++ b/src/view.js       Mon Apr 08 15:06:36 2019 +0200
@@ -11,7 +11,8 @@
         editable: null,
         children_field: null,
         xml_parser: null,
-        init: function(screen, xml) {
+        init: function(view_id, screen, xml) {
+            this.view_id = view_id;
             this.screen = screen;
             this.widgets = {};
             this.state_widgets = [];
@@ -27,9 +28,11 @@
             for (var name in this.screen.model.fields) {
                 field_attrs[name] = this.screen.model.fields[name].description;
             }
-            new this.xml_parser(
-                this, this.screen.exclude_field, field_attrs)
-                .parse(xml.children()[0]);
+            if (this.xml_parser) {
+                new this.xml_parser(
+                    this, this.screen.exclude_field, field_attrs)
+                    .parse(xml.children()[0]);
+            }
         },
         set_value: function() {
         },
@@ -71,16 +74,18 @@
         return path;
     };
 
-    Sao.View.parse = function(screen, xml, children_field) {
-        switch (xml.children().prop('tagName')) {
+    Sao.View.parse = function(screen, view_id, type, xml, children_field) {
+        switch (type) {
             case 'tree':
-                return new Sao.View.Tree(screen, xml, children_field);
+                return new Sao.View.Tree(view_id, screen, xml, children_field);
             case 'form':
-                return new Sao.View.Form(screen, xml);
+                return new Sao.View.Form(view_id, screen, xml);
             case 'graph':
-                return new Sao.View.Graph(screen, xml);
+                return new Sao.View.Graph(view_id, screen, xml);
             case 'calendar':
-                return new Sao.View.Calendar(screen, xml);
+                return new Sao.View.Calendar(view_id, screen, xml);
+            case 'list-form':
+                return new Sao.View.ListForm(view_id, screen, xml);
         }
     };
 
diff -r dadc99547af6 -r e596254259df src/view/calendar.js
--- a/src/view/calendar.js      Mon Apr 08 10:14:39 2019 +0200
+++ b/src/view/calendar.js      Mon Apr 08 15:06:36 2019 +0200
@@ -77,14 +77,14 @@
         editable: false,
         view_type: 'calendar',
         xml_parser: Sao.View.CalendarXMLViewParser,
-        init: function(screen, xml) {
+        init: function(view_id, screen, xml) {
             // Used to check if the events are still processing
             this.processing = true;
             this.fields = [];
             this.el = jQuery('<div/>', {
                 'class': 'calendar'
             });
-            Sao.View.Calendar._super.init.call(this, screen, xml);
+            Sao.View.Calendar._super.init.call(this, view_id, screen, xml);
             //this.el.fullCalendar('changeView', defaultview);
         },
         get_colors: function(record) {
diff -r dadc99547af6 -r e596254259df src/view/form.js
--- a/src/view/form.js  Mon Apr 08 10:14:39 2019 +0200
+++ b/src/view/form.js  Mon Apr 08 15:06:36 2019 +0200
@@ -216,7 +216,7 @@
         editable: true,
         view_type: 'form',
         xml_parser: Sao.View.FormXMLViewParser,
-        init: function(screen, xml) {
+        init: function(view_id, screen, xml) {
             this.el = jQuery('<div/>', {
                 'class': 'form'
             });
@@ -224,7 +224,7 @@
             this.expandables = [];
             this.containers = [];
             this.widget_id = 0;
-            Sao.View.Form._super.init.call(this, screen, xml);
+            Sao.View.Form._super.init.call(this, view_id, screen, xml);
         },
         get_fields: function() {
             return Object.keys(this.widgets);
diff -r dadc99547af6 -r e596254259df src/view/graph.js
--- a/src/view/graph.js Mon Apr 08 10:14:39 2019 +0200
+++ b/src/view/graph.js Mon Apr 08 15:06:36 2019 +0200
@@ -50,12 +50,12 @@
         editable: false,
         view_type: 'graph',
         xml_parser: Sao.View.GraphXMLViewParser,
-        init: function(screen, xml, children_field) {
+        init: function(view_id, screen, xml, children_field) {
             this.el = jQuery('<div/>', {
                 'class': 'graph'
             });
 
-            Sao.View.Graph._super.init.call(this, screen, xml);
+            Sao.View.Graph._super.init.call(this, view_id, screen, xml);
         },
         display: function() {
             return this.widgets.root.display(this.group);
diff -r dadc99547af6 -r e596254259df src/view/list_form.js
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/src/view/list_form.js     Mon Apr 08 15:06:36 2019 +0200
@@ -0,0 +1,147 @@
+/* This file is part of Tryton.  The COPYRIGHT file at the top level of
+   this repository contains the full copyright notices and license terms. */
+(function() {
+    'use strict';
+
+    Sao.View.ListGroupViewForm = Sao.class_(Sao.View.Form, {
+        editable: true,
+        get record() {
+            return this._record;
+        },
+        set record(value) {
+            this._record = value;
+        }
+    });
+
+    Sao.View.ListForm = Sao.class_(Sao.View, {
+        view_type: 'list-form',
+        init: function(view_id, screen, xml) {
+            Sao.View.ListForm._super.init.call(this, view_id, screen, xml);
+            this.editable = true;
+
+            this.form_xml = xml;
+            this.el = jQuery('<ul/>', {
+                'class': 'list-group list-form'
+            });
+            this._view_forms = [];
+        },
+        display: function() {
+            var record, view_form, view_form_frame, to_delete;
+            var deferreds = [];
+            var new_elements = [];
+            for (var i = 0; i < this.group.length; i++) {
+                record = this.group[i];
+                view_form = this._view_forms[i];
+                if (!view_form) {
+                    view_form_frame = this._create_form(record);
+                    new_elements.push(view_form_frame);
+                    view_form = this._view_forms[this._view_forms.length - 1];
+                } else {
+                    view_form_frame = view_form.el.parent();
+                    view_form.record = record;
+                }
+
+                if (~this.group.record_deleted.indexOf(record) ||
+                        ~this.group.record_removed.indexOf(record)) {
+                    view_form_frame.addClass('disabled');
+                } else {
+                    view_form_frame.removeClass('disabled');
+                }
+                if (this.record === record) {
+                    view_form_frame.addClass('list-group-item-selected');
+                } else {
+                    view_form_frame.removeClass('list-group-item-selected');
+                }
+                deferreds.push(view_form.display());
+            }
+            if (new_elements.length > 0) {
+                this.el.append(new_elements);
+            }
+            to_delete = this._view_forms.splice(this.group.length);
+            jQuery(to_delete.map(function (vf) { return vf.el[0]; }))
+                .parent().detach();
+            return jQuery.when.apply(jQuery, deferreds);
+        },
+        _create_form: function(record) {
+            var view_form = new Sao.View.ListGroupViewForm(
+                this.view_id, this.screen, this.form_xml);
+            view_form.record = record;
+            this._view_forms.push(view_form);
+            var frame = jQuery('<li/>', {
+                'class': 'list-group-item list-form-item'
+            });
+            frame.append(view_form.el);
+            frame.click(
+                this._view_forms.length - 1, this._select_row.bind(this));
+            return frame;
+        },
+        get selected_records() {
+            var view_form, records = [];
+            var frame;
+            for (var i = 0; i < this._view_forms.length; i++) {
+                view_form = this._view_forms[i];
+                frame = view_form.el.parent();
+                if (frame.hasClass('list-group-item-selected')) {
+                    records.push(view_form.record);
+                }
+            }
+            return records;
+        },
+        set_cursor: function(new_, reset_view) {
+            if (new_) {
+                this.el.animate({
+                    scrollTop: this.el[0].scrollHeight
+                });
+            }
+        },
+        select_records: function(from, to) {
+            jQuery(this._view_forms.map(function (vf) { return vf.el[0]; }))
+                .parent().removeClass('list-group-item-selected');
+            if ((from === null) && (to === null)) {
+                return;
+            }
+
+            if (!from) {
+                from = 0;
+            }
+            if (!to) {
+                to = 0;
+            }
+            if (to < from) {
+                var tmp = from;
+                from = to;
+                to = tmp;
+            }
+
+            var select_form = function(form) {
+                form.el.parent().addClass('list-group-item-selected');
+            };
+            this._view_forms.slice(from, to + 1).forEach(select_form);
+        },
+        _select_row: function(event_) {
+            var current_view_form;
+            var view_form_idx = event_.data;
+            var view_form = this._view_forms[view_form_idx];
+
+            if (event_.shiftKey) {
+                for (var i=0; i < this._view_forms.length; i++) {
+                    if (this._view_forms[i].record === this.record) {
+                        current_view_form = this._view_forms[i];
+                        break;
+                    }
+                }
+                this.select_records(i, view_form_idx);
+            } else {
+                if (!event_.ctrlKey) {
+                    this.select_records(null, null);
+                }
+                this.record = view_form.record;
+                view_form.el.parent().toggleClass('list-group-item-selected');
+            }
+            if (current_view_form) {
+                this.record = current_view_form.record;
+            }
+        }
+    });
+
+}());
diff -r dadc99547af6 -r e596254259df src/view/tree.js
--- a/src/view/tree.js  Mon Apr 08 10:14:39 2019 +0200
+++ b/src/view/tree.js  Mon Apr 08 15:06:36 2019 +0200
@@ -76,7 +76,7 @@
     Sao.View.Tree = Sao.class_(Sao.View, {
         view_type: 'tree',
         xml_parser: Sao.View.TreeXMLViewParser,
-        init: function(screen, xml, children_field) {
+        init: function(view_id, screen, xml, children_field) {
             this.children_field = children_field;
             this.sum_widgets = {};
             this.columns = [];
@@ -87,7 +87,7 @@
             });
             this.expanded = {};
 
-            Sao.View.Tree._super.init.call(this, screen, xml);
+            Sao.View.Tree._super.init.call(this, view_id, screen, xml);
 
             // Table of records
             this.rows = [];

Reply via email to