Explorar el Código

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

James Allen hace 9 años
padre
commit
beb94b0756

+ 76 - 45
services/web/app/views/project/editor/review-panel.jade

@@ -1,5 +1,10 @@
 #review-panel
 	.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 
 			strong off
 		span.review-panel-toolbar-label(ng-click="editor.wantTrackChanges = false;", ng-if="editor.wantTrackChanges === true") Track Changes is 
@@ -30,10 +35,6 @@
 						entry="entry"
 						threads="reviewPanel.commentThreads"
 						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-indicator-click="toggleReviewPanel();"
 					)
@@ -66,8 +67,6 @@
 					change-entry(
 						entry="entry"
 						user="users[entry.metadata.user_id]"
-						on-reject="rejectChange(entry.id);"
-						on-accept="acceptChange(entry.id);"
 						on-indicator-click="toggleReviewPanel();"
 						ng-click="gotoEntry(doc_id, entry)"
 					)
@@ -76,9 +75,6 @@
 					comment-entry(
 						entry="entry"
 						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-indicator-click="toggleReviewPanel();"
 						ng-click="gotoEntry(doc_id, entry)"
@@ -127,7 +123,7 @@ script(type='text/ng-template', id='changeEntryTemplate')
 						span(ng-switch-when="delete") Deleted 
 							del.rp-content-highlight {{ entry.content }} 
 					.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 }} 
 			.rp-entry-actions
 				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')
 	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(
 			ng-class="{ 'rp-entry-indicator-focused': entry.focused }"
 			ng-click="onIndicatorClick();"
 		)
 			i.fa.fa-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(
-				ng-if="!threads[entry.thread_id].resolved || entry.showWhenResolved"
-				ng-repeat="comment in threads[entry.thread_id].messages"
-				ng-class="comment.user.isSelf ? 'rp-comment-self' : '';"
-			)
-				.rp-avatar(
-					ng-if="!comment.user.isSelf;"
-					style="background-color: hsl({{ comment.user.hue }}, 70%, 50%);"
-				) {{ comment.user.avatar_text | limitTo : 1 }}
-				.rp-comment-body(style="color: hsl({{ comment.user.hue }}, 70%, 90%);")
-					p.rp-comment-content {{ comment.content }}
-					p.rp-comment-metadata
+			div
+				.rp-comment(
+					ng-repeat="comment in threads[entry.thread_id].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 !== threads[entry.thread_id].messages[$index - 1].user.id"
+						) {{ comment.user.name }}: 
+						| {{ comment.content }}
+					.rp-entry-metadata
 						| {{ comment.timestamp | date : 'MMM d, y h:mm a' }}
-						|  • 
-						span(style="color: hsl({{ comment.user.hue }}, 70%, 40%);") {{ comment.user.name }}
-			.rp-comment-reply(ng-if="!threads[entry.thread_id].resolved || entry.showWhenResolved")
+			.rp-comment-reply
 				textarea.rp-comment-input(
 					ng-model="entry.replyContent"
 					ng-keypress="handleCommentReplyKeyPress($event);"
 					stop-propagation="click"
 					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
-				a.rp-entry-button(href, ng-click="onResolve();", ng-if="!threads[entry.thread_id].resolved") 
-					i.fa.fa-check
-					|  Mark as resolved
-				a.rp-entry-button(href, ng-click="onShowThread();", ng-if="threads[entry.thread_id].resolved && !entry.showWhenResolved")
-					|  Show
-				a.rp-entry-button(href, ng-click="onHideThread();", ng-if="threads[entry.thread_id].resolved && entry.showWhenResolved")
-					|  Hide
-				a.rp-entry-button(href, ng-click="onUnresolve();", ng-if="threads[entry.thread_id].resolved") 
-					|  Re-open
-				a.rp-entry-button(href, ng-click="onDelete();", ng-if="threads[entry.thread_id].resolved") 
-					|  Delete
-				
+				a.rp-entry-button(href, ng-click="onResolve();") 
+					i.fa.fa-inbox
+					|  Resolve
+				a.rp-entry-button(href, ng-click="onReply();") 
+					i.fa.fa-reply
+					|  Reply
+	
+script(type='text/ng-template', id='resolvedCommentEntryTemplate')
+	.rp-entry.rp-entry-comment
+		div
+			.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')
 	div
@@ -223,4 +230,28 @@ script(type='text/ng-template', id='addCommentEntryTemplate')
 						|  Cancel
 					a.rp-entry-button(href, ng-click="submitNewComment()") 
 						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"
+				)
+			

+ 2 - 0
services/web/public/coffee/ide/review-panel/ReviewPanelManager.coffee

@@ -5,6 +5,8 @@ define [
 	"ide/review-panel/directives/changeEntry"
 	"ide/review-panel/directives/commentEntry"
 	"ide/review-panel/directives/addCommentEntry"
+	"ide/review-panel/directives/resolvedCommentEntry"
+	"ide/review-panel/directives/resolvedCommentsDropdown"
 	"ide/review-panel/filters/notEmpty"
 	"ide/review-panel/filters/orderOverviewEntries"
 ], () ->

+ 0 - 4
services/web/public/coffee/ide/review-panel/directives/commentEntry.coffee

@@ -10,10 +10,6 @@ define [
 			onResolve: "&"
 			onReply: "&"
 			onIndicatorClick: "&"
-			onDelete: "&"
-			onUnresolve: "&"
-			onShowThread: "&"
-			onHideThread: "&"
 		link: (scope, element, attrs) ->
 			scope.handleCommentReplyKeyPress = (ev) ->
 				if ev.keyCode == 13 and !ev.shiftKey and !ev.ctrlKey and !ev.metaKey

+ 11 - 0
services/web/public/coffee/ide/review-panel/directives/resolvedCommentEntry.coffee

@@ -0,0 +1,11 @@
+define [
+	"base"
+], (App) ->
+	App.directive "resolvedCommentEntry", () ->
+		restrict: "E"
+		templateUrl: "resolvedCommentEntryTemplate"
+		scope: 
+			thread: "="
+			doc: "="
+			onReopen: "&"
+			onDelete: "&"

+ 33 - 0
services/web/public/coffee/ide/review-panel/directives/resolvedCommentsDropdown.coffee

@@ -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
+
+						

+ 70 - 55
services/web/public/stylesheets/app/editor/review-panel.less

@@ -100,7 +100,6 @@
 	.rp-size-expanded & {
 		display: flex;
 		align-items: center;
-		justify-content: space-between;
 		padding: 0 5px;
 	}
 	.rp-state-current-file & {
@@ -120,6 +119,8 @@
 	.review-panel-toolbar-label {
 		cursor: pointer;
 		margin-right: 5px;
+		text-align: right;
+		flex-grow: 1;
 	}
 
 .rp-entry-list {
@@ -229,6 +230,10 @@
 		border-bottom: solid 1px @rp-border-grey;
 		cursor: pointer;
 	}
+	.resolved-comments-dropdown & {
+		position: static;
+		margin-bottom: 5px;
+	}
 
 	border-left: solid @rp-entry-ribbon-width transparent;
 	border-radius: 3px;
@@ -291,8 +296,6 @@
 
 			.rp-entry-metadata {
 				font-size: @rp-small-font-size;
-				.rp-state-overview & {
-				}
 			}
 				.rp-entry-user {
 					font-weight: @rp-semibold-weight;
@@ -328,68 +331,38 @@
 		}
 
 	.rp-comment {
-		display: flex;
-		align-items: flex-start;
-		padding: 5px;
+		margin: 2px 5px;
+		padding-bottom: 3px;
+		line-height: 1.4;
+		border-bottom: solid 1px @rp-border-grey;
+
+		&:last-child {
+			margin-bottom: 2px;
+			border-bottom-width: 0;
+		}
 
 		.rp-state-overview & {
-			padding: 3px 0;
-			line-height: 1.2;
+			padding: 0;
 		}
 	}
-		.rp-comment-body {
-			position: relative;
-			background-color: currentColor;
-			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-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-metadata {
+			color: @rp-type-blue;
+			font-size: @rp-small-font-size;
+			margin: 0;
 		}
 
-		.rp-comment-resolved-description {
-			padding: 5px;
+	.rp-comment-reply {
+		padding: 0 5px;
 
-			.rp-state-overview & {
-				padding: 0px;
-			}
+		.rp-state-overview & {
+			padding: 3px 0 0;
 		}
+	}
 
 	.rp-add-comment-btn {
 		.rp-button();
@@ -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;
+	}
+}