+
+ <% if (synced_repos.length > 0) { %>
+
+ <%- synced_repos_length %>
+
+ <% } else { %>
+ 0
+ <% } %>
|
diff --git a/seahub/templates/libraries.html b/seahub/templates/libraries.html
index ec62655f3a..c6da23d4b8 100644
--- a/seahub/templates/libraries.html
+++ b/seahub/templates/libraries.html
@@ -287,6 +287,11 @@ app["pageOptions"] = {
file_audit_enabled: {% if file_audit_enabled %} true {% else %} false {% endif %},
cur_note: {% if request.cur_note %} {'id': '{{ request.cur_note.id }}'} {% else %} null {% endif %}
};
+app.ui = {
+ currentDropdown: null,
+ currentHighlightedItem: null,
+ freezeItemHightlight: false
+};
{% if debug %}
diff --git a/static/scripts/app/router.js b/static/scripts/app/router.js
index 0f1787261d..8126565910 100644
--- a/static/scripts/app/router.js
+++ b/static/scripts/app/router.js
@@ -42,9 +42,7 @@ define([
Common.initNoticePopup();
this.sideNavView = new SideNavView();
- app.ui = {
- sideNavView: this.sideNavView
- };
+ app.ui.sideNavView = this.sideNavView;
this.dirView = new DirView();
diff --git a/static/scripts/app/views/device.js b/static/scripts/app/views/device.js
index 6377f12b8c..d509929fa7 100644
--- a/static/scripts/app/views/device.js
+++ b/static/scripts/app/views/device.js
@@ -3,33 +3,26 @@ define([
'underscore',
'backbone',
'common',
- 'moment'
-], function($, _, Backbone, Common, Moment) {
+ 'moment',
+ 'app/views/widgets/hl-item-view',
+ 'app/views/widgets/dropdown'
+], function($, _, Backbone, Common, Moment, HLItemView, DropdownView) {
'use strict';
- var DeviceView = Backbone.View.extend({
+ var DeviceView = HLItemView.extend({
tagName: 'tr',
template: _.template($('#device-item-tmpl').html()),
events: {
- 'mouseenter': 'highlight',
- 'mouseleave': 'rmHighlight',
- 'click .unlink-device': 'unlinkDevice',
- 'click .js-toggle-repos': 'toggleSyncedRepos'
+ 'click .unlink-device': 'unlinkDevice'
},
initialize: function() {
- $(document).click(function(e) {
- var target = e.target || event.srcElement;
- if (!$('.js-toggle-repos, .device-libs-popover').is(target)) {
- $('.device-libs-popover').addClass('hide');
- $('.dir-icon').removeClass('icon-caret-up').addClass('icon-caret-down');
- }
- });
+ HLItemView.prototype.initialize.call(this);
},
- render: function () {
+ render: function() {
var data = this.model.toJSON();
if (typeof(data['synced_repos']) == 'undefined') {
@@ -48,36 +41,13 @@ define([
this.$el.html(this.template(data));
+ new DropdownView({
+ el: this.$('.js-dropdown')
+ });
+
return this;
},
- highlight: function() {
- this.$el.addClass('hl');
- this.$el.find('.op-icon').removeClass('vh');
- },
-
- rmHighlight: function() {
- this.$el.removeClass('hl');
- this.$el.find('.op-icon').addClass('vh');
- },
-
- toggleSyncedRepos: function(e) {
- var $current_icon= $(e.currentTarget).children('.dir-icon'),
- $current_popover = $(e.currentTarget).next('.device-libs-popover');
-
- $('.device-libs-popover').not($current_popover).addClass('hide');
- $('.dir-icon').not($current_icon).removeClass('icon-caret-up').addClass('icon-caret-down');
-
- $current_popover.toggleClass('hide');
- if ($current_icon.hasClass('icon-caret-up')) {
- $current_icon.removeClass('icon-caret-up').addClass('icon-caret-down');
- } else {
- $current_icon.removeClass('icon-caret-down').addClass('icon-caret-up');
- }
-
- return false
- },
-
unlinkDevice: function() {
var _this = this,
device_name = this.model.get('device_name');
diff --git a/static/scripts/app/views/group-repo.js b/static/scripts/app/views/group-repo.js
index f4d4952321..c4fdeebb87 100644
--- a/static/scripts/app/views/group-repo.js
+++ b/static/scripts/app/views/group-repo.js
@@ -2,22 +2,23 @@ define([
'jquery',
'underscore',
'backbone',
- 'common'
-], function($, _, Backbone, Common) {
+ 'common',
+ 'app/views/widgets/hl-item-view'
+], function($, _, Backbone, Common, HLItemView) {
'use strict';
- var GroupRepoView = Backbone.View.extend({
+ var GroupRepoView = HLItemView.extend({
tagName: 'tr',
template: _.template($('#group-repo-tmpl').html()),
events: {
- 'mouseenter': 'highlight',
- 'mouseleave': 'rmHighlight',
'click .cancel-share': 'unshare'
},
initialize: function(options) {
+ HLItemView.prototype.initialize.call(this);
+
this.group_id = options.group_id;
this.is_staff = options.is_staff;
@@ -48,14 +49,6 @@ define([
return this;
},
- highlight: function() {
- this.$el.addClass('hl').find('.op-icon').removeClass('vh');
- },
-
- rmHighlight: function() {
- this.$el.removeClass('hl').find('.op-icon').addClass('vh');
- },
-
unshare: function() {
var lib_name = this.model.get('name');
this.model.destroy({
diff --git a/static/scripts/app/views/organization-repo.js b/static/scripts/app/views/organization-repo.js
index 8fa7b918e8..19a25d8938 100644
--- a/static/scripts/app/views/organization-repo.js
+++ b/static/scripts/app/views/organization-repo.js
@@ -2,16 +2,18 @@ define([
'jquery',
'underscore',
'backbone',
- 'common'
-], function($, _, Backbone, Common) {
+ 'common',
+ 'app/views/widgets/hl-item-view'
+], function($, _, Backbone, Common, HLItemView) {
'use strict';
- var OrganizationRepoView = Backbone.View.extend({
+ var OrganizationRepoView = HLItemView.extend({
tagName: 'tr',
template: _.template($('#organization-repo-tmpl').html()),
initialize: function() {
+ HLItemView.prototype.initialize.call(this);
},
render: function() {
@@ -27,19 +29,9 @@ define([
},
events: {
- 'mouseenter': 'highlight',
- 'mouseleave': 'rmHighlight',
'click .cancel-share': 'removeShare'
},
- highlight: function() {
- this.$el.addClass('hl').find('.op-icon').removeClass('vh');
- },
-
- rmHighlight: function() {
- this.$el.removeClass('hl').find('.op-icon').addClass('vh');
- },
-
removeShare: function() {
var el = this.$el;
var lib_name = this.model.get('name');
diff --git a/static/scripts/app/views/repo.js b/static/scripts/app/views/repo.js
index bc1f10c3c5..e6d189d185 100644
--- a/static/scripts/app/views/repo.js
+++ b/static/scripts/app/views/repo.js
@@ -7,12 +7,15 @@ define([
'app/views/dialogs/repo-change-password',
'app/views/dialogs/repo-history-settings',
'app/views/dialogs/repo-share-link-admin',
- 'app/views/dialogs/repo-folder-perm-admin'
+ 'app/views/dialogs/repo-folder-perm-admin',
+ 'app/views/widgets/hl-item-view',
+ 'app/views/widgets/dropdown'
], function($, _, Backbone, Common, ShareView, RepoChangePasswordDialog,
- HistorySettingsDialog, RepoShareLinkAdminDialog, RepoFolderPermAdminDialog) {
+ HistorySettingsDialog, RepoShareLinkAdminDialog, RepoFolderPermAdminDialog,
+ HLItemView, DropdownView) {
'use strict';
- var RepoView = Backbone.View.extend({
+ var RepoView = HLItemView.extend({
tagName: 'tr',
template: _.template($('#repo-tmpl').html()),
@@ -21,11 +24,8 @@ define([
transferTemplate: _.template($('#repo-transfer-form-tmpl').html()),
events: {
- 'mouseenter': 'highlight',
- 'mouseleave': 'rmHighlight',
'click .repo-delete-btn': 'del',
'click .repo-share-btn': 'share',
- 'click .js-toggle-popup': 'togglePopup',
'click .js-repo-rename': 'rename',
'click .js-repo-transfer': 'transfer',
'click .js-repo-change-password': 'changePassword',
@@ -35,6 +35,8 @@ define([
},
initialize: function() {
+ HLItemView.prototype.initialize.call(this);
+
this.listenTo(this.model, "change", this.render);
},
@@ -47,26 +49,12 @@ define([
'icon_title': this.model.getIconTitle()
});
this.$el.html(this.template(obj));
+ this.dropdown = new DropdownView({
+ el: this.$('.js-dropdown')
+ });
return this;
},
- // disable 'hover' when 'repo-del-confirm' popup is shown
- highlight: function() {
- if ($('#my-own-repos .repo-del-confirm').length == 0
- && !$('.hidden-op:visible').length
- && !$('#repo-rename-form').length) {
- this.$el.addClass('hl').find('.op-icon').removeClass('vh');
- }
- },
-
- rmHighlight: function() {
- if ($('#my-own-repos .repo-del-confirm').length == 0
- && !$('.hidden-op:visible').length
- && !$('#repo-rename-form').length) {
- this.$el.removeClass('hl').find('.op-icon').addClass('vh');
- }
- },
-
del: function() {
var del_icon = this.$('.repo-delete-btn');
var op_container = this.$('.op-container').css({'position': 'relative'});
@@ -83,9 +71,12 @@ define([
'width': 180
});
+ app.ui.freezeItemHightlight = true;
+
var _this = this;
$('.no', confirm_popup).click(function() {
confirm_popup.addClass('hide').remove(); // `addClass('hide')`: to rm cursor
+ app.ui.freezeItemHightlight = false;
_this.rmHighlight();
});
$('.yes', confirm_popup).click(function() {
@@ -95,10 +86,12 @@ define([
dataType: 'json',
beforeSend: Common.prepareCSRFToken,
success: function(data) {
+ app.ui.freezeItemHightlight = false;
_this.remove();
Common.feedback(gettext("Delete succeeded."), 'success');
},
error: function(xhr) {
+ app.ui.freezeItemHightlight = false;
confirm_popup.addClass('hide').remove();
_this.rmHighlight();
@@ -129,21 +122,7 @@ define([
},
togglePopup: function() {
- var $icon = this.$('.js-toggle-popup'),
- $popup = this.$('.hidden-op');
-
- if ($popup.hasClass('hide')) { // the popup is not shown
- $popup.css({'left': $icon.position().left});
- if ($icon.offset().top + $popup.height() <= $('#main').offset().top + $('#main').height()) {
- // below the icon
- $popup.css('top', $icon.position().top + $icon.outerHeight(true) + 3);
- } else {
- $popup.css('bottom', $icon.parent().outerHeight() - $icon.position().top + 3);
- }
- $popup.removeClass('hide');
- } else {
- $popup.addClass('hide');
- }
+ this.dropdown.hide();
},
rename: function() {
@@ -164,8 +143,10 @@ define([
$name_span.hide();
this.togglePopup();
+ app.ui.freezeItemHightlight = true;
var cancelRename = function() {
+ app.ui.freezeItemHightlight = false;
form.remove();
$op_td.show();
$name_span.show();
@@ -195,6 +176,7 @@ define([
repo_id: _this.model.get('id')
}) + '?op=rename';
var after_op_success = function(data) {
+ app.ui.freezeItemHightlight = false;
_this.model.set({ 'name': new_name }); // it will trigger 'change' event
};
var after_op_error = function(xhr) {
diff --git a/static/scripts/app/views/shared-repo.js b/static/scripts/app/views/shared-repo.js
index caa04844fc..20d0083a44 100644
--- a/static/scripts/app/views/shared-repo.js
+++ b/static/scripts/app/views/shared-repo.js
@@ -2,22 +2,22 @@ define([
'jquery',
'underscore',
'backbone',
- 'common'
-], function($, _, Backbone, Common) {
+ 'common',
+ 'app/views/widgets/hl-item-view'
+], function($, _, Backbone, Common, HLItemView) {
'use strict';
- var SharedRepoView = Backbone.View.extend({
+ var SharedRepoView = HLItemView.extend({
tagName: 'tr',
template: _.template($('#shared-repo-tmpl').html()),
events: {
- 'mouseenter': 'showAction',
- 'mouseleave': 'hideAction',
'click .unshare-btn': 'removeShare'
},
initialize: function() {
+ HLItemView.prototype.initialize.call(this);
},
removeShare: function(e) {
@@ -56,17 +56,8 @@ define([
});
this.$el.html(this.template(obj));
return this;
- },
-
- showAction: function() {
- this.$el.addClass('hl');
- this.$el.find('.op-icon').removeClass('vh');
- },
-
- hideAction: function() {
- this.$el.removeClass('hl');
- this.$el.find('.op-icon').addClass('vh');
}
+
});
return SharedRepoView;
diff --git a/static/scripts/app/views/starred-file-item.js b/static/scripts/app/views/starred-file-item.js
index d090f5f09c..32cb1cfb3f 100644
--- a/static/scripts/app/views/starred-file-item.js
+++ b/static/scripts/app/views/starred-file-item.js
@@ -2,22 +2,22 @@ define([
'jquery',
'underscore',
'backbone',
- 'common'
-], function($, _, Backbone, Common) {
+ 'common',
+ 'app/views/widgets/hl-item-view'
+], function($, _, Backbone, Common, HLItemView) {
'use strict';
- var StarredFileView = Backbone.View.extend({
+ var StarredFileView = HLItemView.extend({
tagName: 'tr',
template: _.template($('#starred-file-item-tmpl').html()),
events: {
- 'mouseenter': 'showAction',
- 'mouseleave': 'hideAction',
'click .unstar': 'removeShare'
},
initialize: function() {
+ HLItemView.prototype.initialize.call(this);
},
render: function () {
@@ -48,16 +48,6 @@ define([
Common.ajaxErrorHandler(xhr);
}
});
- },
-
- showAction: function() {
- this.$el.addClass('hl');
- this.$el.find('.op-icon').removeClass('vh');
- },
-
- hideAction: function() {
- this.$el.removeClass('hl');
- this.$el.find('.op-icon').addClass('vh');
}
});
diff --git a/static/scripts/app/views/widgets/dropdown.js b/static/scripts/app/views/widgets/dropdown.js
new file mode 100644
index 0000000000..e6715ccc9a
--- /dev/null
+++ b/static/scripts/app/views/widgets/dropdown.js
@@ -0,0 +1,69 @@
+define([
+ 'jquery',
+ 'underscore',
+ 'backbone',
+ 'common',
+], function($, _, Backbone, Common) {
+ 'use strict';
+
+ /*
+ * Dropdown View.
+ */
+
+ // There can be only one visible dropdown view
+ $(document).click(function(e) {
+ var view = app.ui.currentDropdown;
+ var target = e.target || event.srcElement;
+
+ if (!view) {
+ return true;
+ }
+
+ if (!view.$('.js-dropdown-content').is(target)
+ && !view.$('.js-dropdown-content').find('*').is(target))
+ {
+ view.hide();
+ if (app.ui.currentHighlightedItem) {
+ app.ui.currentHighlightedItem.rmHighlight();
+ }
+ }
+ return true;
+ });
+
+ var DropdownView = Backbone.View.extend({
+
+ toggleClass: '.js-dropdown-toggle',
+ popupClass: '.js-dropdown-content',
+
+ initialize: function(options) {
+ this.$el.on('click', '.js-dropdown-toggle', _.bind(this.toggleDropdown, this));
+ },
+
+ hide: function() {
+ app.ui.currentDropdown = null;
+ this.$('.js-dropdown-content').addClass('hide');
+ },
+
+ show: function() {
+ app.ui.currentDropdown = this;
+ this.$('.js-dropdown-content').removeClass('hide');
+ },
+
+ toggleDropdown: function() {
+ if (app.ui.currentDropdown && app.ui.currentDropdown != this) {
+ app.ui.currentDropdown.hide();
+ }
+
+ if (this.$('.js-dropdown-content').is(':hidden')) {
+ this.show();
+ } else {
+ this.hide();
+ }
+
+ return false;
+ }
+
+ });
+
+ return DropdownView;
+});
diff --git a/static/scripts/app/views/widgets/hl-item-view.js b/static/scripts/app/views/widgets/hl-item-view.js
new file mode 100644
index 0000000000..59d806e08a
--- /dev/null
+++ b/static/scripts/app/views/widgets/hl-item-view.js
@@ -0,0 +1,42 @@
+define([
+ 'jquery',
+ 'underscore',
+ 'backbone',
+ 'common',
+], function($, _, Backbone, Common) {
+ 'use strict';
+
+ /*
+ * Hightable Item View.
+ */
+ var HLItemView = Backbone.View.extend({
+ tagName: 'tr',
+
+ hiddenOperationClass: '.op-icon',
+
+ initialize: function(options) {
+ this.$el.on('mouseenter', _.bind(this.highlight, this));
+ this.$el.on('mouseleave', _.bind(this.rmHighlight, this));
+ },
+
+ highlight: function() {
+ // if there are dropdown items or freezeItemHightlight is set, don't highlight
+ if (app.ui.currentDropdown || app.ui.freezeItemHightlight) {
+ return;
+ }
+ app.ui.currentHighlightedItem = this;
+ this.$el.addClass('hl').find(this.hiddenOperationClass).removeClass('vh');
+ },
+
+ rmHighlight: function() {
+ if (app.ui.currentDropdown || app.ui.freezeItemHightlight) {
+ return;
+ }
+ app.ui.currentHighlightedItem = null;
+ this.$el.removeClass('hl').find(this.hiddenOperationClass).addClass('vh');
+ }
+
+ });
+
+ return HLItemView;
+});
|