You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

299 lines
10 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. /*
  2. * Copyright (c) 2015
  3. *
  4. * This file is licensed under the Affero General Public License version 3
  5. * or later.
  6. *
  7. * See the COPYING-README file.
  8. *
  9. */
  10. (function() {
  11. if (!OC.Share) {
  12. OC.Share = {};
  13. }
  14. var TEMPLATE =
  15. '<ul id="shareWithList" class="shareWithList">' +
  16. '{{#each sharees}}' +
  17. '<li data-share-id="{{shareId}}" data-share-type="{{shareType}}" data-share-with="{{shareWith}}">' +
  18. '<a href="#" class="unshare"><span class="icon-loading-small hidden"></span><span class="icon icon-delete"></span><span class="hidden-visually">{{unshareLabel}}</span></a>' +
  19. '{{#if avatarEnabled}}' +
  20. '<div class="avatar {{#if modSeed}}imageplaceholderseed{{/if}}" data-username="{{shareWith}}" {{#if modSeed}}data-seed="{{shareWith}} {{shareType}}"{{/if}}></div>' +
  21. '{{/if}}' +
  22. '<span class="has-tooltip username" title="{{shareWith}}">{{shareWithDisplayName}}</span>' +
  23. '{{#if mailNotificationEnabled}} {{#unless isRemoteShare}}' +
  24. '<span class="shareOption">' +
  25. '<input id="mail-{{cid}}-{{shareWith}}" type="checkbox" name="mailNotification" class="mailNotification checkbox" {{#if wasMailSent}}checked="checked"{{/if}} />' +
  26. '<label for="mail-{{cid}}-{{shareWith}}">{{notifyByMailLabel}}</label>' +
  27. '</span>' +
  28. '{{/unless}} {{/if}}' +
  29. '{{#if isResharingAllowed}} {{#if sharePermissionPossible}}' +
  30. '<span class="shareOption">' +
  31. '<input id="canShare-{{cid}}-{{shareWith}}" type="checkbox" name="share" class="permissions checkbox" {{#if hasSharePermission}}checked="checked"{{/if}} data-permissions="{{sharePermission}}" />' +
  32. '<label for="canShare-{{cid}}-{{shareWith}}">{{canShareLabel}}</label>' +
  33. '</span>' +
  34. '{{/if}} {{/if}}' +
  35. '{{#if editPermissionPossible}}' +
  36. '<span class="shareOption">' +
  37. '<input id="canEdit-{{cid}}-{{shareWith}}" type="checkbox" name="edit" class="permissions checkbox" {{#if hasEditPermission}}checked="checked"{{/if}} />' +
  38. '<label for="canEdit-{{cid}}-{{shareWith}}">{{canEditLabel}}</label>' +
  39. '{{#if isFolder}}' +
  40. '<a href="#" class="showCruds"><img alt="{{crudsLabel}}" src="{{triangleSImage}}"/></a>' +
  41. '{{/if}}' +
  42. '</span>' +
  43. '{{/if}}' +
  44. '<div class="cruds hidden">' +
  45. '{{#if createPermissionPossible}}' +
  46. '<span class="shareOption">' +
  47. '<input id="canCreate-{{cid}}-{{shareWith}}" type="checkbox" name="create" class="permissions checkbox" {{#if hasCreatePermission}}checked="checked"{{/if}} data-permissions="{{createPermission}}"/>' +
  48. '<label for="canCreate-{{cid}}-{{shareWith}}">{{createPermissionLabel}}</label>' +
  49. '</span>' +
  50. '{{/if}}' +
  51. '{{#if updatePermissionPossible}}' +
  52. '<span class="shareOption">' +
  53. '<input id="canUpdate-{{cid}}-{{shareWith}}" type="checkbox" name="update" class="permissions checkbox" {{#if hasUpdatePermission}}checked="checked"{{/if}} data-permissions="{{updatePermission}}"/>' +
  54. '<label for="canUpdate-{{cid}}-{{shareWith}}">{{updatePermissionLabel}}</label>' +
  55. '</span>' +
  56. '{{/if}}' +
  57. '{{#if deletePermissionPossible}}' +
  58. '<span class="shareOption">' +
  59. '<input id="canDelete-{{cid}}-{{shareWith}}" type="checkbox" name="delete" class="permissions checkbox" {{#if hasDeletePermission}}checked="checked"{{/if}} data-permissions="{{deletePermission}}"/>' +
  60. '<label for="canDelete-{{cid}}-{{shareWith}}">{{deletePermissionLabel}}</label>' +
  61. '</span>' +
  62. '{{/if}}' +
  63. '</div>' +
  64. '</li>' +
  65. '{{/each}}' +
  66. '</ul>'
  67. ;
  68. /**
  69. * @class OCA.Share.ShareDialogShareeListView
  70. * @member {OC.Share.ShareItemModel} model
  71. * @member {jQuery} $el
  72. * @memberof OCA.Sharing
  73. * @classdesc
  74. *
  75. * Represents the sharee list part in the GUI of the share dialogue
  76. *
  77. */
  78. var ShareDialogShareeListView = OC.Backbone.View.extend({
  79. /** @type {string} **/
  80. id: 'shareDialogLinkShare',
  81. /** @type {OC.Share.ShareConfigModel} **/
  82. configModel: undefined,
  83. /** @type {Function} **/
  84. _template: undefined,
  85. events: {
  86. 'click .unshare': 'onUnshare',
  87. 'click .permissions': 'onPermissionChange',
  88. 'click .showCruds': 'onCrudsToggle',
  89. 'click .mailNotification': 'onSendMailNotification'
  90. },
  91. initialize: function(options) {
  92. if(!_.isUndefined(options.configModel)) {
  93. this.configModel = options.configModel;
  94. } else {
  95. throw 'missing OC.Share.ShareConfigModel';
  96. }
  97. var view = this;
  98. this.model.on('change:shares', function() {
  99. view.render();
  100. });
  101. },
  102. /**
  103. *
  104. * @param {OC.Share.Types.ShareInfo} shareInfo
  105. * @returns {object}
  106. */
  107. getShareeObject: function(shareIndex) {
  108. var shareWith = this.model.getShareWith(shareIndex);
  109. var shareWithDisplayName = this.model.getShareWithDisplayName(shareIndex);
  110. var shareType = this.model.getShareType(shareIndex);
  111. var hasPermissionOverride = {};
  112. if (shareType === OC.Share.SHARE_TYPE_GROUP) {
  113. shareWithDisplayName = shareWithDisplayName + " (" + t('core', 'group') + ')';
  114. } else if (shareType === OC.Share.SHARE_TYPE_REMOTE) {
  115. shareWithDisplayName = shareWithDisplayName + " (" + t('core', 'remote') + ')';
  116. }
  117. return _.extend(hasPermissionOverride, {
  118. cid: this.cid,
  119. hasSharePermission: this.model.hasSharePermission(shareIndex),
  120. hasEditPermission: this.model.hasEditPermission(shareIndex),
  121. hasCreatePermission: this.model.hasCreatePermission(shareIndex),
  122. hasUpdatePermission: this.model.hasUpdatePermission(shareIndex),
  123. hasDeletePermission: this.model.hasDeletePermission(shareIndex),
  124. wasMailSent: this.model.notificationMailWasSent(shareIndex),
  125. shareWith: shareWith,
  126. shareWithDisplayName: shareWithDisplayName,
  127. shareType: shareType,
  128. shareId: this.model.get('shares')[shareIndex].id,
  129. modSeed: shareType !== OC.Share.SHARE_TYPE_USER,
  130. isRemoteShare: shareType === OC.Share.SHARE_TYPE_REMOTE
  131. });
  132. },
  133. getShareeList: function() {
  134. var universal = {
  135. avatarEnabled: this.configModel.areAvatarsEnabled(),
  136. mailNotificationEnabled: this.configModel.isMailNotificationEnabled(),
  137. notifyByMailLabel: t('core', 'notify by email'),
  138. unshareLabel: t('core', 'Unshare'),
  139. canShareLabel: t('core', 'can share'),
  140. canEditLabel: t('core', 'can edit'),
  141. createPermissionLabel: t('core', 'create'),
  142. updatePermissionLabel: t('core', 'change'),
  143. deletePermissionLabel: t('core', 'delete'),
  144. crudsLabel: t('core', 'access control'),
  145. triangleSImage: OC.imagePath('core', 'actions/triangle-s'),
  146. isResharingAllowed: this.configModel.get('isResharingAllowed'),
  147. sharePermissionPossible: this.model.sharePermissionPossible(),
  148. editPermissionPossible: this.model.editPermissionPossible(),
  149. createPermissionPossible: this.model.createPermissionPossible(),
  150. updatePermissionPossible: this.model.updatePermissionPossible(),
  151. deletePermissionPossible: this.model.deletePermissionPossible(),
  152. sharePermission: OC.PERMISSION_SHARE,
  153. createPermission: OC.PERMISSION_CREATE,
  154. updatePermission: OC.PERMISSION_UPDATE,
  155. deletePermission: OC.PERMISSION_DELETE,
  156. isFolder: this.model.isFolder()
  157. };
  158. if(!this.model.hasUserShares()) {
  159. return [];
  160. }
  161. var shares = this.model.get('shares');
  162. var list = [];
  163. for(var index = 0; index < shares.length; index++) {
  164. // first empty {} is necessary, otherwise we get in trouble
  165. // with references
  166. list.push(_.extend({}, universal, this.getShareeObject(index)));
  167. }
  168. return list;
  169. },
  170. render: function() {
  171. this.$el.html(this.template({
  172. cid: this.cid,
  173. sharees: this.getShareeList()
  174. }));
  175. if(this.configModel.areAvatarsEnabled()) {
  176. this.$el.find('.avatar').each(function() {
  177. var $this = $(this);
  178. if ($this.hasClass('imageplaceholderseed')) {
  179. $this.css({width: 32, height: 32});
  180. $this.imageplaceholder($this.data('seed'));
  181. } else {
  182. $this.avatar($this.data('username'), 32);
  183. }
  184. });
  185. }
  186. this.$el.find('.has-tooltip').tooltip({
  187. placement: 'bottom'
  188. });
  189. this.delegateEvents();
  190. return this;
  191. },
  192. /**
  193. * @returns {Function} from Handlebars
  194. * @private
  195. */
  196. template: function (data) {
  197. if (!this._template) {
  198. this._template = Handlebars.compile(TEMPLATE);
  199. }
  200. return this._template(data);
  201. },
  202. onUnshare: function(event) {
  203. var self = this;
  204. var $element = $(event.target);
  205. if (!$element.is('a')) {
  206. $element = $element.closest('a');
  207. }
  208. var $loading = $element.find('.icon-loading-small').eq(0);
  209. if(!$loading.hasClass('hidden')) {
  210. // in process
  211. return false;
  212. }
  213. $loading.removeClass('hidden');
  214. var $li = $element.closest('li');
  215. var shareId = $li.data('share-id');
  216. self.model.removeShare(shareId)
  217. .done(function() {
  218. $li.remove();
  219. })
  220. .fail(function() {
  221. $loading.addClass('hidden');
  222. OC.Notification.showTemporary(t('core', 'Could not unshare'));
  223. });
  224. return false;
  225. },
  226. onPermissionChange: function(event) {
  227. var $element = $(event.target);
  228. var $li = $element.closest('li');
  229. var shareId = $li.data('share-id');
  230. var shareType = $li.data('share-type');
  231. var shareWith = $li.attr('data-share-with');
  232. // adjust checkbox states
  233. var $checkboxes = $('.permissions', $li).not('input[name="edit"]').not('input[name="share"]');
  234. var checked;
  235. if ($element.attr('name') === 'edit') {
  236. checked = $element.is(':checked');
  237. // Check/uncheck Create, Update, and Delete checkboxes if Edit is checked/unck
  238. $($checkboxes).prop('checked', checked);
  239. } else {
  240. var numberChecked = $checkboxes.filter(':checked').length;
  241. checked = numberChecked > 0;
  242. $('input[name="edit"]', $li).prop('checked', checked);
  243. }
  244. var permissions = OC.PERMISSION_READ;
  245. $('.permissions', $li).not('input[name="edit"]').filter(':checked').each(function(index, checkbox) {
  246. permissions |= $(checkbox).data('permissions');
  247. });
  248. this.model.updateShare(shareId, {permissions: permissions});
  249. },
  250. onCrudsToggle: function(event) {
  251. var $target = $(event.target);
  252. $target.closest('li').find('.cruds').toggleClass('hidden');
  253. return false;
  254. },
  255. onSendMailNotification: function(event) {
  256. var $target = $(event.target);
  257. var $li = $(event.target).closest('li');
  258. var shareType = $li.data('share-type');
  259. var shareWith = $li.attr('data-share-with');
  260. this.model.sendNotificationForShare(shareType, shareWith, $target.is(':checked'));
  261. }
  262. });
  263. OC.Share.ShareDialogShareeListView = ShareDialogShareeListView;
  264. })();