2014-07-08 11:02:26 +00:00
|
|
|
define [
|
|
|
|
"base"
|
|
|
|
], (App) ->
|
2018-02-06 09:56:46 +00:00
|
|
|
App.controller "ShareProjectModalController", ($scope, $modalInstance, $timeout, projectMembers, projectInvites, $modal, $http, ide, validateCaptcha, settings, event_tracking) ->
|
2014-07-08 11:02:26 +00:00
|
|
|
$scope.inputs = {
|
|
|
|
privileges: "readAndWrite"
|
2015-10-15 12:53:46 +00:00
|
|
|
contacts: []
|
2014-07-08 11:02:26 +00:00
|
|
|
}
|
|
|
|
$scope.state = {
|
|
|
|
error: null
|
2016-12-20 09:54:42 +00:00
|
|
|
errorReason: null
|
2014-07-08 11:02:26 +00:00
|
|
|
inflight: false
|
|
|
|
startedFreeTrial: false
|
2016-07-25 13:27:02 +00:00
|
|
|
invites: []
|
2014-07-08 11:02:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$modalInstance.opened.then () ->
|
|
|
|
$timeout () ->
|
|
|
|
$scope.$broadcast "open"
|
|
|
|
, 200
|
|
|
|
|
|
|
|
INFINITE_COLLABORATORS = -1
|
2016-11-07 14:36:04 +00:00
|
|
|
|
|
|
|
$scope.refreshCanAddCollaborators = () ->
|
2014-07-08 11:02:26 +00:00
|
|
|
allowedNoOfMembers = $scope.project.features.collaborators
|
2016-11-07 14:36:04 +00:00
|
|
|
$scope.canAddCollaborators = (
|
|
|
|
($scope.project.members.length + $scope.project.invites.length) < allowedNoOfMembers or allowedNoOfMembers == INFINITE_COLLABORATORS
|
|
|
|
)
|
|
|
|
$scope.refreshCanAddCollaborators()
|
2014-07-08 11:02:26 +00:00
|
|
|
|
2016-11-07 14:36:04 +00:00
|
|
|
$scope.$watch "(project.members.length + project.invites.length)", (_noOfMembers) ->
|
|
|
|
$scope.refreshCanAddCollaborators()
|
2016-08-05 13:01:08 +00:00
|
|
|
|
2015-10-07 16:32:35 +00:00
|
|
|
$scope.autocompleteContacts = []
|
|
|
|
do loadAutocompleteUsers = () ->
|
|
|
|
$http.get "/user/contacts"
|
2017-06-20 15:04:06 +00:00
|
|
|
.then (response) ->
|
|
|
|
{ data } = response
|
2015-10-07 16:32:35 +00:00
|
|
|
$scope.autocompleteContacts = data.contacts or []
|
2015-10-08 17:17:53 +00:00
|
|
|
for contact in $scope.autocompleteContacts
|
|
|
|
if contact.type == "user"
|
2017-09-07 10:30:20 +00:00
|
|
|
if contact.last_name == "" and contact.first_name == contact.email.split("@")[0]
|
2015-10-08 17:17:53 +00:00
|
|
|
# User has not set their proper name so use email as canonical display property
|
|
|
|
contact.display = contact.email
|
|
|
|
else
|
|
|
|
contact.name = "#{contact.first_name} #{contact.last_name}"
|
|
|
|
contact.display = "#{contact.name} <#{contact.email}>"
|
|
|
|
else
|
|
|
|
# Must be a group
|
|
|
|
contact.display = contact.name
|
2016-07-25 09:33:43 +00:00
|
|
|
|
2015-11-02 15:21:41 +00:00
|
|
|
getCurrentMemberEmails = () ->
|
2016-08-15 13:56:02 +00:00
|
|
|
($scope.project.members || []).map (u) -> u.email
|
2015-10-08 17:17:53 +00:00
|
|
|
|
2016-08-03 15:30:34 +00:00
|
|
|
getCurrentInviteEmails = () ->
|
2016-08-15 13:56:02 +00:00
|
|
|
($scope.project.invites || []).map (u) -> u.email
|
2016-08-03 15:30:34 +00:00
|
|
|
|
2015-10-07 16:32:35 +00:00
|
|
|
$scope.filterAutocompleteUsers = ($query) ->
|
2015-11-02 15:21:41 +00:00
|
|
|
currentMemberEmails = getCurrentMemberEmails()
|
2015-10-08 17:17:53 +00:00
|
|
|
return $scope.autocompleteContacts.filter (contact) ->
|
2015-11-02 15:21:41 +00:00
|
|
|
if contact.email? and contact.email in currentMemberEmails
|
|
|
|
return false
|
2015-10-08 17:17:53 +00:00
|
|
|
for text in [contact.name, contact.email]
|
2015-10-07 16:32:35 +00:00
|
|
|
if text?.toLowerCase().indexOf($query.toLowerCase()) > -1
|
|
|
|
return true
|
|
|
|
return false
|
2015-09-02 11:20:37 +00:00
|
|
|
|
2015-10-07 16:32:35 +00:00
|
|
|
$scope.addMembers = () ->
|
2015-11-04 14:33:27 +00:00
|
|
|
addMembers = () ->
|
2015-10-07 16:32:35 +00:00
|
|
|
return if $scope.inputs.contacts.length == 0
|
2015-09-02 11:20:37 +00:00
|
|
|
|
2015-10-15 12:53:46 +00:00
|
|
|
members = $scope.inputs.contacts
|
2015-10-07 16:32:35 +00:00
|
|
|
$scope.inputs.contacts = []
|
2016-12-20 09:54:42 +00:00
|
|
|
$scope.state.error = false
|
|
|
|
$scope.state.errorReason = null
|
2015-10-07 16:32:35 +00:00
|
|
|
$scope.state.inflight = true
|
2016-07-25 09:33:43 +00:00
|
|
|
|
2016-08-15 14:40:16 +00:00
|
|
|
if !$scope.project.invites?
|
|
|
|
$scope.project.invites = []
|
|
|
|
|
2015-11-02 15:21:41 +00:00
|
|
|
currentMemberEmails = getCurrentMemberEmails()
|
2016-08-03 15:30:34 +00:00
|
|
|
currentInviteEmails = getCurrentInviteEmails()
|
2015-10-07 16:32:35 +00:00
|
|
|
do addNextMember = () ->
|
2015-10-15 12:53:46 +00:00
|
|
|
if members.length == 0 or !$scope.canAddCollaborators
|
2015-09-02 11:20:37 +00:00
|
|
|
$scope.state.inflight = false
|
2015-10-07 16:32:35 +00:00
|
|
|
$scope.$apply()
|
|
|
|
return
|
2016-07-25 09:33:43 +00:00
|
|
|
|
2015-10-15 12:53:46 +00:00
|
|
|
member = members.shift()
|
2016-09-21 09:48:04 +00:00
|
|
|
if member.type == "user"
|
|
|
|
email = member.email
|
|
|
|
else # Not an auto-complete object, so email == display
|
|
|
|
email = member.display
|
|
|
|
email = email.toLowerCase()
|
|
|
|
|
|
|
|
if email in currentMemberEmails
|
2015-11-02 15:21:41 +00:00
|
|
|
# Skip this existing member
|
|
|
|
return addNextMember()
|
2018-03-15 18:01:46 +00:00
|
|
|
validateCaptcha (response) ->
|
|
|
|
$scope.grecaptchaResponse = response
|
|
|
|
if email in currentInviteEmails and inviteId = _.find(($scope.project.invites || []), (invite) -> invite.email == email)?._id
|
|
|
|
request = projectInvites.resendInvite(inviteId)
|
|
|
|
else
|
|
|
|
request = projectInvites.sendInvite(email, $scope.inputs.privileges, $scope.grecaptchaResponse)
|
|
|
|
|
|
|
|
request
|
|
|
|
.then (response) ->
|
|
|
|
{ data } = response
|
|
|
|
if data.error
|
|
|
|
$scope.state.error = true
|
|
|
|
$scope.state.errorReason = "#{data.error}"
|
|
|
|
$scope.state.inflight = false
|
2016-07-28 12:47:19 +00:00
|
|
|
else
|
2018-03-15 18:01:46 +00:00
|
|
|
if data.invite
|
|
|
|
invite = data.invite
|
|
|
|
$scope.project.invites.push invite
|
2016-12-20 09:54:42 +00:00
|
|
|
else
|
2018-03-15 18:01:46 +00:00
|
|
|
if data.users?
|
|
|
|
users = data.users
|
|
|
|
else if data.user?
|
|
|
|
users = [data.user]
|
|
|
|
else
|
|
|
|
users = []
|
|
|
|
$scope.project.members.push users...
|
|
|
|
|
|
|
|
setTimeout () ->
|
|
|
|
# Give $scope a chance to update $scope.canAddCollaborators
|
|
|
|
# with new collaborator information.
|
|
|
|
addNextMember()
|
|
|
|
, 0
|
|
|
|
.catch (httpResponse) ->
|
|
|
|
{data, status, headers, config } = httpResponse
|
|
|
|
$scope.state.inflight = false
|
|
|
|
$scope.state.error = true
|
|
|
|
|
|
|
|
if data?.errorReason?
|
|
|
|
$scope.state.errorReason = data?.errorReason
|
|
|
|
else
|
|
|
|
$scope.state.errorReason = null
|
|
|
|
|
2016-07-25 09:33:43 +00:00
|
|
|
|
2018-03-15 18:01:46 +00:00
|
|
|
$timeout addMembers, 50 # Give email list a chance to update
|
2014-07-08 11:02:26 +00:00
|
|
|
|
|
|
|
$scope.removeMember = (member) ->
|
|
|
|
$scope.state.error = null
|
|
|
|
$scope.state.inflight = true
|
|
|
|
projectMembers
|
|
|
|
.removeMember(member)
|
2017-06-20 10:49:55 +00:00
|
|
|
.then () ->
|
2014-07-08 11:02:26 +00:00
|
|
|
$scope.state.inflight = false
|
|
|
|
index = $scope.project.members.indexOf(member)
|
|
|
|
return if index == -1
|
|
|
|
$scope.project.members.splice(index, 1)
|
2017-06-20 10:49:55 +00:00
|
|
|
.catch () ->
|
2014-07-08 11:02:26 +00:00
|
|
|
$scope.state.inflight = false
|
|
|
|
$scope.state.error = "Sorry, something went wrong :("
|
|
|
|
|
2016-07-25 13:27:02 +00:00
|
|
|
$scope.revokeInvite = (invite) ->
|
|
|
|
$scope.state.error = null
|
|
|
|
$scope.state.inflight = true
|
|
|
|
projectInvites
|
|
|
|
.revokeInvite(invite._id)
|
2017-06-20 10:49:55 +00:00
|
|
|
.then () ->
|
2016-07-25 13:27:02 +00:00
|
|
|
$scope.state.inflight = false
|
2016-08-01 16:05:37 +00:00
|
|
|
index = $scope.project.invites.indexOf(invite)
|
2016-07-25 13:27:02 +00:00
|
|
|
return if index == -1
|
2016-08-01 16:05:37 +00:00
|
|
|
$scope.project.invites.splice(index, 1)
|
2017-06-20 10:49:55 +00:00
|
|
|
.catch () ->
|
2016-07-25 13:27:02 +00:00
|
|
|
$scope.state.inflight = false
|
|
|
|
$scope.state.error = "Sorry, something went wrong :("
|
|
|
|
|
2016-08-12 10:25:03 +00:00
|
|
|
$scope.resendInvite = (invite, event) ->
|
2016-08-03 14:42:19 +00:00
|
|
|
$scope.state.error = null
|
|
|
|
$scope.state.inflight = true
|
|
|
|
projectInvites
|
|
|
|
.resendInvite(invite._id)
|
2017-06-20 10:49:55 +00:00
|
|
|
.then () ->
|
2016-08-03 14:42:19 +00:00
|
|
|
$scope.state.inflight = false
|
2016-08-12 10:25:03 +00:00
|
|
|
event.target.blur()
|
2017-06-20 10:49:55 +00:00
|
|
|
.catch () ->
|
2016-08-03 14:42:19 +00:00
|
|
|
$scope.state.inflight = false
|
|
|
|
$scope.state.error = "Sorry, something went wrong resending the invite :("
|
2016-08-12 10:25:03 +00:00
|
|
|
event.target.blur()
|
2016-08-03 10:55:24 +00:00
|
|
|
|
2017-09-28 15:06:08 +00:00
|
|
|
$scope.makeTokenBased = () ->
|
|
|
|
$scope.project.publicAccesLevel = "tokenBased"
|
|
|
|
settings.saveProjectAdminSettings({publicAccessLevel: "tokenBased"})
|
2017-10-31 14:23:05 +00:00
|
|
|
event_tracking.sendMB 'project-make-token-based'
|
2017-09-28 15:06:08 +00:00
|
|
|
|
2014-07-08 11:02:26 +00:00
|
|
|
$scope.makePrivate = () ->
|
|
|
|
$scope.project.publicAccesLevel = "private"
|
2016-03-10 11:13:57 +00:00
|
|
|
settings.saveProjectAdminSettings({publicAccessLevel: "private"})
|
2017-09-28 15:06:08 +00:00
|
|
|
|
2018-02-06 10:00:59 +00:00
|
|
|
$scope.$watch "project.tokens.readAndWrite", (token) ->
|
|
|
|
if token?
|
|
|
|
$scope.readAndWriteTokenLink = "#{location.origin}/#{token}"
|
2017-10-04 15:31:24 +00:00
|
|
|
else
|
2018-02-06 10:00:59 +00:00
|
|
|
$scope.readAndWriteTokenLink = null
|
2017-09-29 09:11:23 +00:00
|
|
|
|
2018-02-06 10:00:59 +00:00
|
|
|
$scope.$watch "project.tokens.readOnly", (token) ->
|
|
|
|
if token?
|
2018-02-12 10:42:57 +00:00
|
|
|
$scope.readOnlyTokenLink = "#{location.origin}/read/#{token}"
|
2017-10-04 15:31:24 +00:00
|
|
|
else
|
2018-02-06 10:00:59 +00:00
|
|
|
$scope.readOnlyTokenLink = null
|
2017-09-29 09:11:23 +00:00
|
|
|
|
2014-07-08 11:02:26 +00:00
|
|
|
$scope.done = () ->
|
|
|
|
$modalInstance.close()
|
|
|
|
|
|
|
|
$scope.cancel = () ->
|
|
|
|
$modalInstance.dismiss()
|