mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Add in basic share modal
This commit is contained in:
parent
9097fdd930
commit
be48ab2a30
13 changed files with 231 additions and 30 deletions
|
@ -26,7 +26,8 @@ module.exports =
|
||||||
|
|
||||||
addUserToProject: (project_id, email, privilegeLevel, callback)->
|
addUserToProject: (project_id, email, privilegeLevel, callback)->
|
||||||
emails = mimelib.parseAddresses(email)
|
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 = @
|
self = @
|
||||||
User.findOne {'email':email}, (err, user)->
|
User.findOne {'email':email}, (err, user)->
|
||||||
async.waterfall [
|
async.waterfall [
|
||||||
|
|
|
@ -138,7 +138,7 @@ module.exports = EditorController =
|
||||||
CollaboratorsHandler.addUserToProject project_id, email, privileges, (err, user)=>
|
CollaboratorsHandler.addUserToProject project_id, email, privileges, (err, user)=>
|
||||||
ProjectEntityHandler.flushProjectToThirdPartyDataStore project_id, "", ->
|
ProjectEntityHandler.flushProjectToThirdPartyDataStore project_id, "", ->
|
||||||
EditorRealTimeController.emitToRoom(project_id, 'userAddedToProject', user, privileges)
|
EditorRealTimeController.emitToRoom(project_id, 'userAddedToProject', user, privileges)
|
||||||
callback null, true
|
callback null, ProjectEditorHandler.buildUserModelView(user, privileges)
|
||||||
|
|
||||||
removeUserFromProject: (project_id, user_id, callback)->
|
removeUserFromProject: (project_id, user_id, callback)->
|
||||||
CollaboratorsHandler.removeUserFromProject project_id, user_id, =>
|
CollaboratorsHandler.removeUserFromProject project_id, user_id, =>
|
||||||
|
|
|
@ -37,6 +37,8 @@ block content
|
||||||
|
|
||||||
include ./editor/header
|
include ./editor/header
|
||||||
|
|
||||||
|
include ./editor/share
|
||||||
|
|
||||||
#ide-body(ng-cloak, layout="main", ng-hide="state.loading")
|
#ide-body(ng-cloak, layout="main", ng-hide="state.loading")
|
||||||
.ui-layout-west
|
.ui-layout-west
|
||||||
include ./editor/file-tree
|
include ./editor/file-tree
|
||||||
|
@ -45,33 +47,6 @@ block content
|
||||||
include ./editor/editor
|
include ./editor/editor
|
||||||
include ./editor/track-changes
|
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(src='/socket.io/socket.io.js')
|
||||||
|
|
||||||
script(type='text/javascript').
|
script(type='text/javascript').
|
||||||
|
|
|
@ -13,7 +13,13 @@ header.toolbar.toolbar-header(ng-cloak, ng-hide="state.loading")
|
||||||
i.fa.fa-pencil
|
i.fa.fa-pencil
|
||||||
|
|
||||||
.toolbar-right
|
.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
|
i.fa.fa-fw.fa-group
|
||||||
a.btn.btn-full-height(
|
a.btn.btn-full-height(
|
||||||
href,
|
href,
|
||||||
|
|
61
services/web/app/views/project/editor/share.jade
Normal file
61
services/web/app/views/project/editor/share.jade
Normal 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
|
|
@ -7,6 +7,7 @@ define [
|
||||||
"ide/online-users/OnlineUsersManager"
|
"ide/online-users/OnlineUsersManager"
|
||||||
"ide/track-changes/TrackChangesManager"
|
"ide/track-changes/TrackChangesManager"
|
||||||
"ide/pdf/PdfManager"
|
"ide/pdf/PdfManager"
|
||||||
|
"ide/share/index"
|
||||||
"ide/directives/layout"
|
"ide/directives/layout"
|
||||||
"ide/services/ide"
|
"ide/services/ide"
|
||||||
"directives/focus"
|
"directives/focus"
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
define [
|
||||||
|
"base"
|
||||||
|
], (App) ->
|
||||||
|
App.controller "ShareController", ["$scope", "$modal", ($scope, $modal) ->
|
||||||
|
$scope.openShareProjectModal = () ->
|
||||||
|
$modal.open(
|
||||||
|
templateUrl: "shareProjectModalTemplate"
|
||||||
|
controller: "ShareProjectModalController"
|
||||||
|
scope: $scope
|
||||||
|
)
|
||||||
|
]
|
|
@ -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()
|
||||||
|
]
|
5
services/web/public/coffee/app/ide/share/index.coffee
Normal file
5
services/web/public/coffee/app/ide/share/index.coffee
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
define [
|
||||||
|
"ide/share/controllers/ShareController"
|
||||||
|
"ide/share/controllers/ShareProjectModalController"
|
||||||
|
"ide/share/services/projectMembers"
|
||||||
|
], () ->
|
|
@ -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
|
||||||
|
}
|
||||||
|
]
|
|
@ -3,6 +3,7 @@
|
||||||
@import "./editor/toolbar.less";
|
@import "./editor/toolbar.less";
|
||||||
@import "./editor/left-menu.less";
|
@import "./editor/left-menu.less";
|
||||||
@import "./editor/pdf.less";
|
@import "./editor/pdf.less";
|
||||||
|
@import "./editor/share.less";
|
||||||
|
|
||||||
.full-size {
|
.full-size {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
49
services/web/public/stylesheets/app/editor/share.less
Normal file
49
services/web/public/stylesheets/app/editor/share.less
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -126,6 +126,10 @@
|
||||||
.btn-block + .btn-block {
|
.btn-block + .btn-block {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-footer-left {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scale up the modal
|
// Scale up the modal
|
||||||
|
|
Loading…
Reference in a new issue