ShareProjectModalController.coffee 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. define [
  2. "base"
  3. ], (App) ->
  4. App.controller "ShareProjectModalController", ($scope, $modalInstance, $timeout, projectMembers, projectInvites, $modal, $http, ide) ->
  5. $scope.inputs = {
  6. privileges: "readAndWrite"
  7. contacts: []
  8. }
  9. $scope.state = {
  10. error: null
  11. errorReason: null
  12. inflight: false
  13. startedFreeTrial: false
  14. invites: []
  15. }
  16. $modalInstance.opened.then () ->
  17. $timeout () ->
  18. $scope.$broadcast "open"
  19. , 200
  20. INFINITE_COLLABORATORS = -1
  21. $scope.refreshCanAddCollaborators = () ->
  22. allowedNoOfMembers = $scope.project.features.collaborators
  23. $scope.canAddCollaborators = (
  24. ($scope.project.members.length + $scope.project.invites.length) < allowedNoOfMembers or allowedNoOfMembers == INFINITE_COLLABORATORS
  25. )
  26. $scope.refreshCanAddCollaborators()
  27. $scope.$watch "(project.members.length + project.invites.length)", (_noOfMembers) ->
  28. $scope.refreshCanAddCollaborators()
  29. $scope.autocompleteContacts = []
  30. do loadAutocompleteUsers = () ->
  31. $http.get "/user/contacts"
  32. .then (response) ->
  33. { data } = response
  34. $scope.autocompleteContacts = data.contacts or []
  35. for contact in $scope.autocompleteContacts
  36. if contact.type == "user"
  37. if contact.last_name == "" and contact.first_name == contact.email.split("@")[0]
  38. # User has not set their proper name so use email as canonical display property
  39. contact.display = contact.email
  40. else
  41. contact.name = "#{contact.first_name} #{contact.last_name}"
  42. contact.display = "#{contact.name} <#{contact.email}>"
  43. else
  44. # Must be a group
  45. contact.display = contact.name
  46. getCurrentMemberEmails = () ->
  47. ($scope.project.members || []).map (u) -> u.email
  48. getCurrentInviteEmails = () ->
  49. ($scope.project.invites || []).map (u) -> u.email
  50. _recaptchaCallbacks = []
  51. onRecaptchaSubmit = (token) ->
  52. for cb in _recaptchaCallbacks
  53. cb(token)
  54. _recaptchaCallbacks = []
  55. recaptchaId = null
  56. validateCaptcha = (callback = (response) ->) =>
  57. if !grecaptcha?
  58. return callback()
  59. reset = () ->
  60. grecaptcha.reset()
  61. _recaptchaCallbacks.push callback
  62. _recaptchaCallbacks.push reset
  63. if !recaptchaId?
  64. el = $('.g-recaptcha')[0]
  65. recaptchaId = grecaptcha.render(el, {callback: onRecaptchaSubmit})
  66. grecaptcha.execute(recaptchaId)
  67. $scope.filterAutocompleteUsers = ($query) ->
  68. currentMemberEmails = getCurrentMemberEmails()
  69. return $scope.autocompleteContacts.filter (contact) ->
  70. if contact.email? and contact.email in currentMemberEmails
  71. return false
  72. for text in [contact.name, contact.email]
  73. if text?.toLowerCase().indexOf($query.toLowerCase()) > -1
  74. return true
  75. return false
  76. $scope.addMembers = () ->
  77. addMembers = () ->
  78. return if $scope.inputs.contacts.length == 0
  79. members = $scope.inputs.contacts
  80. $scope.inputs.contacts = []
  81. $scope.state.error = false
  82. $scope.state.errorReason = null
  83. $scope.state.inflight = true
  84. if !$scope.project.invites?
  85. $scope.project.invites = []
  86. currentMemberEmails = getCurrentMemberEmails()
  87. currentInviteEmails = getCurrentInviteEmails()
  88. do addNextMember = () ->
  89. if members.length == 0 or !$scope.canAddCollaborators
  90. $scope.state.inflight = false
  91. $scope.$apply()
  92. return
  93. member = members.shift()
  94. if member.type == "user"
  95. email = member.email
  96. else # Not an auto-complete object, so email == display
  97. email = member.display
  98. email = email.toLowerCase()
  99. if email in currentMemberEmails
  100. # Skip this existing member
  101. return addNextMember()
  102. if email in currentInviteEmails and inviteId = _.find(($scope.project.invites || []), (invite) -> invite.email == email)?._id
  103. request = projectInvites.resendInvite(inviteId)
  104. else
  105. request = projectInvites.sendInvite(email, $scope.inputs.privileges, $scope.grecaptchaResponse)
  106. request
  107. .then (response) ->
  108. { data } = response
  109. if data.error
  110. $scope.state.error = true
  111. $scope.state.errorReason = "#{data.error}"
  112. $scope.state.inflight = false
  113. else
  114. if data.invite
  115. invite = data.invite
  116. $scope.project.invites.push invite
  117. else
  118. if data.users?
  119. users = data.users
  120. else if data.user?
  121. users = [data.user]
  122. else
  123. users = []
  124. $scope.project.members.push users...
  125. setTimeout () ->
  126. # Give $scope a chance to update $scope.canAddCollaborators
  127. # with new collaborator information.
  128. addNextMember()
  129. , 0
  130. .catch (err) ->
  131. $scope.state.inflight = false
  132. $scope.state.error = true
  133. if err.status? and err.status == 400
  134. $scope.state.errorReason = 'invalid_email'
  135. else
  136. $scope.state.errorReason = null
  137. validateCaptcha (response) ->
  138. $scope.grecaptchaResponse = response
  139. $timeout addMembers, 50 # Give email list a chance to update
  140. $scope.removeMember = (member) ->
  141. $scope.state.error = null
  142. $scope.state.inflight = true
  143. projectMembers
  144. .removeMember(member)
  145. .then () ->
  146. $scope.state.inflight = false
  147. index = $scope.project.members.indexOf(member)
  148. return if index == -1
  149. $scope.project.members.splice(index, 1)
  150. .catch () ->
  151. $scope.state.inflight = false
  152. $scope.state.error = "Sorry, something went wrong :("
  153. $scope.revokeInvite = (invite) ->
  154. $scope.state.error = null
  155. $scope.state.inflight = true
  156. projectInvites
  157. .revokeInvite(invite._id)
  158. .then () ->
  159. $scope.state.inflight = false
  160. index = $scope.project.invites.indexOf(invite)
  161. return if index == -1
  162. $scope.project.invites.splice(index, 1)
  163. .catch () ->
  164. $scope.state.inflight = false
  165. $scope.state.error = "Sorry, something went wrong :("
  166. $scope.resendInvite = (invite, event) ->
  167. $scope.state.error = null
  168. $scope.state.inflight = true
  169. projectInvites
  170. .resendInvite(invite._id)
  171. .then () ->
  172. $scope.state.inflight = false
  173. event.target.blur()
  174. .catch () ->
  175. $scope.state.inflight = false
  176. $scope.state.error = "Sorry, something went wrong resending the invite :("
  177. event.target.blur()
  178. $scope.openMakePrivateModal = () ->
  179. $modal.open {
  180. templateUrl: "makePrivateModalTemplate"
  181. controller: "MakePrivateModalController"
  182. scope: $scope
  183. }
  184. $scope.openMakeTokenBasedModal = () ->
  185. $modal.open {
  186. templateUrl: "makeTokenBasedModalTemplate"
  187. controller: "MakeTokenBasedModalController"
  188. scope: $scope
  189. }
  190. $scope.getReadAndWriteTokenLink = () ->
  191. if $scope?.project?.tokens?.readAndWrite?
  192. location.origin + "/" + $scope.project.tokens.readAndWrite
  193. else
  194. ''
  195. $scope.getReadOnlyTokenLink = () ->
  196. if $scope?.project?.tokens?.readOnly?
  197. location.origin + "/read/" + $scope.project.tokens.readOnly
  198. else
  199. ''
  200. $scope.done = () ->
  201. $modalInstance.close()
  202. $scope.cancel = () ->
  203. $modalInstance.dismiss()
  204. App.controller "MakePublicModalController", ["$scope", "$modalInstance", "settings", ($scope, $modalInstance, settings) ->
  205. $scope.inputs = {
  206. privileges: "readAndWrite"
  207. }
  208. $scope.makePublic = () ->
  209. $scope.project.publicAccesLevel = $scope.inputs.privileges
  210. settings.saveProjectAdminSettings({publicAccessLevel: $scope.inputs.privileges})
  211. $modalInstance.close()
  212. $scope.cancel = () ->
  213. $modalInstance.dismiss()
  214. ]
  215. App.controller "MakeTokenBasedModalController", ["$scope", "$modalInstance", "settings", "event_tracking", ($scope, $modalInstance, settings, event_tracking) ->
  216. $scope.makeTokenBased = () ->
  217. $scope.project.publicAccesLevel = "tokenBased"
  218. settings.saveProjectAdminSettings({publicAccessLevel: "tokenBased"})
  219. event_tracking.sendMB 'project-make-token-based'
  220. $modalInstance.close()
  221. $scope.cancel = () ->
  222. $modalInstance.dismiss()
  223. ]
  224. App.controller "MakePrivateModalController", ["$scope", "$modalInstance", "settings", ($scope, $modalInstance, settings) ->
  225. $scope.makePrivate = () ->
  226. $scope.project.publicAccesLevel = "private"
  227. settings.saveProjectAdminSettings({publicAccessLevel: "private"})
  228. $modalInstance.close()
  229. $scope.cancel = () ->
  230. $modalInstance.dismiss()
  231. ]