add saving favorite locations
[qcg-portal.git] / filex / static / filex / filex.js
index 5132ec7..29589c3 100644 (file)
@@ -95,8 +95,7 @@ $(function(){
         model: Filex.PathBit,
 
         initialize: function() {
-            this.listenTo(this, 'reset', this.setActive);
-            this.listenTo(this, 'add', this.setActive);
+            this.listenTo(this, 'reset add', this.setActive);
         },
 
         setActive: function() {
@@ -210,7 +209,9 @@ $(function(){
         events: {
             'change #show-hidden': 'toggleHidden',
             'click #select-all': 'selectAll',
-            'click #btn-refresh': 'reloadFiles'
+            'click #btn-refresh': 'reloadFiles',
+            'click #btn-favorites': 'toggleFavorites',
+            'click #btn-host': 'editHost'
         },
 
         initialize: function(options) {
@@ -218,14 +219,15 @@ $(function(){
             this.$error = $('#error');
             this.$showHidden = $('#show-hidden');
             this.$selectAll = $('#select-all');
+            this.$favorites = $('#btn-favorites');
+            this.$host = $('#btn-host');
 
-            this.host = options.host;
             this.path = new Filex.Path();
             this.files = new Filex.FileList();
 
             this.listenTo(this.path, 'reset', this.resetPath);
-            this.listenTo(this.path, 'add', this.reloadFiles);
             this.listenTo(this.path, 'add', this.addPath);
+            this.listenTo(this.path, 'add reset', this.changedPath);
             this.listenTo(this.path, 'selected', this.selectedPath);
             this.listenTo(this.files, 'reset', this.resetFiles);
             this.listenTo(this.files, 'selected:dir', this.selectedDir);
@@ -236,58 +238,102 @@ $(function(){
                 optionTemplate = _.template('<div><div><%= host %></div><div class="small text-muted"><%= path %></div></div>');
 
             this.$('#host-selector').selectize({
-                valueField: 'host',
+                optgroupField: 'group',
                 labelField: 'host',
                 searchField: ['host', 'path'],
                 sortField: [
                     {field: 'host', direction: 'asc'},
                     {field: 'path', direction: 'asc'}
                 ],
-                items: [this.host],
-                options: options.hostOptions,
+                options: options.locations,
+                optgroups: [
+                    {value: 'sys', label: 'Podstawowe'},
+                    {value: 'usr', label: 'Użytkownika'}
+                ],
+                lockOptgroupOrder: true,
+                create: function(input, callback) {
+                    var $form = $('#favorite-form'),
+                        parts = input.split('/', 1),
+                        callback_called = false;
+
+                    $form.find('#id_host').val(parts[0]);
+
+                    if (parts.length > 1)
+                        $form.find('#id_path').val(parts[1]);
+
+                    $form.on('submit', function(e) {
+                        var $this = $(this),
+                            $btn = $this.find('[type="submit"]');
+
+                        e.preventDefault();
+                        $btn.button('loading');
+
+                        $.post($this.attr('action'), $this.serialize(), function(data) {
+                            callback(data);
+                            callback_called = true;
+
+                            $this.modal('hide');
+                            $btn.button('reset');
+                        }, 'json').fail(function() {
+                            console.error(arguments);
+                            $btn.button('error');
+                        });
+                    });
+
+                    $form.one('hide.bs.modal', function() {
+                        if (!callback_called)
+                            callback();
+                        $form.off();
+                    });
+
+                    $form.modal();
+                },
                 render: {
                     option: function(item) {
                         return optionTemplate(item);
+                    },
+                    option_create : function(data, escape) {
+                        return '<div class="create">Dodaj <em>' + escape(data.input) + '</em>&hellip;</div>';
                     }
                 },
-                onDropdownClose: function() {
+                onItemRemove: function(value) {
+                    this.oldValue = value;
+                },
+                onItemAdd: function(value) {
+                    view.load(value);
                     this.blur();
                 },
                 onBlur: function() {
-                    var value = this.getValue();
-                    if (!value) {
-                        this.addItem(view.host, true);
-                        return;
-                    }
-
-                    if (value != view.host) {
-                        var location = this.options[value];
+                    if (!this.getValue() && this.oldValue)
+                        this.addItem(this.oldValue);
 
-                        view.host = location.host;
-                        view.navigate(location.path);
-                    }
+                    $('#host').removeClass('edit');
+                    this.clear();
                 }
             });
             this.hostSelectize = this.$('#host-selector')[0].selectize;
 
             this.render();
-            this.navigate(this.hostSelectize.options[this.host].path);
         },
 
         render: function() {
             this.updateSelectAll();
+            this.updateFavorites();
             this.$noItems.toggle(!Boolean(this.visibleFiles().length));
             this.$error.hide();
         },
 
-        navigate: function(path) {
-            var pathBits = [new Filex.PathBit({'text': '/', 'path': ''})];
-
-            pathBits = pathBits.concat(_.map(path.replace(/(^\/+|\/+$)/g, '').split('/'), function(name) {
-                return new Filex.PathBit({'text': name, 'path': name});
-            }));
+        load: function(location) {
+            var path = location.replace(/(^\/+|\/+$)/g, '').split('/'),
+                host = path.shift(),
+                pathBits = [new Filex.PathBit({'text': '/', 'path': ''})].concat(_.map(path, function(name) {
+                    return new Filex.PathBit({'text': name, 'path': name});
+                }));
 
+            this.host = host;
             this.path.reset(pathBits);
+
+            this.$host.text(this.host);
         },
 
         reloadFiles: function() {
@@ -321,8 +367,6 @@ $(function(){
         },
 
         resetPath: function(models, options) {
-            this.reloadFiles();
-
             _.each(options.previousModels, function(model) {
                 model.trigger('remove');
             });
@@ -351,9 +395,7 @@ $(function(){
         },
 
         selectedPath: function(bit) {
-            var newPath = this.path.slice(0, this.path.indexOf(bit) + 1);
-            this.path.set(newPath);
-            this.reloadFiles();
+            this.path.reset(this.path.slice(0, this.path.indexOf(bit) + 1));
         },
 
         showHidden: function() {
@@ -401,8 +443,81 @@ $(function(){
             _.each(this.visibleFiles(), function(item) {
                 item.set('checked', false);
             });
+        },
 
-            this.updateSelectAll();
+        toggleFavorites: function() {
+            var $btn = this.$favorites,
+                locations = this.hostSelectize,
+                is_active = $btn.hasClass('active'),
+                url = is_active ? '/filex/fav/delete/' : '/filex/fav/add/',
+                data = {
+                    host: this.host,
+                    path: this.path.full()
+                };
+
+            $btn.button('loading');
+
+            $.post(url, data, 'json').done(function () {
+                $btn.button('reset');
+
+                if (is_active) {
+                    locations.removeOption(data.host + data.path);
+                }
+                else {
+                    locations.addOption({
+                        group: 'usr',
+                        host: data.host,
+                        path: data.path,
+                        value: data.host + data.path
+                    });
+                }
+            }).fail(function() {
+                $btn.button('reset');
+                $btn.button('toggle');
+
+                console.error(arguments);
+            });
+        },
+
+        initialLoad: function() {
+            if (!this.host) {
+                var opts = this.hostSelectize.options;
+
+                this.load(opts[Object.keys(opts)[0]].value);
+            }
+        },
+
+        changedPath: function () {
+            this.reloadFiles();
+            this.updateFavorites();
+        },
+
+        updateFavorites: function() {
+            var loc = this.host + this.path.full(),
+                favorites = this.hostSelectize.options;
+
+            if (favorites.hasOwnProperty(loc)) {
+                if (favorites[loc].group == 'sys') {
+                    this.$favorites.addClass('disabled').prop('disabled', true);
+                    if (this.$favorites.hasClass('active'))
+                        this.$favorites.button('toggle');
+                }
+                else {
+                    this.$favorites.removeClass('disabled').prop('disabled', false);
+                    if (!this.$favorites.hasClass('active'))
+                        this.$favorites.button('toggle');
+                }
+            }
+            else {
+                this.$favorites.removeClass('disabled').prop('disabled', false);
+                if (this.$favorites.hasClass('active'))
+                    this.$favorites.button('toggle');
+            }
+        },
+
+        editHost: function() {
+            $('#host').addClass('edit');
+            this.hostSelectize.focus();
         }
     });
 });