Merge pull request #607 from nextcloud/sharing-popover-menu

Move sharing options into popover menu
This commit is contained in:
Lukas Reschke 2016-10-03 14:18:17 +02:00 committed by GitHub
commit 08b0e5c112
4 changed files with 126 additions and 66 deletions

View File

@ -57,6 +57,16 @@
vertical-align:text-bottom; /* properly align icons */ vertical-align:text-bottom; /* properly align icons */
} }
#shareWithList .sharingOptionsGroup .icon-more,
#shareWithList .unshare .icon-delete {
vertical-align: sub;
}
#shareWithList .unshare .icon-delete {
padding-left: 15px;
padding-right: 15px;
}
#shareWithList label input[type=checkbox]{ #shareWithList label input[type=checkbox]{
margin-left: 0; margin-left: 0;
position: relative; position: relative;

View File

@ -63,6 +63,15 @@
white-space: normal; white-space: normal;
} }
#shareWithList .sharingOptionsGroup {
position: absolute;
right: 0;
}
#shareWithList .sharingOptionsGroup .popovermenu {
right: 44px;
}
#shareWithList .shareOption { #shareWithList .shareOption {
white-space: nowrap; white-space: nowrap;
display: inline-block; display: inline-block;
@ -104,12 +113,10 @@ a.showCruds {
} }
a.unshare { a.unshare {
display:inline; display:inline-block;
float:right;
opacity:.5; opacity:.5;
padding: 10px; padding: 10px;
margin-top: -5px; margin-top: -5px;
margin-right: -10px;
} }
#link { #link {

View File

@ -1,3 +1,5 @@
/* global OC, Handlebars */
/* /*
* Copyright (c) 2015 * Copyright (c) 2015
* *
@ -19,7 +21,6 @@
'<ul id="shareWithList" class="shareWithList">' + '<ul id="shareWithList" class="shareWithList">' +
'{{#each sharees}}' + '{{#each sharees}}' +
'<li data-share-id="{{shareId}}" data-share-type="{{shareType}}" data-share-with="{{shareWith}}">' + '<li data-share-id="{{shareId}}" data-share-type="{{shareType}}" data-share-with="{{shareWith}}">' +
'<a href="#" class="unshare"><span class="icon-loading-small hidden"></span><span class="icon icon-delete"></span><span class="hidden-visually">{{unshareLabel}}</span></a>' +
'{{#if avatarEnabled}}' + '{{#if avatarEnabled}}' +
'<div class="avatar {{#if modSeed}}imageplaceholderseed{{/if}}" data-username="{{shareWith}}" {{#if modSeed}}data-seed="{{shareWith}} {{shareType}}"{{/if}}></div>' + '<div class="avatar {{#if modSeed}}imageplaceholderseed{{/if}}" data-username="{{shareWith}}" {{#if modSeed}}data-seed="{{shareWith}} {{shareType}}"{{/if}}></div>' +
'{{/if}}' + '{{/if}}' +
@ -30,45 +31,57 @@
'<label for="mail-{{cid}}-{{shareWith}}">{{notifyByMailLabel}}</label>' + '<label for="mail-{{cid}}-{{shareWith}}">{{notifyByMailLabel}}</label>' +
'</span>' + '</span>' +
'{{/unless}} {{/if}}' + '{{/unless}} {{/if}}' +
'{{#if isResharingAllowed}} {{#if sharePermissionPossible}}' + '<span class="sharingOptionsGroup">' +
'<span class="shareOption">' + '{{#if editPermissionPossible}}' +
'<input id="canShare-{{cid}}-{{shareWith}}" type="checkbox" name="share" class="permissions checkbox" {{#if hasSharePermission}}checked="checked"{{/if}} data-permissions="{{sharePermission}}" />' + '<span class="shareOption">' +
'<label for="canShare-{{cid}}-{{shareWith}}">{{canShareLabel}}</label>' + '<input id="canEdit-{{cid}}-{{shareWith}}" type="checkbox" name="edit" class="permissions checkbox" {{#if hasEditPermission}}checked="checked"{{/if}} />' +
'<label for="canEdit-{{cid}}-{{shareWith}}">{{canEditLabel}}</label>' +
'</span>' +
'{{/if}}' +
'<a href="#"><span class="icon icon-more"></span></a>' +
'<div class="popovermenu bubble hidden menu">' +
'<ul>' +
'{{#if isResharingAllowed}} {{#if sharePermissionPossible}}' +
'<li>' +
'<span class="shareOption">' +
'<input id="canShare-{{cid}}-{{shareWith}}" type="checkbox" name="share" class="permissions checkbox" {{#if hasSharePermission}}checked="checked"{{/if}} data-permissions="{{sharePermission}}" />' +
'<label for="canShare-{{cid}}-{{shareWith}}">{{canShareLabel}}</label>' +
'</span>' +
'</li>' +
'{{/if}} {{/if}}' +
'{{#if isFolder}}' +
'{{#if createPermissionPossible}}' +
'<li>' +
'<span class="shareOption">' +
'<input id="canCreate-{{cid}}-{{shareWith}}" type="checkbox" name="create" class="permissions checkbox" {{#if hasCreatePermission}}checked="checked"{{/if}} data-permissions="{{createPermission}}"/>' +
'<label for="canCreate-{{cid}}-{{shareWith}}">{{createPermissionLabel}}</label>' +
'</span>' +
'</li>' +
'{{/if}}' +
'{{#if updatePermissionPossible}}' +
'<li>' +
'<span class="shareOption">' +
'<input id="canUpdate-{{cid}}-{{shareWith}}" type="checkbox" name="update" class="permissions checkbox" {{#if hasUpdatePermission}}checked="checked"{{/if}} data-permissions="{{updatePermission}}"/>' +
'<label for="canUpdate-{{cid}}-{{shareWith}}">{{updatePermissionLabel}}</label>' +
'</span>' +
'</li>' +
'{{/if}}' +
'{{#if deletePermissionPossible}}' +
'<li>' +
'<span class="shareOption">' +
'<input id="canDelete-{{cid}}-{{shareWith}}" type="checkbox" name="delete" class="permissions checkbox" {{#if hasDeletePermission}}checked="checked"{{/if}} data-permissions="{{deletePermission}}"/>' +
'<label for="canDelete-{{cid}}-{{shareWith}}">{{deletePermissionLabel}}</label>' +
'</span>' +
'</li>' +
'{{/if}}' +
'{{/if}}' +
'</ul>' +
'</div>' +
'<a href="#" class="unshare"><span class="icon-loading-small hidden"></span><span class="icon icon-delete"></span><span class="hidden-visually">{{unshareLabel}}</span></a>' +
'</span>' + '</span>' +
'{{/if}} {{/if}}' +
'{{#if editPermissionPossible}}' +
'<span class="shareOption">' +
'<input id="canEdit-{{cid}}-{{shareWith}}" type="checkbox" name="edit" class="permissions checkbox" {{#if hasEditPermission}}checked="checked"{{/if}} />' +
'<label for="canEdit-{{cid}}-{{shareWith}}">{{canEditLabel}}</label>' +
'{{#if isFolder}}' +
'<a href="#" class="showCruds"><img alt="{{crudsLabel}}" src="{{triangleSImage}}"/></a>' +
'{{/if}}' +
'</span>' +
'{{/if}}' +
'<div class="cruds hidden">' +
'{{#if createPermissionPossible}}' +
'<span class="shareOption">' +
'<input id="canCreate-{{cid}}-{{shareWith}}" type="checkbox" name="create" class="permissions checkbox" {{#if hasCreatePermission}}checked="checked"{{/if}} data-permissions="{{createPermission}}"/>' +
'<label for="canCreate-{{cid}}-{{shareWith}}">{{createPermissionLabel}}</label>' +
'</span>' +
'{{/if}}' +
'{{#if updatePermissionPossible}}' +
'<span class="shareOption">' +
'<input id="canUpdate-{{cid}}-{{shareWith}}" type="checkbox" name="update" class="permissions checkbox" {{#if hasUpdatePermission}}checked="checked"{{/if}} data-permissions="{{updatePermission}}"/>' +
'<label for="canUpdate-{{cid}}-{{shareWith}}">{{updatePermissionLabel}}</label>' +
'</span>' +
'{{/if}}' +
'{{#if deletePermissionPossible}}' +
'<span class="shareOption">' +
'<input id="canDelete-{{cid}}-{{shareWith}}" type="checkbox" name="delete" class="permissions checkbox" {{#if hasDeletePermission}}checked="checked"{{/if}} data-permissions="{{deletePermission}}"/>' +
'<label for="canDelete-{{cid}}-{{shareWith}}">{{deletePermissionLabel}}</label>' +
'</span>' +
'{{/if}}' +
'</div>' +
'</li>' + '</li>' +
'{{/each}}' + '{{/each}}' +
'</ul>' '</ul>';
;
/** /**
* @class OCA.Share.ShareDialogShareeListView * @class OCA.Share.ShareDialogShareeListView
@ -90,10 +103,12 @@
/** @type {Function} **/ /** @type {Function} **/
_template: undefined, _template: undefined,
_menuOpen: false,
events: { events: {
'click .unshare': 'onUnshare', 'click .unshare': 'onUnshare',
'click .icon-more': 'onToggleMenu',
'click .permissions': 'onPermissionChange', 'click .permissions': 'onPermissionChange',
'click .showCruds': 'onCrudsToggle',
'click .mailNotification': 'onSendMailNotification' 'click .mailNotification': 'onSendMailNotification'
}, },
@ -150,7 +165,7 @@
mailNotificationEnabled: this.configModel.isMailNotificationEnabled(), mailNotificationEnabled: this.configModel.isMailNotificationEnabled(),
notifyByMailLabel: t('core', 'notify by email'), notifyByMailLabel: t('core', 'notify by email'),
unshareLabel: t('core', 'Unshare'), unshareLabel: t('core', 'Unshare'),
canShareLabel: t('core', 'can share'), canShareLabel: t('core', 'can reshare'),
canEditLabel: t('core', 'can edit'), canEditLabel: t('core', 'can edit'),
createPermissionLabel: t('core', 'create'), createPermissionLabel: t('core', 'create'),
updatePermissionLabel: t('core', 'change'), updatePermissionLabel: t('core', 'change'),
@ -192,7 +207,7 @@
})); }));
if(this.configModel.areAvatarsEnabled()) { if(this.configModel.areAvatarsEnabled()) {
this.$el.find('.avatar').each(function() { this.$('.avatar').each(function() {
var $this = $(this); var $this = $(this);
if ($this.hasClass('imageplaceholderseed')) { if ($this.hasClass('imageplaceholderseed')) {
$this.css({width: 32, height: 32}); $this.css({width: 32, height: 32});
@ -203,10 +218,19 @@
}); });
} }
this.$el.find('.has-tooltip').tooltip({ this.$('.has-tooltip').tooltip({
placement: 'bottom' placement: 'bottom'
}); });
var _this = this;
this.$('.popovermenu').on('afterHide', function() {
_this._menuOpen = false;
});
if (this._menuOpen) {
// Open menu again if it was opened before
OC.showMenu(null, this.$('.popovermenu'));
}
this.delegateEvents(); this.delegateEvents();
return this; return this;
@ -224,6 +248,8 @@
}, },
onUnshare: function(event) { onUnshare: function(event) {
event.preventDefault();
event.stopPropagation();
var self = this; var self = this;
var $element = $(event.target); var $element = $(event.target);
if (!$element.is('a')) { if (!$element.is('a')) {
@ -237,7 +263,7 @@
} }
$loading.removeClass('hidden'); $loading.removeClass('hidden');
var $li = $element.closest('li'); var $li = $element.closest('li[data-share-id]');
var shareId = $li.data('share-id'); var shareId = $li.data('share-id');
@ -252,25 +278,45 @@
return false; return false;
}, },
onPermissionChange: function(event) { onToggleMenu: function(event) {
event.preventDefault();
event.stopPropagation();
var $element = $(event.target); var $element = $(event.target);
var $li = $element.closest('li'); var $li = $element.closest('li[data-share-id]');
var $menu = $li.find('.popovermenu');
OC.showMenu(null, $menu);
this._menuOpen = true;
},
onPermissionChange: function(event) {
event.preventDefault();
event.stopPropagation();
var $element = $(event.target);
var $li = $element.closest('li[data-share-id]');
var shareId = $li.data('share-id'); var shareId = $li.data('share-id');
// adjust checkbox states var permissions = OC.PERMISSION_READ;
var $checkboxes = $('.permissions', $li).not('input[name="edit"]').not('input[name="share"]');
var checked; if (this.model.isFolder()) {
if ($element.attr('name') === 'edit') { // adjust checkbox states
checked = $element.is(':checked'); var $checkboxes = $('.permissions', $li).not('input[name="edit"]').not('input[name="share"]');
// Check/uncheck Create, Update, and Delete checkboxes if Edit is checked/unck var checked;
$($checkboxes).prop('checked', checked); if ($element.attr('name') === 'edit') {
checked = $element.is(':checked');
// Check/uncheck Create, Update, and Delete checkboxes if Edit is checked/unck
$($checkboxes).prop('checked', checked);
} else {
var numberChecked = $checkboxes.filter(':checked').length;
checked = numberChecked > 0;
$('input[name="edit"]', $li).prop('checked', checked);
}
} else { } else {
var numberChecked = $checkboxes.filter(':checked').length; if ($element.attr('name') === 'edit' && $element.is(':checked')) {
checked = numberChecked > 0; permissions |= OC.PERMISSION_UPDATE;
$('input[name="edit"]', $li).prop('checked', checked); }
} }
var permissions = OC.PERMISSION_READ;
$('.permissions', $li).not('input[name="edit"]').filter(':checked').each(function(index, checkbox) { $('.permissions', $li).not('input[name="edit"]').filter(':checked').each(function(index, checkbox) {
permissions |= $(checkbox).data('permissions'); permissions |= $(checkbox).data('permissions');
}); });
@ -278,15 +324,9 @@
this.model.updateShare(shareId, {permissions: permissions}); this.model.updateShare(shareId, {permissions: permissions});
}, },
onCrudsToggle: function(event) {
var $target = $(event.target);
$target.closest('li').find('.cruds').toggleClass('hidden');
return false;
},
onSendMailNotification: function(event) { onSendMailNotification: function(event) {
var $target = $(event.target); var $target = $(event.target);
var $li = $(event.target).closest('li'); var $li = $(event.target).closest('li[data-share-id]');
var shareType = $li.data('share-type'); var shareType = $li.data('share-type');
var shareWith = $li.attr('data-share-with'); var shareWith = $li.attr('data-share-with');

View File

@ -102,6 +102,7 @@ describe('OC.Share.ShareDialogShareeListView', function () {
share_with: 'user1', share_with: 'user1',
share_with_displayname: 'User One' share_with_displayname: 'User One'
}]); }]);
shareModel.set('itemType', 'folder');
listView.render(); listView.render();
listView.$el.find("input[name='edit']").click(); listView.$el.find("input[name='edit']").click();
expect(listView.$el.find("input[name='update']").is(':checked')).toEqual(true); expect(listView.$el.find("input[name='update']").is(':checked')).toEqual(true);
@ -115,8 +116,10 @@ describe('OC.Share.ShareDialogShareeListView', function () {
permissions: 1, permissions: 1,
share_type: OC.Share.SHARE_TYPE_USER, share_type: OC.Share.SHARE_TYPE_USER,
share_with: 'user1', share_with: 'user1',
share_with_displayname: 'User One' share_with_displayname: 'User One',
itemType: 'folder'
}]); }]);
shareModel.set('itemType', 'folder');
listView.render(); listView.render();
listView.$el.find("input[name='update']").click(); listView.$el.find("input[name='update']").click();
expect(listView.$el.find("input[name='edit']").is(':checked')).toEqual(true); expect(listView.$el.find("input[name='edit']").is(':checked')).toEqual(true);