Merge branch 'ja-track-changes' of github.com:sharelatex/web-sharelatex into ja-track-changes

This commit is contained in:
James Allen
2017-01-06 13:42:08 +01:00
6 changed files with 195 additions and 107 deletions
@@ -1,5 +1,10 @@
#review-panel #review-panel
.review-panel-toolbar .review-panel-toolbar
resolved-comments-dropdown(
entries="reviewPanel.entries"
threads="reviewPanel.commentThreads"
docs="docs"
)
span.review-panel-toolbar-label(ng-click="editor.wantTrackChanges = true;", ng-if="editor.wantTrackChanges === false") Track Changes is span.review-panel-toolbar-label(ng-click="editor.wantTrackChanges = true;", ng-if="editor.wantTrackChanges === false") Track Changes is
strong off strong off
span.review-panel-toolbar-label(ng-click="editor.wantTrackChanges = false;", ng-if="editor.wantTrackChanges === true") Track Changes is span.review-panel-toolbar-label(ng-click="editor.wantTrackChanges = false;", ng-if="editor.wantTrackChanges === true") Track Changes is
@@ -30,10 +35,6 @@
entry="entry" entry="entry"
threads="reviewPanel.commentThreads" threads="reviewPanel.commentThreads"
on-resolve="resolveComment(entry, entry_id)" on-resolve="resolveComment(entry, entry_id)"
on-unresolve="unresolveComment(entry, entry_id)"
on-show-thread="showThread(entry)"
on-hide-thread="hideThread(entry)"
on-delete="deleteComment(entry_id)"
on-reply="submitReply(entry, entry_id);" on-reply="submitReply(entry, entry_id);"
on-indicator-click="toggleReviewPanel();" on-indicator-click="toggleReviewPanel();"
) )
@@ -66,8 +67,6 @@
change-entry( change-entry(
entry="entry" entry="entry"
user="users[entry.metadata.user_id]" user="users[entry.metadata.user_id]"
on-reject="rejectChange(entry.id);"
on-accept="acceptChange(entry.id);"
on-indicator-click="toggleReviewPanel();" on-indicator-click="toggleReviewPanel();"
ng-click="gotoEntry(doc_id, entry)" ng-click="gotoEntry(doc_id, entry)"
) )
@@ -76,9 +75,6 @@
comment-entry( comment-entry(
entry="entry" entry="entry"
users="users" users="users"
on-resolve="resolveComment(entry, entry.id)"
on-unresolve="unresolveComment(entry, entry.id)"
on-delete="deleteComment(entry.id)"
on-reply="submitReply(entry, entry_id);" on-reply="submitReply(entry, entry_id);"
on-indicator-click="toggleReviewPanel();" on-indicator-click="toggleReviewPanel();"
ng-click="gotoEntry(doc_id, entry)" ng-click="gotoEntry(doc_id, entry)"
@@ -127,7 +123,7 @@ script(type='text/ng-template', id='changeEntryTemplate')
span(ng-switch-when="delete") Deleted  span(ng-switch-when="delete") Deleted 
del.rp-content-highlight {{ entry.content }} del.rp-content-highlight {{ entry.content }}
.rp-entry-metadata .rp-entry-metadata
span {{ entry.metadata.ts | date : 'MMM d, y h:mm a' }} •  | {{ entry.metadata.ts | date : 'MMM d, y h:mm a' }} • 
span.rp-entry-user(style="color: hsl({{ user.hue }}, 70%, 40%);") {{ user.name }} span.rp-entry-user(style="color: hsl({{ user.hue }}, 70%, 40%);") {{ user.name }}
.rp-entry-actions .rp-entry-actions
a.rp-entry-button(href, ng-click="onReject();") a.rp-entry-button(href, ng-click="onReject();")
@@ -139,55 +135,66 @@ script(type='text/ng-template', id='changeEntryTemplate')
script(type='text/ng-template', id='commentEntryTemplate') script(type='text/ng-template', id='commentEntryTemplate')
div div
.rp-entry-callout.rp-entry-callout-comment(ng-if="!threads[entry.thread_id].resolved") .rp-entry-callout.rp-entry-callout-comment
.rp-entry-indicator( .rp-entry-indicator(
ng-class="{ 'rp-entry-indicator-focused': entry.focused }" ng-class="{ 'rp-entry-indicator-focused': entry.focused }"
ng-click="onIndicatorClick();" ng-click="onIndicatorClick();"
) )
i.fa.fa-comment i.fa.fa-comment
.rp-entry.rp-entry-comment( .rp-entry.rp-entry-comment(
ng-class="{ 'rp-entry-focused': entry.focused, 'rp-entry-comment-resolved': threads[entry.thread_id].resolved}" ng-class="{ 'rp-entry-focused': entry.focused }"
) )
.rp-comment( div
ng-if="!threads[entry.thread_id].resolved || entry.showWhenResolved" .rp-comment(
ng-repeat="comment in threads[entry.thread_id].messages" ng-repeat="comment in threads[entry.thread_id].messages track by comment.id"
ng-class="comment.user.isSelf ? 'rp-comment-self' : '';" )
) p.rp-comment-content
.rp-avatar( span.rp-entry-user(
ng-if="!comment.user.isSelf;" style="color: hsl({{ comment.user.hue }}, 70%, 40%);"
style="background-color: hsl({{ comment.user.hue }}, 70%, 50%);" ng-if="$first || comment.user.id !== threads[entry.thread_id].messages[$index - 1].user.id"
) {{ comment.user.avatar_text | limitTo : 1 }} ) {{ comment.user.name }}: 
.rp-comment-body(style="color: hsl({{ comment.user.hue }}, 70%, 90%);") | {{ comment.content }}
p.rp-comment-content {{ comment.content }} .rp-entry-metadata
p.rp-comment-metadata
| {{ comment.timestamp | date : 'MMM d, y h:mm a' }} | {{ comment.timestamp | date : 'MMM d, y h:mm a' }}
|  •  .rp-comment-reply
span(style="color: hsl({{ comment.user.hue }}, 70%, 40%);") {{ comment.user.name }}
.rp-comment-reply(ng-if="!threads[entry.thread_id].resolved || entry.showWhenResolved")
textarea.rp-comment-input( textarea.rp-comment-input(
ng-model="entry.replyContent" ng-model="entry.replyContent"
ng-keypress="handleCommentReplyKeyPress($event);" ng-keypress="handleCommentReplyKeyPress($event);"
stop-propagation="click" stop-propagation="click"
placeholder="{{ 'Hit \"Enter\" to reply' + (entry.resolved ? ' and re-open' : '') }}" placeholder="{{ 'Hit \"Enter\" to reply' + (entry.resolved ? ' and re-open' : '') }}"
) )
.rp-comment-resolved-description(ng-if="threads[entry.thread_id].resolved && !entry.showWhenResolved")
div
| Comment resolved by
span(style="color: hsl({{ threads[entry.thread_id].resolved_by_user.hue }}, 70%, 40%);") {{ threads[entry.thread_id].resolved_by_user.name }}
div {{ threads[entry.thread_id].resolved_at | date : 'MMM d, y h:mm a' }}
.rp-entry-actions .rp-entry-actions
a.rp-entry-button(href, ng-click="onResolve();", ng-if="!threads[entry.thread_id].resolved") a.rp-entry-button(href, ng-click="onResolve();")
i.fa.fa-check i.fa.fa-inbox
|  Mark as resolved |  Resolve
a.rp-entry-button(href, ng-click="onShowThread();", ng-if="threads[entry.thread_id].resolved && !entry.showWhenResolved") a.rp-entry-button(href, ng-click="onReply();")
|  Show i.fa.fa-reply
a.rp-entry-button(href, ng-click="onHideThread();", ng-if="threads[entry.thread_id].resolved && entry.showWhenResolved") |  Reply
|  Hide
a.rp-entry-button(href, ng-click="onUnresolve();", ng-if="threads[entry.thread_id].resolved") script(type='text/ng-template', id='resolvedCommentEntryTemplate')
|  Re-open .rp-entry.rp-entry-comment
a.rp-entry-button(href, ng-click="onDelete();", ng-if="threads[entry.thread_id].resolved") div
|  Delete .rp-comment-context
| Quoted text on 
.rp-comment-context-file {{ doc.doc.name }}
.rp-comment-context-quote {{ thread.content }}
.rp-comment(
ng-repeat="comment in thread.messages track by comment.id"
)
p.rp-comment-content
span.rp-entry-user(
style="color: hsl({{ comment.user.hue }}, 70%, 40%);"
ng-if="$first || comment.user.id !== thread.messages[$index - 1].user.id"
) {{ comment.user.name }}: 
| {{ comment.content }}
.rp-entry-metadata
| {{ comment.timestamp | date : 'MMM d, y h:mm a' }}
.rp-entry-actions
a.rp-entry-button(href, ng-click="onUnresolve();")
|  Re-open
a.rp-entry-button(href, ng-click="onDelete();")
|  Delete
script(type='text/ng-template', id='addCommentEntryTemplate') script(type='text/ng-template', id='addCommentEntryTemplate')
div div
@@ -223,4 +230,28 @@ script(type='text/ng-template', id='addCommentEntryTemplate')
|  Cancel |  Cancel
a.rp-entry-button(href, ng-click="submitNewComment()") a.rp-entry-button(href, ng-click="submitNewComment()")
i.fa.fa-comment i.fa.fa-comment
|  Comment |  Comment
script(type='text/ng-template', id='resolvedCommentsDropdownTemplate')
.resolved-comments
.resolved-comments-backdrop(
ng-class="{ 'resolved-comments-backdrop-visible' : state.isOpen }"
ng-click="state.isOpen = !state.isOpen"
)
a.resolved-comments-toggle(
href
ng-click="state.isOpen = !state.isOpen"
)
i.fa.fa-inbox
.resolved-comments-dropdown(
ng-class="{ 'resolved-comments-dropdown-open' : state.isOpen }"
)
div(
ng-repeat="doc in docs"
)
resolved-comment-entry(
ng-repeat="thread in resolvedCommentsPerFile[doc.doc.id]"
thread="thread"
doc="doc"
)
@@ -5,6 +5,8 @@ define [
"ide/review-panel/directives/changeEntry" "ide/review-panel/directives/changeEntry"
"ide/review-panel/directives/commentEntry" "ide/review-panel/directives/commentEntry"
"ide/review-panel/directives/addCommentEntry" "ide/review-panel/directives/addCommentEntry"
"ide/review-panel/directives/resolvedCommentEntry"
"ide/review-panel/directives/resolvedCommentsDropdown"
"ide/review-panel/filters/notEmpty" "ide/review-panel/filters/notEmpty"
"ide/review-panel/filters/orderOverviewEntries" "ide/review-panel/filters/orderOverviewEntries"
], () -> ], () ->
@@ -10,10 +10,6 @@ define [
onResolve: "&" onResolve: "&"
onReply: "&" onReply: "&"
onIndicatorClick: "&" onIndicatorClick: "&"
onDelete: "&"
onUnresolve: "&"
onShowThread: "&"
onHideThread: "&"
link: (scope, element, attrs) -> link: (scope, element, attrs) ->
scope.handleCommentReplyKeyPress = (ev) -> scope.handleCommentReplyKeyPress = (ev) ->
if ev.keyCode == 13 and !ev.shiftKey and !ev.ctrlKey and !ev.metaKey if ev.keyCode == 13 and !ev.shiftKey and !ev.ctrlKey and !ev.metaKey
@@ -0,0 +1,11 @@
define [
"base"
], (App) ->
App.directive "resolvedCommentEntry", () ->
restrict: "E"
templateUrl: "resolvedCommentEntryTemplate"
scope:
thread: "="
doc: "="
onReopen: "&"
onDelete: "&"
@@ -0,0 +1,33 @@
define [
"base"
], (App) ->
App.directive "resolvedCommentsDropdown", () ->
restrict: "E"
templateUrl: "resolvedCommentsDropdownTemplate"
scope:
entries : "="
threads : "="
docs : "="
link: (scope, element, attrs) ->
scope.state =
isOpen: false
scope.resolvedCommentsPerFile = {}
filterResolvedComments = () ->
scope.resolvedCommentsPerFile = {}
for fileId, fileEntries of scope.entries
scope.resolvedCommentsPerFile[fileId] = {}
for entryId, entry of fileEntries
if entry.type == "comment" and scope.threads[entry.thread_id].resolved?
scope.resolvedCommentsPerFile[fileId][entryId] = angular.copy scope.threads[entry.thread_id]
scope.resolvedCommentsPerFile[fileId][entryId].content = entry.content
console.log scope.resolvedCommentsPerFile
scope.$watchCollection "entries", filterResolvedComments
scope.$watchCollection "threads", filterResolvedComments
@@ -100,7 +100,6 @@
.rp-size-expanded & { .rp-size-expanded & {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between;
padding: 0 5px; padding: 0 5px;
} }
.rp-state-current-file & { .rp-state-current-file & {
@@ -120,6 +119,8 @@
.review-panel-toolbar-label { .review-panel-toolbar-label {
cursor: pointer; cursor: pointer;
margin-right: 5px; margin-right: 5px;
text-align: right;
flex-grow: 1;
} }
.rp-entry-list { .rp-entry-list {
@@ -229,6 +230,10 @@
border-bottom: solid 1px @rp-border-grey; border-bottom: solid 1px @rp-border-grey;
cursor: pointer; cursor: pointer;
} }
.resolved-comments-dropdown & {
position: static;
margin-bottom: 5px;
}
border-left: solid @rp-entry-ribbon-width transparent; border-left: solid @rp-entry-ribbon-width transparent;
border-radius: 3px; border-radius: 3px;
@@ -291,8 +296,6 @@
.rp-entry-metadata { .rp-entry-metadata {
font-size: @rp-small-font-size; font-size: @rp-small-font-size;
.rp-state-overview & {
}
} }
.rp-entry-user { .rp-entry-user {
font-weight: @rp-semibold-weight; font-weight: @rp-semibold-weight;
@@ -328,69 +331,39 @@
} }
.rp-comment { .rp-comment {
display: flex; margin: 2px 5px;
align-items: flex-start; padding-bottom: 3px;
padding: 5px; line-height: 1.4;
border-bottom: solid 1px @rp-border-grey;
&:last-child {
margin-bottom: 2px;
border-bottom-width: 0;
}
.rp-state-overview & { .rp-state-overview & {
padding: 3px 0; padding: 0;
line-height: 1.2;
} }
} }
.rp-comment-body { .rp-comment-content {
position: relative; margin: 0;
background-color: currentColor; color: @rp-type-darkgrey;
flex-grow: 1;
padding: 2px 5px;
margin-left: @rp-entry-arrow-width;
border-radius: 3px;
.rp-comment-self & {
margin-left: 0;
margin-right: @rp-entry-arrow-width;
}
&::after {
.triangle(left, @rp-entry-arrow-width, @rp-entry-arrow-width * 1.5, inherit);
top: (@review-off-width / 2) - @rp-entry-arrow-width;
left: -@rp-entry-arrow-width;
content: '';
.rp-comment-self & {
.triangle(right, @rp-entry-arrow-width, @rp-entry-arrow-width * 1.5, inherit);
right: -@rp-entry-arrow-width;
left: auto;
}
}
}
.rp-comment-content {
margin: 0;
color: @rp-type-darkgrey;
}
.rp-comment-metadata {
color: @rp-type-blue;
font-size: @rp-small-font-size;
margin: 0;
}
.rp-comment-reply {
padding: 0 5px;
.rp-state-overview & {
padding: 3px 0 0;
}
} }
.rp-comment-resolved-description { .rp-comment-metadata {
padding: 5px; color: @rp-type-blue;
font-size: @rp-small-font-size;
.rp-state-overview & { margin: 0;
padding: 0px;
}
} }
.rp-comment-reply {
padding: 0 5px;
.rp-state-overview & {
padding: 3px 0 0;
}
}
.rp-add-comment-btn { .rp-add-comment-btn {
.rp-button(); .rp-button();
display: block; display: block;
@@ -665,3 +638,45 @@
} }
} }
.resolved-comments-toggle {
font-size: @rp-icon-large-size;
color: lighten(@rp-type-blue, 25%);
border: solid 1px @rp-border-grey;
border-radius: 3px;
padding: 0 4px;
&:hover,
&:focus {
text-decoration: none;
color: @rp-type-blue;
}
}
.resolved-comments-backdrop {
display: none;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0, 0, 0, .5);
&-visible {
display: block;
}
}
.resolved-comments-dropdown {
display: none;
position: absolute;
width: 300px;
background-color: @rp-bg-blue;
text-align: left;
padding: 5px;
border-radius: 3px;
&-open {
display: block;
}
}