mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Sort out permissions and displaying anonymous users
This commit is contained in:
parent
58e4e92d84
commit
a8d371d2f6
15 changed files with 111 additions and 43 deletions
|
@ -25,7 +25,8 @@ div.full-size(
|
|||
cursor-position="editor.cursorPosition",
|
||||
goto-line="editor.gotoLine",
|
||||
resize-on="layout:main:resize,layout:pdf:resize",
|
||||
annotations="pdf.logEntryAnnotations[editor.open_doc_id]"
|
||||
annotations="pdf.logEntryAnnotations[editor.open_doc_id]",
|
||||
read-only="!permissions.write"
|
||||
)
|
||||
|
||||
.ui-layout-east
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
aside#file-tree(ng-controller="FileTreeController")
|
||||
.toolbar.toolbar-small
|
||||
.toolbar.toolbar-small(ng-if="permissions.write")
|
||||
a(
|
||||
href,
|
||||
ng-click="openNewDocModal()",
|
||||
|
@ -39,14 +39,19 @@ aside#file-tree(ng-controller="FileTreeController")
|
|||
)
|
||||
i.fa.fa-trash-o
|
||||
|
||||
.file-tree-inner(ng-if="rootFolder", ng-controller="FileTreeRootFolderController")
|
||||
.file-tree-inner(
|
||||
ng-if="rootFolder",
|
||||
ng-controller="FileTreeRootFolderController",
|
||||
ng-class="{ 'no-toolbar': !permissions.write }"
|
||||
)
|
||||
ul.list-unstyled.file-tree-list(
|
||||
droppable
|
||||
droppable="permissions.write"
|
||||
accept=".entity-name"
|
||||
on-drop-callback="onDrop"
|
||||
)
|
||||
file-entity(
|
||||
entity="entity",
|
||||
permissions="permissions",
|
||||
ng-repeat="entity in rootFolder.children | orderBy:[orderByFoldersFirst, 'name']"
|
||||
)
|
||||
|
||||
|
@ -76,11 +81,12 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
|||
.entity(ng-if="entity.type != 'folder'")
|
||||
.entity-name(
|
||||
ng-click="select()"
|
||||
ng-dblclick="startRenaming()"
|
||||
draggable
|
||||
ng-dblclick="permissions.write && startRenaming()"
|
||||
draggable="permissions.write"
|
||||
context-menu
|
||||
data-target="context-menu-{{ entity.id }}"
|
||||
context-menu-container="body"
|
||||
context-menu-disabled="!permissions.write"
|
||||
)
|
||||
//- Just a spacer to align with folders
|
||||
i.fa.fa-fw.toggle(ng-if="entity.type != 'folder'")
|
||||
|
@ -92,6 +98,7 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
|||
ng-hide="entity.renaming"
|
||||
) {{ entity.name }}
|
||||
input(
|
||||
ng-if="permissions.write",
|
||||
ng-show="entity.renaming",
|
||||
ng-model="inputs.name",
|
||||
ng-blur="finishRenaming()",
|
||||
|
@ -99,7 +106,10 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
|||
on-enter="finishRenaming()"
|
||||
)
|
||||
|
||||
span.dropdown(ng-show="entity.selected")
|
||||
span.dropdown(
|
||||
ng-show="entity.selected",
|
||||
ng-if="permissions.write"
|
||||
)
|
||||
a.dropdown-toggle(href)
|
||||
i.fa.fa-chevron-down
|
||||
|
||||
|
@ -117,7 +127,10 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
|||
ng-click="openDeleteModal()"
|
||||
) Delete
|
||||
|
||||
div.dropdown.context-menu(id="context-menu-{{ entity.id }}")
|
||||
div.dropdown.context-menu(
|
||||
id="context-menu-{{ entity.id }}",
|
||||
ng-if="permissions.write"
|
||||
)
|
||||
ul.dropdown-menu
|
||||
li
|
||||
a(
|
||||
|
@ -138,9 +151,9 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
|||
.entity(ng-if="entity.type == 'folder'", ng-controller="FileTreeFolderController")
|
||||
.entity-name(
|
||||
ng-click="select()"
|
||||
ng-dblclick="startRenaming()"
|
||||
draggable
|
||||
droppable
|
||||
ng-dblclick="permissions.write && startRenaming()"
|
||||
draggable="permissions.write"
|
||||
droppable="permissions.write"
|
||||
accept=".entity-name"
|
||||
on-drop-callback="onDrop"
|
||||
)
|
||||
|
@ -148,6 +161,7 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
|||
context-menu
|
||||
data-target="context-menu-{{ entity.id }}"
|
||||
context-menu-container="body"
|
||||
context-menu-disabled="!permissions.write"
|
||||
)
|
||||
i.fa.fa-fw.toggle(
|
||||
ng-if="entity.type == 'folder'"
|
||||
|
@ -168,6 +182,7 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
|||
ng-hide="entity.renaming"
|
||||
) {{ entity.name }}
|
||||
input(
|
||||
ng-if="permissions.write",
|
||||
ng-show="entity.renaming",
|
||||
ng-model="inputs.name",
|
||||
ng-blur="finishRenaming()",
|
||||
|
@ -175,7 +190,10 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
|||
on-enter="finishRenaming()"
|
||||
)
|
||||
|
||||
span.dropdown(ng-show="entity.selected")
|
||||
span.dropdown(
|
||||
ng-if="permissions.write"
|
||||
ng-show="entity.selected"
|
||||
)
|
||||
a.dropdown-toggle(href)
|
||||
i.fa.fa-chevron-down
|
||||
|
||||
|
@ -212,7 +230,10 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
|||
ng-click="openUploadFileModal()"
|
||||
) Upload File
|
||||
|
||||
.dropdown.context-menu(id="context-menu-{{ entity.id }}")
|
||||
.dropdown.context-menu(
|
||||
ng-if="permissions.write"
|
||||
id="context-menu-{{ entity.id }}"
|
||||
)
|
||||
ul.dropdown-menu
|
||||
li
|
||||
a(
|
||||
|
@ -254,12 +275,13 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
|||
ul.list-unstyled(
|
||||
ng-if="entity.type == 'folder'"
|
||||
ng-show="expanded"
|
||||
droppable
|
||||
droppable="permissions.write"
|
||||
accept=".entity-name"
|
||||
on-drop-callback="onDrop"
|
||||
)
|
||||
file-entity(
|
||||
entity="child",
|
||||
permissions="permissions",
|
||||
ng-repeat="child in entity.children | orderBy:[orderByFoldersFirst, 'name']"
|
||||
)
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ header.toolbar.toolbar-header(ng-cloak, ng-hide="state.loading")
|
|||
.toolbar-right
|
||||
a.btn.btn-full-height(
|
||||
href,
|
||||
ng-if="permissions.admin",
|
||||
tooltip="Share",
|
||||
tooltip-placement="bottom",
|
||||
ng-click="openShareProjectModal()",
|
||||
|
|
|
@ -9,7 +9,7 @@ script(type='text/ng-template', id='shareProjectModalTemplate')
|
|||
.modal-body.modal-body-share
|
||||
.container-fluid
|
||||
.row.public-access-level(ng-show="project.publicAccesLevel == 'private'")
|
||||
.col-md-12.text-center
|
||||
.col-xs-12.text-center
|
||||
| This project is private and can only be accessed by the people below.
|
||||
|
|
||||
a(
|
||||
|
@ -17,7 +17,7 @@ script(type='text/ng-template', id='shareProjectModalTemplate')
|
|||
ng-click="openMakePublicModal()"
|
||||
) Make Public
|
||||
.row.public-access-level(ng-show="project.publicAccesLevel != 'private'")
|
||||
.col-md-12.text-center
|
||||
.col-xs-12.text-center
|
||||
strong(ng-if="project.publicAccesLevel == 'readAndWrite'") This project is public and can be edited by anyone with the URL.
|
||||
strong(ng-if="project.publicAccesLevel == 'readOnly'") This project is public and can be viewed by anyone with the URL.
|
||||
|
|
||||
|
@ -26,16 +26,16 @@ script(type='text/ng-template', id='shareProjectModalTemplate')
|
|||
ng-click="openMakePrivateModal()"
|
||||
) Make Private
|
||||
.row.project-member
|
||||
.col-md-8 {{ project.owner.email }}
|
||||
.col-xs-8 {{ project.owner.email }}
|
||||
.text-right(
|
||||
ng-class="{'col-md-3': project.members.length > 0, 'col-md-4': project.members.length == 0}"
|
||||
ng-class="{'col-xs-3': project.members.length > 0, 'col-xs-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
|
||||
.col-xs-8 {{ member.email }}
|
||||
.col-xs-3.text-right
|
||||
span(ng-show="member.privileges == 'readAndWrite'") Can Edit
|
||||
span(ng-show="member.privileges == 'readOnly'") Read Only
|
||||
.col-md-1
|
||||
.col-xs-1
|
||||
a(
|
||||
href
|
||||
tooltip="Remove collaborator"
|
||||
|
|
|
@ -70,8 +70,11 @@ div#trackChanges(ng-show="ui.view == 'track-changes'")
|
|||
div.users
|
||||
div.user(ng-repeat="update_user in update.meta.users")
|
||||
.color-square(ng-style="{'background-color': 'hsl({{ update_user.hue }}, 100%, 50%)'}")
|
||||
span(ng-if="update_user.id != user.id") {{user.first_name}} {{user.last_name}}
|
||||
span(ng-if="update_user.id != user.id") {{update_user.first_name}} {{update_user.last_name}}
|
||||
span(ng-if="update_user.id == user.id") You
|
||||
div.user(ng-if="update.meta.users.length == 0")
|
||||
.color-square(style="background-color: hsl(100, 100%, 50%)")
|
||||
span Anonymous
|
||||
|
||||
.loading(ng-show="trackChanges.loading")
|
||||
i.fa.fa-spin.fa-refresh
|
||||
|
|
|
@ -5,6 +5,7 @@ define [
|
|||
"ide/editor/EditorManager"
|
||||
"ide/online-users/OnlineUsersManager"
|
||||
"ide/track-changes/TrackChangesManager"
|
||||
"ide/permissions/PermissionsManager"
|
||||
"ide/pdf/PdfManager"
|
||||
"ide/settings/index"
|
||||
"ide/share/index"
|
||||
|
@ -22,6 +23,7 @@ define [
|
|||
EditorManager
|
||||
OnlineUsersManager
|
||||
TrackChangesManager
|
||||
PermissionsManager
|
||||
PdfManager
|
||||
) ->
|
||||
App.controller "IdeController", ["$scope", "$timeout", "ide", ($scope, $timeout, ide) ->
|
||||
|
@ -59,6 +61,7 @@ define [
|
|||
ide.onlineUsersManager = new OnlineUsersManager(ide, $scope)
|
||||
ide.trackChangesManager = new TrackChangesManager(ide, $scope)
|
||||
ide.pdfManager = new PdfManager(ide, $scope)
|
||||
ide.permissionsManager = new PermissionsManager(ide, $scope)
|
||||
]
|
||||
|
||||
angular.bootstrap(document.body, ["SharelatexApp"])
|
|
@ -57,6 +57,7 @@ define [], () ->
|
|||
@$scope.$apply () =>
|
||||
@$scope.protocolVersion = protocolVersion
|
||||
@$scope.project = project
|
||||
@$scope.permissionsLevel = permissionsLevel
|
||||
@$scope.state.load_progress = 100
|
||||
@$scope.state.loading = false
|
||||
@$scope.$emit "project:joined"
|
||||
|
|
|
@ -204,16 +204,16 @@ define [
|
|||
_getColorScheme: (hue) ->
|
||||
if @_isDarkTheme()
|
||||
return {
|
||||
cursor: "hsl(#{hue}, 100%, 50%)"
|
||||
labelBackgroundColor: "hsl(#{hue}, 100%, 50%)"
|
||||
cursor: "hsl(#{hue}, 70%, 50%)"
|
||||
labelBackgroundColor: "hsl(#{hue}, 70%, 50%)"
|
||||
highlightBackgroundColor: "hsl(#{hue}, 100%, 28%);"
|
||||
strikeThroughBackgroundColor: "hsl(#{hue}, 100%, 20%);"
|
||||
strikeThroughForegroundColor: "hsl(#{hue}, 100%, 60%);"
|
||||
}
|
||||
else
|
||||
return {
|
||||
cursor: "hsl(#{hue}, 100%, 50%)"
|
||||
labelBackgroundColor: "hsl(#{hue}, 100%, 50%)"
|
||||
cursor: "hsl(#{hue}, 70%, 50%)"
|
||||
labelBackgroundColor: "hsl(#{hue}, 70%, 50%)"
|
||||
highlightBackgroundColor: "hsl(#{hue}, 70%, 85%);"
|
||||
strikeThroughBackgroundColor: "hsl(#{hue}, 70%, 95%);"
|
||||
strikeThroughForegroundColor: "hsl(#{hue}, 70%, 40%);"
|
||||
|
|
|
@ -4,9 +4,11 @@ define [
|
|||
App.directive "draggable", () ->
|
||||
return {
|
||||
link: (scope, element, attrs) ->
|
||||
element.draggable
|
||||
delay: 250
|
||||
opacity: 0.7
|
||||
helper: "clone"
|
||||
scroll: true
|
||||
scope.$watch attrs.draggable, (draggable) ->
|
||||
if draggable
|
||||
element.draggable
|
||||
delay: 250
|
||||
opacity: 0.7
|
||||
helper: "clone"
|
||||
scroll: true
|
||||
}
|
|
@ -7,10 +7,11 @@ define [
|
|||
onDropCallback: "="
|
||||
}
|
||||
link: (scope, element, attrs) ->
|
||||
console.log "DROPPABLE", element, scope.onDropCallback
|
||||
element.droppable
|
||||
greedy: true
|
||||
hoverClass: "droppable-hover"
|
||||
accept: attrs.accept
|
||||
drop: scope.onDropCallback
|
||||
scope.$watch attrs.droppable, (droppable) ->
|
||||
if droppable
|
||||
element.droppable
|
||||
greedy: true
|
||||
hoverClass: "droppable-hover"
|
||||
accept: attrs.accept
|
||||
drop: scope.onDropCallback
|
||||
}
|
|
@ -6,10 +6,18 @@ define [
|
|||
restrict: "E"
|
||||
scope: {
|
||||
entity: "="
|
||||
permissions: "="
|
||||
}
|
||||
templateUrl: "entityListItemTemplate"
|
||||
compile: (element) ->
|
||||
RecursionHelper.compile element, (scope, element, attrs, ctrl) ->
|
||||
# Link function here if needed
|
||||
# Don't freak out if we're already in an apply callback
|
||||
scope.$originalApply = scope.$apply
|
||||
scope.$apply = (fn = () ->) ->
|
||||
phase = @$root.$$phase
|
||||
if (phase == '$apply' || phase == '$digest')
|
||||
fn()
|
||||
else
|
||||
@$originalApply(fn);
|
||||
}
|
||||
]
|
|
@ -56,7 +56,7 @@ define [
|
|||
OWN_HUE: 200 # We will always appear as this color to ourselves
|
||||
ANONYMOUS_HUE: 100
|
||||
getHueForUserId: (user_id) ->
|
||||
if !user_id?
|
||||
if !user_id? or user_id == "anonymous-user"
|
||||
return @ANONYMOUS_HUE
|
||||
|
||||
if window.user.id == user_id
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
define [], () ->
|
||||
class PermissionsManager
|
||||
constructor: (@ide, @$scope) ->
|
||||
@$scope.$watch "permissionsLevel", (permissionsLevel) =>
|
||||
@$scope.permissions =
|
||||
read: false
|
||||
write: false
|
||||
admin: false
|
||||
if permissionsLevel?
|
||||
if permissionsLevel == "readOnly"
|
||||
@$scope.permissions.read = true
|
||||
else if permissionsLevel == "readAndWrite"
|
||||
@$scope.permissions.read = true
|
||||
@$scope.permissions.write = true
|
||||
else if permissionsLevel == "owner"
|
||||
@$scope.permissions.read = true
|
||||
@$scope.permissions.write = true
|
||||
@$scope.permissions.admin = true
|
||||
|
|
@ -157,21 +157,24 @@ define [
|
|||
}
|
||||
|
||||
if entry.i? or entry.d?
|
||||
name = "#{entry.meta.user.first_name} #{entry.meta.user.last_name}"
|
||||
if entry.meta.user.id == @$scope.user.id
|
||||
if entry.meta.user?
|
||||
name = "#{entry.meta.user.first_name} #{entry.meta.user.last_name}"
|
||||
else
|
||||
name = "Anonymous"
|
||||
if entry.meta.user?.id == @$scope.user.id
|
||||
name = "you"
|
||||
date = moment(entry.meta.end_ts).format("Do MMM YYYY, h:mm a")
|
||||
if entry.i?
|
||||
highlights.push {
|
||||
label: "Added by #{name} on #{date}"
|
||||
highlight: range
|
||||
hue: @ide.onlineUsersManager.getHueForUserId(entry.meta.user.id)
|
||||
hue: @ide.onlineUsersManager.getHueForUserId(entry.meta.user?.id)
|
||||
}
|
||||
else if entry.d?
|
||||
highlights.push {
|
||||
label: "Deleted by #{name} on #{date}"
|
||||
strikeThrough: range
|
||||
hue: @ide.onlineUsersManager.getHueForUserId(entry.meta.user.id)
|
||||
hue: @ide.onlineUsersManager.getHueForUserId(entry.meta.user?.id)
|
||||
}
|
||||
|
||||
return {text, highlights}
|
||||
|
|
|
@ -9,6 +9,10 @@ aside#file-tree {
|
|||
left: 0;
|
||||
right: 0;
|
||||
overflow-y: auto;
|
||||
|
||||
&.no-toolbar {
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
|
|
Loading…
Reference in a new issue