sharedialogexpirationview.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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. /* global moment, Handlebars */
  11. (function() {
  12. if (!OC.Share) {
  13. OC.Share = {};
  14. }
  15. var TEMPLATE =
  16. // currently expiration is only effective for link share.
  17. // this is about to change in future. Therefore this is not included
  18. // in the LinkShareView to ease reusing it in future. Then,
  19. // modifications (getting rid of IDs) are still necessary.
  20. '{{#if isLinkShare}}' +
  21. '<input type="checkbox" name="expirationCheckbox" class="expirationCheckbox checkbox" id="expirationCheckbox-{{cid}}" value="1" ' +
  22. '{{#if isExpirationSet}}checked="checked"{{/if}} {{#if disableCheckbox}}disabled="disabled"{{/if}} />' +
  23. '<label for="expirationCheckbox-{{cid}}">{{setExpirationLabel}}</label>' +
  24. '<div class="expirationDateContainer {{#unless isExpirationSet}}hidden{{/unless}}">' +
  25. ' <label for="expirationDate" class="hidden-visually" value="{{expirationDate}}">{{expirationLabel}}</label>' +
  26. ' <input id="expirationDate" class="datepicker" type="text" placeholder="{{expirationDatePlaceholder}}" value="{{expirationValue}}" />' +
  27. '</div>' +
  28. ' {{#if isExpirationEnforced}}' +
  29. // originally the expire message was shown when a default date was set, however it never had text
  30. '<em id="defaultExpireMessage">{{defaultExpireMessage}}</em>' +
  31. ' {{/if}}' +
  32. '{{/if}}'
  33. ;
  34. /**
  35. * @class OCA.Share.ShareDialogExpirationView
  36. * @member {OC.Share.ShareItemModel} model
  37. * @member {jQuery} $el
  38. * @memberof OCA.Sharing
  39. * @classdesc
  40. *
  41. * Represents the expiration part in the GUI of the share dialogue
  42. *
  43. */
  44. var ShareDialogExpirationView = OC.Backbone.View.extend({
  45. /** @type {string} **/
  46. id: 'shareDialogLinkShare',
  47. /** @type {OC.Share.ShareConfigModel} **/
  48. configModel: undefined,
  49. /** @type {Function} **/
  50. _template: undefined,
  51. /** @type {boolean} **/
  52. showLink: true,
  53. className: 'hidden',
  54. events: {
  55. 'change .expirationCheckbox': '_onToggleExpiration',
  56. 'change .datepicker': '_onChangeExpirationDate'
  57. },
  58. initialize: function(options) {
  59. if(!_.isUndefined(options.configModel)) {
  60. this.configModel = options.configModel;
  61. } else {
  62. throw 'missing OC.Share.ShareConfigModel';
  63. }
  64. var view = this;
  65. this.configModel.on('change:isDefaultExpireDateEnforced', function() {
  66. view.render();
  67. });
  68. this.model.on('change:itemType', function() {
  69. view.render();
  70. });
  71. this.model.on('change:linkShare', function() {
  72. view.render();
  73. });
  74. },
  75. _onToggleExpiration: function(event) {
  76. var $checkbox = $(event.target);
  77. var state = $checkbox.prop('checked');
  78. // TODO: slide animation
  79. this.$el.find('.expirationDateContainer').toggleClass('hidden', !state);
  80. if (!state) {
  81. // discard expiration date
  82. this.model.get('linkShare').expiration = '';
  83. this.model.saveLinkShare({
  84. expireDate: ''
  85. });
  86. } else {
  87. this.$el.find('#expirationDate').focus();
  88. }
  89. },
  90. _onChangeExpirationDate: function(event) {
  91. var $target = $(event.target);
  92. $target.tooltip('hide');
  93. $target.removeClass('error');
  94. var expiration = moment($target.val(), 'DD-MM-YYYY').format('YYYY-MM-DD');
  95. this.model.get('linkShare').expiration = expiration;
  96. this.model.saveLinkShare({
  97. expiration: expiration
  98. }, {
  99. error: function(model, message) {
  100. if (!message) {
  101. $target.attr('title', t('core', 'Error setting expiration date'));
  102. } else {
  103. $target.attr('title', message);
  104. }
  105. $target.tooltip({gravity: 'n'});
  106. $target.tooltip('show');
  107. $target.addClass('error');
  108. }
  109. });
  110. },
  111. render: function() {
  112. var defaultExpireMessage = '';
  113. var defaultExpireDays = this.configModel.get('defaultExpireDate');
  114. var isExpirationEnforced = this.configModel.get('isDefaultExpireDateEnforced');
  115. if( (this.model.isFolder() || this.model.isFile())
  116. && isExpirationEnforced) {
  117. defaultExpireMessage = t(
  118. 'core',
  119. 'The public link will expire no later than {days} days after it is created',
  120. {'days': defaultExpireDays }
  121. );
  122. }
  123. var isExpirationSet = !!this.model.get('linkShare').expiration || isExpirationEnforced;
  124. var expiration;
  125. if (isExpirationSet) {
  126. expiration = moment(this.model.get('linkShare').expiration, 'YYYY-MM-DD').format('DD-MM-YYYY');
  127. }
  128. this.$el.html(this.template({
  129. cid: this.cid,
  130. setExpirationLabel: t('core', 'Set expiration date'),
  131. expirationLabel: t('core', 'Expiration'),
  132. expirationDatePlaceholder: t('core', 'Expiration date'),
  133. defaultExpireMessage: defaultExpireMessage,
  134. isLinkShare: this.model.get('linkShare').isLinkShare,
  135. isExpirationSet: isExpirationSet,
  136. isExpirationEnforced: isExpirationEnforced,
  137. disableCheckbox: isExpirationEnforced && isExpirationSet,
  138. expirationValue: expiration
  139. }));
  140. // what if there is another date picker on that page?
  141. var minDate = new Date();
  142. var maxDate = null;
  143. // min date should always be the next day
  144. minDate.setDate(minDate.getDate()+1);
  145. if(isExpirationSet) {
  146. if(isExpirationEnforced) {
  147. // TODO: hack: backend returns string instead of integer
  148. var shareTime = this.model.get('linkShare').stime;
  149. if (_.isNumber(shareTime)) {
  150. shareTime = new Date(shareTime * 1000);
  151. }
  152. if (!shareTime) {
  153. shareTime = new Date(); // now
  154. }
  155. shareTime = OC.Util.stripTime(shareTime).getTime();
  156. maxDate = new Date(shareTime + defaultExpireDays * 24 * 3600 * 1000);
  157. }
  158. }
  159. $.datepicker.setDefaults({
  160. minDate: minDate,
  161. maxDate: maxDate
  162. });
  163. this.$el.find('.datepicker').datepicker({dateFormat : 'dd-mm-yy'});
  164. this.delegateEvents();
  165. return this;
  166. },
  167. /**
  168. * @returns {Function} from Handlebars
  169. * @private
  170. */
  171. template: function (data) {
  172. if (!this._template) {
  173. this._template = Handlebars.compile(TEMPLATE);
  174. }
  175. return this._template(data);
  176. }
  177. });
  178. OC.Share.ShareDialogExpirationView = ShareDialogExpirationView;
  179. })();