2016-07-27 16:08:24 +03:00
|
|
|
/* global OC, Handlebars */
|
|
|
|
|
2015-08-25 17:07:14 +03:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2015
|
|
|
|
*
|
|
|
|
* This file is licensed under the Affero General Public License version 3
|
|
|
|
* or later.
|
|
|
|
*
|
|
|
|
* See the COPYING-README file.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2016-08-19 22:03:25 +03:00
|
|
|
/* globals Handlebars */
|
|
|
|
|
2015-08-25 17:07:14 +03:00
|
|
|
(function() {
|
2017-03-28 15:39:38 +03:00
|
|
|
|
|
|
|
var PASSWORD_PLACEHOLDER = '**********';
|
|
|
|
var PASSWORD_PLACEHOLDER_MESSAGE = t('core', 'Choose a password for the mail share');
|
|
|
|
|
2015-08-25 17:07:14 +03:00
|
|
|
if (!OC.Share) {
|
|
|
|
OC.Share = {};
|
|
|
|
}
|
|
|
|
|
|
|
|
var TEMPLATE =
|
2015-10-16 11:54:45 +03:00
|
|
|
'<ul id="shareWithList" class="shareWithList">' +
|
2015-08-25 17:07:14 +03:00
|
|
|
'{{#each sharees}}' +
|
2016-03-18 13:59:57 +03:00
|
|
|
'<li data-share-id="{{shareId}}" data-share-type="{{shareType}}" data-share-with="{{shareWith}}">' +
|
2016-11-29 13:24:35 +03:00
|
|
|
'<div class="avatar {{#if modSeed}}imageplaceholderseed{{/if}}" data-username="{{shareWith}}" data-displayname="{{shareWithDisplayName}}" {{#if modSeed}}data-seed="{{shareWith}} {{shareType}}"{{/if}}></div>' +
|
2017-04-24 12:39:03 +03:00
|
|
|
'<span class="username" title="{{shareWithTitle}}">{{shareWithDisplayName}}</span>' +
|
2016-07-27 16:08:24 +03:00
|
|
|
'<span class="sharingOptionsGroup">' +
|
|
|
|
'{{#if editPermissionPossible}}' +
|
2016-03-18 13:59:57 +03:00
|
|
|
'<span class="shareOption">' +
|
2018-02-16 00:41:09 +03:00
|
|
|
'<input id="canEdit-{{cid}}-{{shareWith}}" type="checkbox" name="edit" class="permissions checkbox" />' +
|
2016-07-27 16:08:24 +03:00
|
|
|
'<label for="canEdit-{{cid}}-{{shareWith}}">{{canEditLabel}}</label>' +
|
2016-03-18 13:59:57 +03:00
|
|
|
'</span>' +
|
2016-04-04 18:01:51 +03:00
|
|
|
'{{/if}}' +
|
2016-08-19 14:07:04 +03:00
|
|
|
'<a href="#"><span class="icon icon-more"></span></a>' +
|
2016-11-29 14:51:37 +03:00
|
|
|
'{{{popoverMenu}}}' +
|
2016-10-26 12:27:43 +03:00
|
|
|
'</span>' +
|
2016-03-18 13:59:57 +03:00
|
|
|
'</li>' +
|
2015-08-25 17:07:14 +03:00
|
|
|
'{{/each}}' +
|
2016-08-28 21:59:12 +03:00
|
|
|
'{{#each linkReshares}}' +
|
2016-10-10 13:57:57 +03:00
|
|
|
'<li data-share-id="{{shareId}}" data-share-type="{{shareType}}">' +
|
2016-10-05 21:35:46 +03:00
|
|
|
'<div class="avatar" data-username="{{shareInitiator}}"></div>' +
|
|
|
|
'<span class="has-tooltip username" title="{{shareInitiator}}">' + t('core', '{{shareInitiatorDisplayName}} shared via link') + '</span>' +
|
|
|
|
|
|
|
|
'<span class="sharingOptionsGroup">' +
|
|
|
|
'<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>' +
|
2016-08-28 21:59:12 +03:00
|
|
|
'</li>' +
|
|
|
|
'{{/each}}' +
|
|
|
|
'</ul>'
|
|
|
|
;
|
2015-08-25 17:07:14 +03:00
|
|
|
|
2016-11-29 14:51:37 +03:00
|
|
|
var TEMPLATE_POPOVER_MENU =
|
|
|
|
'<div class="popovermenu bubble hidden menu">' +
|
|
|
|
'<ul>' +
|
|
|
|
'{{#if isResharingAllowed}} {{#if sharePermissionPossible}} {{#unless isMailShare}}' +
|
|
|
|
'<li>' +
|
2017-01-21 21:02:48 +03:00
|
|
|
'<span class="shareOption menuitem">' +
|
2016-11-29 14:51:37 +03:00
|
|
|
'<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>' +
|
|
|
|
'{{/unless}} {{/if}} {{/if}}' +
|
|
|
|
'{{#if isFolder}}' +
|
|
|
|
'{{#if createPermissionPossible}}{{#unless isMailShare}}' +
|
|
|
|
'<li>' +
|
2017-01-21 21:02:48 +03:00
|
|
|
'<span class="shareOption menuitem">' +
|
2016-11-29 14:51:37 +03:00
|
|
|
'<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>' +
|
|
|
|
'{{/unless}}{{/if}}' +
|
|
|
|
'{{#if updatePermissionPossible}}{{#unless isMailShare}}' +
|
|
|
|
'<li>' +
|
2017-01-21 21:02:48 +03:00
|
|
|
'<span class="shareOption menuitem">' +
|
2016-11-29 14:51:37 +03:00
|
|
|
'<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>' +
|
|
|
|
'{{/unless}}{{/if}}' +
|
|
|
|
'{{#if deletePermissionPossible}}{{#unless isMailShare}}' +
|
|
|
|
'<li>' +
|
2017-01-21 21:02:48 +03:00
|
|
|
'<span class="shareOption menuitem">' +
|
2016-11-29 14:51:37 +03:00
|
|
|
'<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>' +
|
|
|
|
'{{/unless}}{{/if}}' +
|
|
|
|
'{{/if}}' +
|
2017-03-29 12:58:04 +03:00
|
|
|
'{{#if isMailShare}}' +
|
|
|
|
'{{#if hasCreatePermission}}' +
|
|
|
|
'<li>' +
|
|
|
|
'<span class="shareOption menuitem">' +
|
|
|
|
'<input id="secureDrop-{{cid}}-{{shareId}}" type="checkbox" name="secureDrop" class="checkbox secureDrop" {{#if secureDropMode}}checked="checked"{{/if}} data-permissions="{{readPermission}}"/>' +
|
|
|
|
'<label for="secureDrop-{{cid}}-{{shareId}}">{{secureDropLabel}}</label>' +
|
|
|
|
'</span>' +
|
|
|
|
'</li>' +
|
|
|
|
'{{/if}}' +
|
2017-03-28 15:39:38 +03:00
|
|
|
'<li>' +
|
|
|
|
'<span class="shareOption menuitem">' +
|
2017-04-11 22:29:54 +03:00
|
|
|
'<input id="password-{{cid}}-{{shareId}}" type="checkbox" name="password" class="password checkbox" {{#if isPasswordSet}}checked="checked"{{/if}}{{#if isPasswordSet}}{{#if isPasswordForMailSharesRequired}}disabled=""{{/if}}{{/if}}" />' +
|
2017-03-28 15:39:38 +03:00
|
|
|
'<label for="password-{{cid}}-{{shareId}}">{{passwordLabel}}</label>' +
|
|
|
|
'<div class="passwordContainer-{{cid}}-{{shareId}} {{#unless isPasswordSet}}hidden{{/unless}}">' +
|
|
|
|
' <label for="passwordField-{{cid}}-{{shareId}}" class="hidden-visually" value="{{password}}">{{passwordLabel}}</label>' +
|
2018-02-28 15:47:06 +03:00
|
|
|
' <input id="passwordField-{{cid}}-{{shareId}}" class="passwordField" type="password" placeholder="{{passwordPlaceholder}}" value="{{passwordValue}}" autocomplete="new-password" />' +
|
2017-03-28 15:39:38 +03:00
|
|
|
' <span class="icon-loading-small hidden"></span>' +
|
|
|
|
'</div>' +
|
|
|
|
'</span>' +
|
|
|
|
'</li>' +
|
|
|
|
'{{/if}}' +
|
2017-03-30 16:30:44 +03:00
|
|
|
'<li>' +
|
|
|
|
'<span class="shareOption menuitem">' +
|
|
|
|
'<input id="expireDate-{{cid}}-{{shareId}}" type="checkbox" name="expirationDate" class="expireDate checkbox" {{#if hasExpireDate}}checked="checked"{{/if}}" />' +
|
|
|
|
'<label for="expireDate-{{cid}}-{{shareId}}">{{expireDateLabel}}</label>' +
|
|
|
|
'<div class="expirationDateContainer-{{cid}}-{{shareId}} {{#unless hasExpireDate}}hidden{{/unless}}">' +
|
|
|
|
' <label for="expirationDatePicker-{{cid}}-{{shareId}}" class="hidden-visually" value="{{expirationDate}}">{{expirationLabel}}</label>' +
|
2018-01-05 10:26:01 +03:00
|
|
|
' <input id="expirationDatePicker-{{cid}}-{{shareId}}" class="datepicker" type="text" placeholder="{{expirationDatePlaceholder}}" value="{{#if hasExpireDate}}{{expireDate}}{{else}}{{defaultExpireDate}}{{/if}}" />' +
|
2017-03-30 16:30:44 +03:00
|
|
|
'</div>' +
|
|
|
|
'</span>' +
|
|
|
|
'</li>' +
|
2017-03-28 15:39:38 +03:00
|
|
|
'<li>' +
|
2016-11-29 14:51:37 +03:00
|
|
|
'<a href="#" class="unshare"><span class="icon-loading-small hidden"></span><span class="icon icon-delete"></span><span>{{unshareLabel}}</span></a>' +
|
|
|
|
'</li>' +
|
|
|
|
'</ul>' +
|
|
|
|
'</div>';
|
|
|
|
|
2015-08-25 17:07:14 +03:00
|
|
|
/**
|
|
|
|
* @class OCA.Share.ShareDialogShareeListView
|
|
|
|
* @member {OC.Share.ShareItemModel} model
|
|
|
|
* @member {jQuery} $el
|
|
|
|
* @memberof OCA.Sharing
|
|
|
|
* @classdesc
|
|
|
|
*
|
|
|
|
* Represents the sharee list part in the GUI of the share dialogue
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
var ShareDialogShareeListView = OC.Backbone.View.extend({
|
|
|
|
/** @type {string} **/
|
|
|
|
id: 'shareDialogLinkShare',
|
|
|
|
|
|
|
|
/** @type {OC.Share.ShareConfigModel} **/
|
|
|
|
configModel: undefined,
|
|
|
|
|
|
|
|
/** @type {Function} **/
|
|
|
|
_template: undefined,
|
|
|
|
|
2016-11-29 14:51:37 +03:00
|
|
|
/** @type {Function} **/
|
|
|
|
_popoverMenuTemplate: undefined,
|
|
|
|
|
2016-07-28 11:46:00 +03:00
|
|
|
_menuOpen: false,
|
|
|
|
|
2016-11-29 14:51:37 +03:00
|
|
|
/** @type {boolean|number} **/
|
|
|
|
_renderPermissionChange: false,
|
|
|
|
|
2015-09-14 18:47:47 +03:00
|
|
|
events: {
|
|
|
|
'click .unshare': 'onUnshare',
|
2016-07-27 16:08:24 +03:00
|
|
|
'click .icon-more': 'onToggleMenu',
|
2015-09-14 18:47:47 +03:00
|
|
|
'click .permissions': 'onPermissionChange',
|
2017-03-28 15:39:38 +03:00
|
|
|
'click .expireDate' : 'onExpireDateChange',
|
|
|
|
'click .password' : 'onMailSharePasswordProtectChange',
|
2017-03-29 12:58:04 +03:00
|
|
|
'click .secureDrop' : 'onSecureDropChange',
|
2017-03-28 15:39:38 +03:00
|
|
|
'keyup input.passwordField': 'onMailSharePasswordKeyUp',
|
2017-03-29 17:50:23 +03:00
|
|
|
'focusout input.passwordField': 'onMailSharePasswordEntered',
|
|
|
|
'change .datepicker': 'onChangeExpirationDate',
|
|
|
|
'click .datepicker' : 'showDatePicker'
|
2015-09-14 18:47:47 +03:00
|
|
|
},
|
|
|
|
|
2015-08-25 17:07:14 +03:00
|
|
|
initialize: function(options) {
|
|
|
|
if(!_.isUndefined(options.configModel)) {
|
|
|
|
this.configModel = options.configModel;
|
|
|
|
} else {
|
|
|
|
throw 'missing OC.Share.ShareConfigModel';
|
|
|
|
}
|
2015-09-01 13:43:04 +03:00
|
|
|
|
|
|
|
var view = this;
|
|
|
|
this.model.on('change:shares', function() {
|
|
|
|
view.render();
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param {OC.Share.Types.ShareInfo} shareInfo
|
|
|
|
* @returns {object}
|
|
|
|
*/
|
|
|
|
getShareeObject: function(shareIndex) {
|
|
|
|
var shareWith = this.model.getShareWith(shareIndex);
|
|
|
|
var shareWithDisplayName = this.model.getShareWithDisplayName(shareIndex);
|
2016-10-25 17:24:49 +03:00
|
|
|
var shareWithTitle = '';
|
2015-09-01 13:43:04 +03:00
|
|
|
var shareType = this.model.getShareType(shareIndex);
|
2017-04-10 18:07:45 +03:00
|
|
|
var sharedBy = this.model.getSharedBy(shareIndex);
|
|
|
|
var sharedByDisplayName = this.model.getSharedByDisplayName(shareIndex);
|
2015-09-01 13:43:04 +03:00
|
|
|
|
2015-09-02 18:27:25 +03:00
|
|
|
var hasPermissionOverride = {};
|
2015-09-01 13:43:04 +03:00
|
|
|
if (shareType === OC.Share.SHARE_TYPE_GROUP) {
|
|
|
|
shareWithDisplayName = shareWithDisplayName + " (" + t('core', 'group') + ')';
|
|
|
|
} else if (shareType === OC.Share.SHARE_TYPE_REMOTE) {
|
|
|
|
shareWithDisplayName = shareWithDisplayName + " (" + t('core', 'remote') + ')';
|
2016-10-25 17:24:49 +03:00
|
|
|
} else if (shareType === OC.Share.SHARE_TYPE_EMAIL) {
|
|
|
|
shareWithDisplayName = shareWithDisplayName + " (" + t('core', 'email') + ')';
|
2017-03-17 22:48:33 +03:00
|
|
|
} else if (shareType === OC.Share.SHARE_TYPE_CIRCLE) {
|
2016-10-25 17:24:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (shareType === OC.Share.SHARE_TYPE_GROUP) {
|
|
|
|
shareWithTitle = shareWith + " (" + t('core', 'group') + ')';
|
|
|
|
} else if (shareType === OC.Share.SHARE_TYPE_REMOTE) {
|
|
|
|
shareWithTitle = shareWith + " (" + t('core', 'remote') + ')';
|
|
|
|
} else if (shareType === OC.Share.SHARE_TYPE_EMAIL) {
|
|
|
|
shareWithTitle = shareWith + " (" + t('core', 'email') + ')';
|
2017-03-17 22:48:33 +03:00
|
|
|
} else if (shareType === OC.Share.SHARE_TYPE_CIRCLE) {
|
|
|
|
shareWithTitle = shareWith;
|
2015-09-01 13:43:04 +03:00
|
|
|
}
|
|
|
|
|
2017-04-10 18:07:45 +03:00
|
|
|
if (sharedBy !== oc_current_user) {
|
|
|
|
var empty = shareWithTitle === '';
|
|
|
|
if (!empty) {
|
|
|
|
shareWithTitle += ' (';
|
|
|
|
}
|
|
|
|
shareWithTitle += t('core', 'shared by {sharer}', {sharer: sharedByDisplayName});
|
|
|
|
if (!empty) {
|
|
|
|
shareWithTitle += ')';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-28 15:39:38 +03:00
|
|
|
var share = this.model.get('shares')[shareIndex];
|
|
|
|
var password = share.password;
|
|
|
|
var hasPassword = password !== null && password !== '';
|
|
|
|
|
|
|
|
|
2015-09-02 18:27:25 +03:00
|
|
|
return _.extend(hasPermissionOverride, {
|
2015-10-16 11:54:45 +03:00
|
|
|
cid: this.cid,
|
2015-09-01 13:43:04 +03:00
|
|
|
hasSharePermission: this.model.hasSharePermission(shareIndex),
|
2018-02-15 23:10:39 +03:00
|
|
|
editPermissionState: this.model.editPermissionState(shareIndex),
|
2015-09-01 13:43:04 +03:00
|
|
|
hasCreatePermission: this.model.hasCreatePermission(shareIndex),
|
|
|
|
hasUpdatePermission: this.model.hasUpdatePermission(shareIndex),
|
|
|
|
hasDeletePermission: this.model.hasDeletePermission(shareIndex),
|
|
|
|
shareWith: shareWith,
|
|
|
|
shareWithDisplayName: shareWithDisplayName,
|
2016-10-25 17:24:49 +03:00
|
|
|
shareWithTitle: shareWithTitle,
|
2015-09-01 13:43:04 +03:00
|
|
|
shareType: shareType,
|
2016-01-22 19:30:18 +03:00
|
|
|
shareId: this.model.get('shares')[shareIndex].id,
|
2015-09-02 17:47:25 +03:00
|
|
|
modSeed: shareType !== OC.Share.SHARE_TYPE_USER,
|
2016-10-26 12:27:43 +03:00
|
|
|
isRemoteShare: shareType === OC.Share.SHARE_TYPE_REMOTE,
|
|
|
|
isMailShare: shareType === OC.Share.SHARE_TYPE_EMAIL,
|
2017-03-17 22:48:33 +03:00
|
|
|
isCircleShare: shareType === OC.Share.SHARE_TYPE_CIRCLE,
|
2017-03-28 15:39:38 +03:00
|
|
|
isFileSharedByMail: shareType === OC.Share.SHARE_TYPE_EMAIL && !this.model.isFolder(),
|
|
|
|
isPasswordSet: hasPassword,
|
2017-03-29 12:58:04 +03:00
|
|
|
secureDropMode: !this.model.hasReadPermission(shareIndex),
|
2017-03-29 17:50:23 +03:00
|
|
|
hasExpireDate: this.model.getExpireDate(shareIndex) !== null,
|
2017-04-07 14:54:32 +03:00
|
|
|
expireDate: moment(this.model.getExpireDate(shareIndex), 'YYYY-MM-DD').format('DD-MM-YYYY'),
|
2017-03-28 15:39:38 +03:00
|
|
|
passwordPlaceholder: hasPassword ? PASSWORD_PLACEHOLDER : PASSWORD_PLACEHOLDER_MESSAGE,
|
2015-09-02 18:27:25 +03:00
|
|
|
});
|
2015-08-25 17:07:14 +03:00
|
|
|
},
|
|
|
|
|
2016-11-29 14:51:37 +03:00
|
|
|
getShareProperties: function() {
|
|
|
|
return {
|
2015-08-25 17:07:14 +03:00
|
|
|
unshareLabel: t('core', 'Unshare'),
|
2017-03-29 19:13:12 +03:00
|
|
|
canShareLabel: t('core', 'Can reshare'),
|
|
|
|
canEditLabel: t('core', 'Can edit'),
|
|
|
|
createPermissionLabel: t('core', 'Can create'),
|
|
|
|
updatePermissionLabel: t('core', 'Can change'),
|
|
|
|
deletePermissionLabel: t('core', 'Can delete'),
|
2017-05-18 17:53:10 +03:00
|
|
|
secureDropLabel: t('core', 'File drop (upload only)'),
|
2017-03-29 19:13:12 +03:00
|
|
|
expireDateLabel: t('core', 'Set expiration date'),
|
|
|
|
passwordLabel: t('core', 'Password protect'),
|
|
|
|
crudsLabel: t('core', 'Access control'),
|
2018-01-05 10:26:01 +03:00
|
|
|
expirationDatePlaceholder: t('core', 'Expiration date'),
|
|
|
|
defaultExpireDate: moment().add(1, 'day').format('DD-MM-YYYY'), // Can't expire today
|
2015-09-01 13:43:04 +03:00
|
|
|
triangleSImage: OC.imagePath('core', 'actions/triangle-s'),
|
2015-09-05 03:02:55 +03:00
|
|
|
isResharingAllowed: this.configModel.get('isResharingAllowed'),
|
2017-04-10 19:36:23 +03:00
|
|
|
isPasswordForMailSharesRequired: this.configModel.get('isPasswordForMailSharesRequired'),
|
2015-09-01 13:43:04 +03:00
|
|
|
sharePermissionPossible: this.model.sharePermissionPossible(),
|
|
|
|
editPermissionPossible: this.model.editPermissionPossible(),
|
|
|
|
createPermissionPossible: this.model.createPermissionPossible(),
|
|
|
|
updatePermissionPossible: this.model.updatePermissionPossible(),
|
|
|
|
deletePermissionPossible: this.model.deletePermissionPossible(),
|
|
|
|
sharePermission: OC.PERMISSION_SHARE,
|
|
|
|
createPermission: OC.PERMISSION_CREATE,
|
|
|
|
updatePermission: OC.PERMISSION_UPDATE,
|
2016-07-20 16:24:51 +03:00
|
|
|
deletePermission: OC.PERMISSION_DELETE,
|
2017-03-29 12:58:04 +03:00
|
|
|
readPermission: OC.PERMISSION_READ,
|
2016-07-20 16:24:51 +03:00
|
|
|
isFolder: this.model.isFolder()
|
2015-08-25 17:07:14 +03:00
|
|
|
};
|
2016-11-29 14:51:37 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* get an array of sharees' share properties
|
|
|
|
*
|
|
|
|
* @returns {Array}
|
|
|
|
*/
|
|
|
|
getShareeList: function() {
|
|
|
|
var universal = this.getShareProperties();
|
2015-08-25 17:07:14 +03:00
|
|
|
|
2015-09-14 18:20:51 +03:00
|
|
|
if(!this.model.hasUserShares()) {
|
2015-09-01 13:43:04 +03:00
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
2015-09-02 14:06:00 +03:00
|
|
|
var shares = this.model.get('shares');
|
2015-09-01 13:43:04 +03:00
|
|
|
var list = [];
|
2015-09-02 14:06:00 +03:00
|
|
|
for(var index = 0; index < shares.length; index++) {
|
2016-08-28 21:59:12 +03:00
|
|
|
var share = this.getShareeObject(index);
|
|
|
|
|
|
|
|
if (share.shareType === OC.Share.SHARE_TYPE_LINK) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// first empty {} is necessary, otherwise we get in trouble
|
|
|
|
// with references
|
|
|
|
list.push(_.extend({}, universal, share));
|
|
|
|
}
|
|
|
|
|
|
|
|
return list;
|
|
|
|
},
|
|
|
|
|
|
|
|
getLinkReshares: function() {
|
|
|
|
var universal = {
|
|
|
|
unshareLabel: t('core', 'Unshare'),
|
|
|
|
};
|
|
|
|
|
|
|
|
if(!this.model.hasUserShares()) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
var shares = this.model.get('shares');
|
|
|
|
var list = [];
|
|
|
|
for(var index = 0; index < shares.length; index++) {
|
|
|
|
var share = this.getShareeObject(index);
|
|
|
|
|
|
|
|
if (share.shareType !== OC.Share.SHARE_TYPE_LINK) {
|
|
|
|
continue;
|
|
|
|
}
|
2016-01-22 19:30:18 +03:00
|
|
|
// first empty {} is necessary, otherwise we get in trouble
|
|
|
|
// with references
|
2016-08-28 21:59:12 +03:00
|
|
|
list.push(_.extend({}, universal, share, {
|
|
|
|
shareInitiator: shares[index].uid_owner,
|
|
|
|
shareInitiatorDisplayName: shares[index].displayname_owner
|
|
|
|
}));
|
2015-09-01 13:43:04 +03:00
|
|
|
}
|
2015-08-25 17:07:14 +03:00
|
|
|
|
|
|
|
return list;
|
|
|
|
},
|
|
|
|
|
|
|
|
render: function() {
|
2016-11-29 14:51:37 +03:00
|
|
|
if(!this._renderPermissionChange) {
|
|
|
|
this.$el.html(this.template({
|
|
|
|
cid: this.cid,
|
|
|
|
sharees: this.getShareeList(),
|
|
|
|
linkReshares: this.getLinkReshares()
|
|
|
|
}));
|
|
|
|
|
2017-02-14 02:49:05 +03:00
|
|
|
this.$('.avatar').each(function () {
|
|
|
|
var $this = $(this);
|
|
|
|
if ($this.hasClass('imageplaceholderseed')) {
|
|
|
|
$this.css({width: 32, height: 32});
|
|
|
|
$this.imageplaceholder($this.data('seed'));
|
|
|
|
} else {
|
|
|
|
// user, size, ie8fix, hidedefault, callback, displayname
|
|
|
|
$this.avatar($this.data('username'), 32, undefined, undefined, undefined, $this.data('displayname'));
|
|
|
|
}
|
|
|
|
});
|
2016-11-29 14:51:37 +03:00
|
|
|
|
|
|
|
this.$('.has-tooltip').tooltip({
|
|
|
|
placement: 'bottom'
|
2015-09-12 15:21:14 +03:00
|
|
|
});
|
2017-04-24 12:39:03 +03:00
|
|
|
|
|
|
|
this.$('ul.shareWithList > li').each(function() {
|
|
|
|
var $this = $(this);
|
|
|
|
|
|
|
|
var shareWith = $this.data('share-with');
|
|
|
|
var shareType = $this.data('share-type');
|
|
|
|
|
|
|
|
$this.find('div.avatar, span.username').contactsMenu(shareWith, shareType, $this);
|
2017-05-01 06:42:53 +03:00
|
|
|
});
|
2016-11-29 14:51:37 +03:00
|
|
|
} else {
|
|
|
|
var permissionChangeShareId = parseInt(this._renderPermissionChange, 10);
|
|
|
|
var shareWithIndex = this.model.findShareWithIndex(permissionChangeShareId);
|
|
|
|
var sharee = this.getShareeObject(shareWithIndex);
|
|
|
|
$.extend(sharee, this.getShareProperties());
|
|
|
|
var $li = this.$('li[data-share-id=' + permissionChangeShareId + ']');
|
2017-11-17 19:08:29 +03:00
|
|
|
$li.find('.sharingOptionsGroup .popovermenu').replaceWith(this.popoverMenuTemplate(sharee));
|
2018-02-16 00:41:09 +03:00
|
|
|
}
|
2016-11-29 17:44:43 +03:00
|
|
|
|
2018-02-16 00:41:09 +03:00
|
|
|
var _this = this;
|
|
|
|
this.getShareeList().forEach(function(sharee) {
|
|
|
|
var checkBoxId = 'canEdit-' + _this.cid + '-' + sharee.shareWith;
|
2018-02-16 13:42:41 +03:00
|
|
|
checkBoxId = '#' + checkBoxId.replace( /(:|\.|\[|\]|,|=|@|\/)/g, "\\$1");
|
2018-02-16 00:41:09 +03:00
|
|
|
var $edit = _this.$(checkBoxId);
|
2016-12-02 14:27:15 +03:00
|
|
|
if($edit.length === 1) {
|
2018-02-15 23:10:39 +03:00
|
|
|
$edit.prop('checked', sharee.editPermissionState === 'checked');
|
|
|
|
$edit.prop('indeterminate', sharee.editPermissionState === 'indeterminate');
|
2016-11-29 17:44:43 +03:00
|
|
|
}
|
2018-02-16 00:41:09 +03:00
|
|
|
});
|
2016-07-28 11:46:00 +03:00
|
|
|
this.$('.popovermenu').on('afterHide', function() {
|
|
|
|
_this._menuOpen = false;
|
|
|
|
});
|
2017-04-05 17:36:07 +03:00
|
|
|
this.$('.popovermenu').on('beforeHide', function() {
|
|
|
|
var shareId = parseInt(_this._menuOpen, 10);
|
|
|
|
if(!_.isNaN(shareId)) {
|
|
|
|
var datePickerClass = '.expirationDateContainer-' + _this.cid + '-' + shareId;
|
|
|
|
var datePickerInput = '#expirationDatePicker-' + _this.cid + '-' + shareId;
|
|
|
|
var expireDateCheckbox = '#expireDate-' + _this.cid + '-' + shareId;
|
|
|
|
if ($(expireDateCheckbox).prop('checked')) {
|
|
|
|
$(datePickerInput).removeClass('hidden-visually');
|
|
|
|
$(datePickerClass).removeClass('hasDatepicker');
|
|
|
|
$(datePickerClass + ' .ui-datepicker').hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2017-11-17 19:08:29 +03:00
|
|
|
if (this._menuOpen !== false) {
|
2016-07-28 11:46:00 +03:00
|
|
|
// Open menu again if it was opened before
|
2016-11-28 12:56:22 +03:00
|
|
|
var shareId = parseInt(this._menuOpen, 10);
|
|
|
|
if(!_.isNaN(shareId)) {
|
|
|
|
var liSelector = 'li[data-share-id=' + shareId + ']';
|
2017-11-17 19:08:29 +03:00
|
|
|
OC.showMenu(null, this.$(liSelector + ' .sharingOptionsGroup .popovermenu'));
|
2016-11-28 12:56:22 +03:00
|
|
|
}
|
2016-07-28 11:46:00 +03:00
|
|
|
}
|
|
|
|
|
2016-11-29 14:51:37 +03:00
|
|
|
this._renderPermissionChange = false;
|
|
|
|
|
2015-09-14 18:47:47 +03:00
|
|
|
this.delegateEvents();
|
2015-09-14 02:24:21 +03:00
|
|
|
|
2015-08-25 17:07:14 +03:00
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @returns {Function} from Handlebars
|
|
|
|
* @private
|
|
|
|
*/
|
2015-10-16 11:54:45 +03:00
|
|
|
template: function (data) {
|
2015-08-25 17:07:14 +03:00
|
|
|
if (!this._template) {
|
|
|
|
this._template = Handlebars.compile(TEMPLATE);
|
|
|
|
}
|
2016-12-02 14:27:15 +03:00
|
|
|
var sharees = data.sharees;
|
2016-11-29 14:51:37 +03:00
|
|
|
if(_.isArray(sharees)) {
|
|
|
|
for (var i = 0; i < sharees.length; i++) {
|
2016-12-02 14:27:15 +03:00
|
|
|
data.sharees[i].popoverMenu = this.popoverMenuTemplate(sharees[i]);
|
2016-11-29 14:51:37 +03:00
|
|
|
}
|
|
|
|
}
|
2015-10-16 11:54:45 +03:00
|
|
|
return this._template(data);
|
2015-09-14 02:24:21 +03:00
|
|
|
},
|
|
|
|
|
2016-11-29 14:51:37 +03:00
|
|
|
/**
|
|
|
|
* renders the popover template and returns the resulting HTML
|
|
|
|
*
|
|
|
|
* @param {Object} data
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
popoverMenuTemplate: function(data) {
|
|
|
|
if(!this._popoverMenuTemplate) {
|
|
|
|
this._popoverMenuTemplate = Handlebars.compile(TEMPLATE_POPOVER_MENU);
|
|
|
|
}
|
|
|
|
return this._popoverMenuTemplate(data);
|
|
|
|
},
|
|
|
|
|
2015-09-14 18:47:47 +03:00
|
|
|
onUnshare: function(event) {
|
2016-07-27 16:08:24 +03:00
|
|
|
event.preventDefault();
|
|
|
|
event.stopPropagation();
|
2016-01-22 19:30:18 +03:00
|
|
|
var self = this;
|
2015-09-14 18:47:47 +03:00
|
|
|
var $element = $(event.target);
|
2015-12-07 19:58:17 +03:00
|
|
|
if (!$element.is('a')) {
|
|
|
|
$element = $element.closest('a');
|
|
|
|
}
|
2015-09-14 02:24:21 +03:00
|
|
|
|
2015-12-07 19:58:17 +03:00
|
|
|
var $loading = $element.find('.icon-loading-small').eq(0);
|
2015-09-25 13:11:50 +03:00
|
|
|
if(!$loading.hasClass('hidden')) {
|
2015-09-14 02:24:21 +03:00
|
|
|
// in process
|
2015-12-07 19:58:17 +03:00
|
|
|
return false;
|
2015-09-14 02:24:21 +03:00
|
|
|
}
|
2015-09-25 13:11:50 +03:00
|
|
|
$loading.removeClass('hidden');
|
2015-09-14 02:24:21 +03:00
|
|
|
|
2016-07-27 16:08:24 +03:00
|
|
|
var $li = $element.closest('li[data-share-id]');
|
2015-09-14 02:24:21 +03:00
|
|
|
|
2016-01-22 19:30:18 +03:00
|
|
|
var shareId = $li.data('share-id');
|
2015-09-14 02:24:21 +03:00
|
|
|
|
2016-01-22 19:30:18 +03:00
|
|
|
self.model.removeShare(shareId)
|
|
|
|
.done(function() {
|
|
|
|
$li.remove();
|
|
|
|
})
|
|
|
|
.fail(function() {
|
|
|
|
$loading.addClass('hidden');
|
|
|
|
OC.Notification.showTemporary(t('core', 'Could not unshare'));
|
|
|
|
});
|
2015-09-14 02:40:16 +03:00
|
|
|
return false;
|
|
|
|
},
|
|
|
|
|
2016-07-27 16:08:24 +03:00
|
|
|
onToggleMenu: function(event) {
|
|
|
|
event.preventDefault();
|
|
|
|
event.stopPropagation();
|
|
|
|
var $element = $(event.target);
|
|
|
|
var $li = $element.closest('li[data-share-id]');
|
2017-04-24 14:04:49 +03:00
|
|
|
var $menu = $li.find('.sharingOptionsGroup .popovermenu');
|
2016-07-27 16:08:24 +03:00
|
|
|
|
|
|
|
OC.showMenu(null, $menu);
|
2016-11-28 12:56:22 +03:00
|
|
|
this._menuOpen = $li.data('share-id');
|
2016-07-27 16:08:24 +03:00
|
|
|
},
|
|
|
|
|
2017-03-27 23:03:10 +03:00
|
|
|
onExpireDateChange: function(event) {
|
|
|
|
var element = $(event.target);
|
|
|
|
var li = element.closest('li[data-share-id]');
|
|
|
|
var shareId = li.data('share-id');
|
|
|
|
var datePickerClass = '.expirationDateContainer-' + this.cid + '-' + shareId;
|
|
|
|
var datePicker = $(datePickerClass);
|
|
|
|
var state = element.prop('checked');
|
|
|
|
datePicker.toggleClass('hidden', !state);
|
|
|
|
if (!state) {
|
2017-03-29 17:50:23 +03:00
|
|
|
this.setExpirationDate(shareId, '');
|
2017-03-27 23:03:10 +03:00
|
|
|
} else {
|
2017-03-29 17:50:23 +03:00
|
|
|
this.showDatePicker(event);
|
|
|
|
|
2017-03-27 23:03:10 +03:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2017-03-29 17:50:23 +03:00
|
|
|
showDatePicker: function(event) {
|
|
|
|
var element = $(event.target);
|
|
|
|
var li = element.closest('li[data-share-id]');
|
|
|
|
var shareId = li.data('share-id');
|
|
|
|
var expirationDatePicker = '#expirationDatePicker-' + this.cid + '-' + shareId;
|
2017-04-05 17:36:07 +03:00
|
|
|
var view = this;
|
2017-12-13 13:11:05 +03:00
|
|
|
$(expirationDatePicker).datepicker({
|
2017-04-05 17:36:07 +03:00
|
|
|
dateFormat : 'dd-mm-yy',
|
2017-12-13 13:11:05 +03:00
|
|
|
onSelect: function (expireDate) {
|
|
|
|
view.setExpirationDate(shareId, expireDate);
|
|
|
|
}
|
2017-04-05 17:36:07 +03:00
|
|
|
});
|
2017-12-13 13:11:05 +03:00
|
|
|
$(expirationDatePicker).focus();
|
2017-03-29 17:50:23 +03:00
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
setExpirationDate: function(shareId, expireDate) {
|
|
|
|
this.model.updateShare(shareId, {expireDate: expireDate}, {});
|
|
|
|
},
|
|
|
|
|
2017-03-28 15:39:38 +03:00
|
|
|
onMailSharePasswordProtectChange: function(event) {
|
|
|
|
var element = $(event.target);
|
|
|
|
var li = element.closest('li[data-share-id]');
|
|
|
|
var shareId = li.data('share-id');
|
|
|
|
var passwordContainerClass = '.passwordContainer-' + this.cid + '-' + shareId;
|
|
|
|
var passwordContainer = $(passwordContainerClass);
|
2017-04-06 12:33:24 +03:00
|
|
|
var loading = this.$el.find(passwordContainerClass + ' .icon-loading-small');
|
2017-03-28 15:39:38 +03:00
|
|
|
var inputClass = '#passwordField-' + this.cid + '-' + shareId;
|
|
|
|
var passwordField = $(inputClass);
|
|
|
|
var state = element.prop('checked');
|
|
|
|
if (!state) {
|
|
|
|
this.model.updateShare(shareId, {password: ''});
|
|
|
|
passwordField.attr('value', '');
|
2017-04-06 12:33:24 +03:00
|
|
|
passwordField.removeClass('error');
|
|
|
|
passwordField.tooltip('hide');
|
|
|
|
loading.addClass('hidden');
|
2017-03-28 15:39:38 +03:00
|
|
|
passwordField.attr('placeholder', PASSWORD_PLACEHOLDER_MESSAGE);
|
2017-04-06 12:33:24 +03:00
|
|
|
// We first need to reset the password field before we hide it
|
|
|
|
passwordContainer.toggleClass('hidden', !state);
|
2017-03-28 15:39:38 +03:00
|
|
|
} else {
|
2017-04-06 12:33:24 +03:00
|
|
|
passwordContainer.toggleClass('hidden', !state);
|
2017-03-30 18:03:04 +03:00
|
|
|
passwordField = '#passwordField-' + this.cid + '-' + shareId;
|
2017-03-28 15:39:38 +03:00
|
|
|
this.$(passwordField).focus();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
onMailSharePasswordKeyUp: function(event) {
|
|
|
|
if(event.keyCode === 13) {
|
|
|
|
this.onMailSharePasswordEntered(event);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
onMailSharePasswordEntered: function(event) {
|
|
|
|
var passwordField = $(event.target);
|
|
|
|
var li = passwordField.closest('li[data-share-id]');
|
|
|
|
var shareId = li.data('share-id');
|
|
|
|
var passwordContainerClass = '.passwordContainer-' + this.cid + '-' + shareId;
|
|
|
|
var loading = this.$el.find(passwordContainerClass + ' .icon-loading-small');
|
|
|
|
if (!loading.hasClass('hidden')) {
|
|
|
|
// still in process
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
passwordField.removeClass('error');
|
|
|
|
var password = passwordField.val();
|
|
|
|
// in IE9 the password might be the placeholder due to bugs in the placeholders polyfill
|
|
|
|
if(password === '' || password === PASSWORD_PLACEHOLDER || password === PASSWORD_PLACEHOLDER_MESSAGE) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
loading
|
|
|
|
.removeClass('hidden')
|
|
|
|
.addClass('inlineblock');
|
|
|
|
|
|
|
|
|
|
|
|
this.model.updateShare(shareId, {
|
|
|
|
password: password
|
|
|
|
}, {
|
|
|
|
error: function(model, msg) {
|
|
|
|
// destroy old tooltips
|
|
|
|
passwordField.tooltip('destroy');
|
|
|
|
loading.removeClass('inlineblock').addClass('hidden');
|
|
|
|
passwordField.addClass('error');
|
|
|
|
passwordField.attr('title', msg);
|
|
|
|
passwordField.tooltip({placement: 'bottom', trigger: 'manual'});
|
|
|
|
passwordField.tooltip('show');
|
|
|
|
},
|
|
|
|
success: function(model, msg) {
|
|
|
|
passwordField.blur();
|
|
|
|
passwordField.attr('value', '');
|
|
|
|
passwordField.attr('placeholder', PASSWORD_PLACEHOLDER);
|
|
|
|
loading.removeClass('inlineblock').addClass('hidden');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2015-09-14 18:47:47 +03:00
|
|
|
onPermissionChange: function(event) {
|
2016-07-27 16:08:24 +03:00
|
|
|
event.preventDefault();
|
|
|
|
event.stopPropagation();
|
2015-09-14 18:47:47 +03:00
|
|
|
var $element = $(event.target);
|
2016-07-27 16:08:24 +03:00
|
|
|
var $li = $element.closest('li[data-share-id]');
|
2016-01-22 19:30:18 +03:00
|
|
|
var shareId = $li.data('share-id');
|
2015-09-14 03:29:22 +03:00
|
|
|
|
2016-08-10 11:32:59 +03:00
|
|
|
var permissions = OC.PERMISSION_READ;
|
|
|
|
|
|
|
|
if (this.model.isFolder()) {
|
|
|
|
// adjust checkbox states
|
|
|
|
var $checkboxes = $('.permissions', $li).not('input[name="edit"]').not('input[name="share"]');
|
|
|
|
var 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);
|
2016-12-06 17:41:10 +03:00
|
|
|
if (checked) {
|
|
|
|
permissions |= OC.PERMISSION_CREATE | OC.PERMISSION_UPDATE | OC.PERMISSION_DELETE;
|
|
|
|
}
|
2016-08-10 11:32:59 +03:00
|
|
|
} else {
|
|
|
|
var numberChecked = $checkboxes.filter(':checked').length;
|
2018-02-16 00:41:09 +03:00
|
|
|
checked = numberChecked === $checkboxes.length;
|
|
|
|
var $editCb = $('input[name="edit"]', $li);
|
|
|
|
$editCb.prop('checked', checked);
|
|
|
|
$editCb.prop('indeterminate', !checked && numberChecked > 0);
|
2016-08-10 11:32:59 +03:00
|
|
|
}
|
2016-12-06 17:41:10 +03:00
|
|
|
} else {
|
|
|
|
if ($element.attr('name') === 'edit' && $element.is(':checked')) {
|
|
|
|
permissions |= OC.PERMISSION_UPDATE;
|
|
|
|
}
|
2015-09-14 03:29:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
$('.permissions', $li).not('input[name="edit"]').filter(':checked').each(function(index, checkbox) {
|
|
|
|
permissions |= $(checkbox).data('permissions');
|
|
|
|
});
|
|
|
|
|
2016-12-02 15:14:25 +03:00
|
|
|
|
|
|
|
/** disable checkboxes during save operation to avoid race conditions **/
|
|
|
|
$li.find('input[type=checkbox]').prop('disabled', true);
|
|
|
|
var enableCb = function() {
|
|
|
|
$li.find('input[type=checkbox]').prop('disabled', false);
|
|
|
|
};
|
|
|
|
var errorCb = function(elem, msg) {
|
|
|
|
OC.dialogs.alert(msg, t('core', 'Error while sharing'));
|
|
|
|
enableCb();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.model.updateShare(shareId, {permissions: permissions}, {error: errorCb, success: enableCb});
|
2016-11-29 14:51:37 +03:00
|
|
|
|
|
|
|
this._renderPermissionChange = shareId;
|
2015-09-14 03:29:22 +03:00
|
|
|
},
|
2017-03-29 12:58:04 +03:00
|
|
|
|
|
|
|
onSecureDropChange: function(event) {
|
|
|
|
event.preventDefault();
|
|
|
|
event.stopPropagation();
|
|
|
|
var $element = $(event.target);
|
|
|
|
var $li = $element.closest('li[data-share-id]');
|
|
|
|
var shareId = $li.data('share-id');
|
|
|
|
|
2017-03-30 18:03:04 +03:00
|
|
|
var permissions = OC.PERMISSION_CREATE | OC.PERMISSION_UPDATE | OC.PERMISSION_DELETE | OC.PERMISSION_READ;
|
2017-03-29 12:58:04 +03:00
|
|
|
if ($element.is(':checked')) {
|
2017-03-30 18:03:04 +03:00
|
|
|
permissions = OC.PERMISSION_CREATE | OC.PERMISSION_UPDATE | OC.PERMISSION_DELETE;
|
2017-03-29 12:58:04 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/** disable checkboxes during save operation to avoid race conditions **/
|
|
|
|
$li.find('input[type=checkbox]').prop('disabled', true);
|
|
|
|
var enableCb = function() {
|
|
|
|
$li.find('input[type=checkbox]').prop('disabled', false);
|
|
|
|
};
|
|
|
|
var errorCb = function(elem, msg) {
|
|
|
|
OC.dialogs.alert(msg, t('core', 'Error while sharing'));
|
|
|
|
enableCb();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.model.updateShare(shareId, {permissions: permissions}, {error: errorCb, success: enableCb});
|
|
|
|
|
|
|
|
this._renderPermissionChange = shareId;
|
|
|
|
}
|
|
|
|
|
2015-08-25 17:07:14 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
OC.Share.ShareDialogShareeListView = ShareDialogShareeListView;
|
|
|
|
|
|
|
|
})();
|