Add in basic share modal

This commit is contained in:
James Allen 2014-07-01 14:12:28 +01:00
parent 9097fdd930
commit be48ab2a30
13 changed files with 231 additions and 30 deletions

View file

@ -26,7 +26,8 @@ module.exports =
addUserToProject: (project_id, email, privilegeLevel, callback)->
emails = mimelib.parseAddresses(email)
email = emails[0].address?.toLowerCase()
email = emails[0]?.address?.toLowerCase()
return callback(new Error("no valid email provided")) if !email?
self = @
User.findOne {'email':email}, (err, user)->
async.waterfall [

View file

@ -138,7 +138,7 @@ module.exports = EditorController =
CollaboratorsHandler.addUserToProject project_id, email, privileges, (err, user)=>
ProjectEntityHandler.flushProjectToThirdPartyDataStore project_id, "", ->
EditorRealTimeController.emitToRoom(project_id, 'userAddedToProject', user, privileges)
callback null, true
callback null, ProjectEditorHandler.buildUserModelView(user, privileges)
removeUserFromProject: (project_id, user_id, callback)->
CollaboratorsHandler.removeUserFromProject project_id, user_id, =>

View file

@ -37,6 +37,8 @@ block content
include ./editor/header
include ./editor/share
#ide-body(ng-cloak, layout="main", ng-hide="state.loading")
.ui-layout-west
include ./editor/file-tree
@ -45,33 +47,6 @@ block content
include ./editor/editor
include ./editor/track-changes
//- #loadingScreen
//- h3 Loading...
//- p#loadingMessage Loading editor
//- #errorMessages
//- #connectionLostMessage(style="display: none;")
//- | Lost connection.
//- span#trying-reconnect
//- | Reconnecting in
//- span#reconnection-countdown ?
//- | seconds.
//- a(href='#')#try-reconnect-now Try now.
//- span#reconnecting
//- | Reconnecting...
//- #savingProblems(style="display: none")
//- | Saving...
//- div#toolbar.sidebar-navigation
//- ul#tabs
//- #toolbar-footer
//- #tab-content.tab-content
//- include ../templates
//- include ../templates/dropbox
script(src='/socket.io/socket.io.js')
script(type='text/javascript').

View file

@ -13,7 +13,13 @@ header.toolbar.toolbar-header(ng-cloak, ng-hide="state.loading")
i.fa.fa-pencil
.toolbar-right
a.btn.btn-full-height(href='#', tooltip="Share", tooltip-placement="bottom")
a.btn.btn-full-height(
href,
tooltip="Share",
tooltip-placement="bottom",
ng-click="openShareProjectModal()",
ng-controller="ShareController"
)
i.fa.fa-fw.fa-group
a.btn.btn-full-height(
href,

View file

@ -0,0 +1,61 @@
script(type='text/ng-template', id='shareProjectModalTemplate')
.modal-header
h3 Share Project
.modal-body.modal-body-share
.container-fluid
.row.public-access-level
.col-md-9 This project is private and can only be accessed by the people below.
.col-md-3.text-right
a(href) Make public
.row.project-member
.col-md-8 {{ project.owner.email }}
.text-right(
ng-class="{'col-md-3': project.members.length > 0, 'col-md-4': project.members.length == 0}"
) Owner
.row.project-member(ng-repeat="member in project.members")
.col-md-8 {{ member.email }}
.col-md-3.text-right
span(ng-show="member.privileges == 'readAndWrite'") Can Edit
span(ng-show="member.privileges == 'readOnly'") Read Only
.col-md-1
a(
href
tooltip="Remove collaborator"
tooltip-placement="bottom"
ng-click="removeMember(member)"
)
i.fa.fa-times
.row.invite-controls
form(ng-show="canAddCollaborators")
.small Share with your collaborators
.form-group
input.form-control(
type="email"
placeholder="Enter email address..."
ng-model="inputs.email"
focus-on="open"
)
.form-group
.pull-right
select.privileges.form-control(
ng-model="inputs.privileges"
name="privileges"
)
option(value="readAndWrite") Can Edit
option(value="readOnly") Read Only
|   
button.btn.btn-info(
type="submit"
ng-click="addMember()"
) Share
div.text-center(ng-hide="canAddCollaborators")
p You need to upgrade your account to add more collaborators.
a.btn.btn-info(href) Start Free Trial
.modal-footer
.modal-footer-left
i.fa.fa-refresh.fa-spin(ng-show="state.inflight")
span.text-danger.error(ng-show="state.error") {{ state.error }}
button.btn.btn-primary(
ng-click="done()"
) Done

View file

@ -7,6 +7,7 @@ define [
"ide/online-users/OnlineUsersManager"
"ide/track-changes/TrackChangesManager"
"ide/pdf/PdfManager"
"ide/share/index"
"ide/directives/layout"
"ide/services/ide"
"directives/focus"

View file

@ -0,0 +1,11 @@
define [
"base"
], (App) ->
App.controller "ShareController", ["$scope", "$modal", ($scope, $modal) ->
$scope.openShareProjectModal = () ->
$modal.open(
templateUrl: "shareProjectModalTemplate"
controller: "ShareProjectModalController"
scope: $scope
)
]

View file

@ -0,0 +1,57 @@
define [
"base"
], (App) ->
App.controller "ShareProjectModalController", ["$scope", "$modalInstance", "$timeout", "projectMembers", ($scope, $modalInstance, $timeout, projectMembers) ->
$scope.inputs = {
privileges: "readAndWrite"
email: ""
}
$scope.state = {
error: null
inflight: false
}
$modalInstance.opened.then () ->
$timeout () ->
$scope.$broadcast "open"
, 200
INFINITE_COLLABORATORS = -1
$scope.$watch "project.members.length", (noOfMembers) ->
allowedNoOfMembers = $scope.project.features.collaborators
$scope.canAddCollaborators = noOfMembers < allowedNoOfMembers or allowedNoOfMembers == INFINITE_COLLABORATORS
$scope.addMember = () ->
console.log "EMAIL", $scope.inputs.email
return if !$scope.inputs.email? or $scope.inputs.email == ""
$scope.state.error = null
$scope.state.inflight = true
projectMembers
.addMember($scope.inputs.email, $scope.inputs.privileges)
.then (user) ->
$scope.state.inflight = false
$scope.inputs.email = ""
console.log "GOT USER", user
$scope.project.members.push user
.catch () ->
$scope.state.inflight = false
$scope.state.error = "Sorry, something went wrong :("
$scope.removeMember = (member) ->
$scope.state.error = null
$scope.state.inflight = true
projectMembers
.removeMember(member)
.then () ->
$scope.state.inflight = false
index = $scope.project.members.indexOf(member)
return if index == -1
$scope.project.members.splice(index, 1)
.catch () ->
$scope.state.inflight = false
$scope.state.error = "Sorry, something went wrong :("
$scope.done = () ->
$modalInstance.close()
]

View file

@ -0,0 +1,5 @@
define [
"ide/share/controllers/ShareController"
"ide/share/controllers/ShareProjectModalController"
"ide/share/services/projectMembers"
], () ->

View file

@ -0,0 +1,30 @@
define [
"base"
], (App) ->
App.factory "projectMembers", ["ide", "$q", (ide, $q) ->
return {
removeMember: (member) ->
deferred = $q.defer()
ide.socket.emit "removeUserFromProject", member._id, (error) =>
if error?
return deferred.reject(error)
deferred.resolve()
return deferred.promise
addMember: (email, privileges) ->
deferred = $q.defer()
ide.socket.emit "addUserToProject", email, privileges, (error, user) =>
if error?
return deferred.reject(error)
if !user
deferred.reject()
else
deferred.resolve(user)
return deferred.promise
}
]

View file

@ -3,6 +3,7 @@
@import "./editor/toolbar.less";
@import "./editor/left-menu.less";
@import "./editor/pdf.less";
@import "./editor/share.less";
.full-size {
position: absolute;

View file

@ -0,0 +1,49 @@
.modal-body-share {
h3 {
border-bottom: 1px solid @gray-lighter;
padding-bottom: @line-height-computed / 4;
margin: 0;
font-size: 1rem;
}
.project-member, .public-access-level {
padding: (@line-height-computed / 2) 0;
border-bottom: 1px solid @gray-lighter;
font-size: 14px;
}
.public-access-level {
color: @gray;
padding-top: 0;
font-size: 12px;
}
.project-member {
&:hover {
background-color: @gray-lightest;
}
}
.invite-controls {
.small {
padding: 2px;
}
padding: @line-height-computed / 2;
background-color: @gray-lightest;
margin-top: @line-height-computed / 2;
form {
.form-group {
margin-bottom: @line-height-computed / 2;
&:last-child {
margin-bottom: 0;
}
}
.privileges {
display: inline-block;
width: auto;
height: 30px;
font-size: 14px;
}
}
}
}

View file

@ -126,6 +126,10 @@
.btn-block + .btn-block {
margin-left: 0;
}
.modal-footer-left {
float: left;
}
}
// Scale up the modal