diff --git a/services/web/app/views/project/editor/share.jade b/services/web/app/views/project/editor/share.jade index ad3b2bd9ba..4d6bee100b 100644 --- a/services/web/app/views/project/editor/share.jade +++ b/services/web/app/views/project/editor/share.jade @@ -43,6 +43,19 @@ script(type='text/ng-template', id='shareProjectModalTemplate') ng-click="removeMember(member)" ) i.fa.fa-times + .row.project-invite(ng-repeat="invite in state.invites") + .col-xs-8 {{ invite.email }} (invite) + .col-xs-3.text-right + span(ng-show="member.privileges == 'readAndWrite'") #{translate("can_edit")} + span(ng-show="member.privileges == 'readOnly'") #{translate("read_only")} + .col-xs-1 + a( + href + tooltip="#{translate('revoke_invite')}" + tooltip-placement="bottom" + ng-click="revokeInvite(invite)" + ) + i.fa.fa-times .row.invite-controls form(ng-show="canAddCollaborators") .small #{translate("share_with_your_collabs")} diff --git a/services/web/public/coffee/ide/share/controllers/ShareProjectModalController.coffee b/services/web/public/coffee/ide/share/controllers/ShareProjectModalController.coffee index ea58bf9ebb..05376b01b8 100644 --- a/services/web/public/coffee/ide/share/controllers/ShareProjectModalController.coffee +++ b/services/web/public/coffee/ide/share/controllers/ShareProjectModalController.coffee @@ -1,7 +1,7 @@ define [ "base" ], (App) -> - App.controller "ShareProjectModalController", ($scope, $modalInstance, $timeout, projectMembers, $modal, $http) -> + App.controller "ShareProjectModalController", ($scope, $modalInstance, $timeout, projectMembers, projectInvites, $modal, $http) -> $scope.inputs = { privileges: "readAndWrite" contacts: [] @@ -10,9 +10,11 @@ define [ error: null inflight: false startedFreeTrial: false + invites: [] } $modalInstance.opened.then () -> + getOutstandingInvites() $timeout () -> $scope.$broadcast "open" , 200 @@ -42,6 +44,16 @@ define [ getCurrentMemberEmails = () -> $scope.project.members.map (u) -> u.email + getOutstandingInvites = (callback) -> + projectInvites.getInvites().then( + (response) -> + $scope.state.invites = response?.data?.invites + $scope.state.invites = [{_id: "wat", email: "user@example.com"}] + , (response) -> + console.error response + ) + window._x = getOutstandingInvites + $scope.filterAutocompleteUsers = ($query) -> currentMemberEmails = getCurrentMemberEmails() return $scope.autocompleteContacts.filter (contact) -> @@ -73,12 +85,13 @@ define [ # Skip this existing member return addNextMember() + # TODO: double-check if member.type == 'user' needs to be an invite if member.type == "user" request = projectMembers.addMember(member.email, $scope.inputs.privileges) else if member.type == "group" request = projectMembers.addGroup(member.id, $scope.inputs.privileges) else # Not an auto-complete object, so email == display - request = projectMembers.addMember(member.display, $scope.inputs.privileges) + request = projectInvites.sendInvite(member.display, $scope.inputs.privileges) request .success (data) -> @@ -115,6 +128,20 @@ define [ $scope.state.inflight = false $scope.state.error = "Sorry, something went wrong :(" + $scope.revokeInvite = (invite) -> + $scope.state.error = null + $scope.state.inflight = true + projectInvites + .revokeInvite(invite._id) + .success () -> + $scope.state.inflight = false + index = $scope.state.invites.indexOf(invite) + return if index == -1 + $scope.state.invites.splice(index, 1) + .error () -> + $scope.state.inflight = false + $scope.state.error = "Sorry, something went wrong :(" + $scope.openMakePublicModal = () -> $modal.open { templateUrl: "makePublicModalTemplate" diff --git a/services/web/public/coffee/ide/share/index.coffee b/services/web/public/coffee/ide/share/index.coffee index 545a145be3..13b2bdbcfd 100644 --- a/services/web/public/coffee/ide/share/index.coffee +++ b/services/web/public/coffee/ide/share/index.coffee @@ -2,4 +2,5 @@ define [ "ide/share/controllers/ShareController" "ide/share/controllers/ShareProjectModalController" "ide/share/services/projectMembers" -], () -> \ No newline at end of file + "ide/share/services/projectInvites" +], () -> diff --git a/services/web/public/coffee/ide/share/services/projectInvites.coffee b/services/web/public/coffee/ide/share/services/projectInvites.coffee new file mode 100644 index 0000000000..f453792574 --- /dev/null +++ b/services/web/public/coffee/ide/share/services/projectInvites.coffee @@ -0,0 +1,30 @@ +define [ + "base" +], (App) -> + App.factory "projectInvites", ["ide", "$http", (ide, $http) -> + return { + + sendInvite: (email, privileges) -> + $http.post("/project/#{ide.project_id}/invite", { + email: email + privileges: privileges + _csrf: window.csrfToken + }) + + revokeInvite: (inviteId) -> + $http({ + url: "/project/#{ide.project_id}/invite/#{inviteId}" + method: "DELETE" + headers: + "X-Csrf-Token": window.csrfToken + }) + + getInvites: () -> + $http.get("/project/#{ide.project_id}/invite", { + json: true + headers: + "X-Csrf-Token": window.csrfToken + }) + + } + ] diff --git a/services/web/public/stylesheets/app/editor/share.less b/services/web/public/stylesheets/app/editor/share.less index 77ed2e0df6..cd06a15313 100644 --- a/services/web/public/stylesheets/app/editor/share.less +++ b/services/web/public/stylesheets/app/editor/share.less @@ -6,7 +6,7 @@ font-size: 1rem; } - .project-member, .public-access-level { + .project-member, .project-invite, .public-access-level { padding: (@line-height-computed / 2) 0; border-bottom: 1px solid @gray-lighter; font-size: 14px; @@ -19,7 +19,7 @@ padding-bottom: @line-height-computed; } - .project-member { + .project-member, .project-invite { &:hover { background-color: @gray-lightest; }