[ZEPPELIN-2813] refactoring

This commit is contained in:
tinkoff-dwh 2017-08-09 14:43:50 +05:00
parent 514b3f57bc
commit dc67f8fad3
12 changed files with 398 additions and 342 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 118 KiB

View file

@ -141,10 +141,7 @@ limitations under the License.
</ul>
<button type="button"
class="btn btn-default btn-xs"
id="compareRevisions"
data-toggle="modal"
ng-disabled="noteRevisions.length < 2"
data-target="#revisionsComparatorModal"
ng-click="toggleRevisionsComparator()"
tooltip-placement="bottom" uib-tooltip="Compare revisions">
<i class="fa fa-exchange"></i>
</button>

View file

@ -31,6 +31,7 @@ function NotebookCtrl ($scope, $route, $routeParams, $location, $rootScope,
$scope.tableToggled = false
$scope.viewOnly = false
$scope.showSetting = false
$scope.showRevisionsComparator = false
$scope.looknfeelOption = ['default', 'simple', 'report']
$scope.cronOption = [
{name: 'None', value: undefined},
@ -59,11 +60,6 @@ function NotebookCtrl ($scope, $route, $routeParams, $location, $rootScope,
}
$scope.noteRevisions = []
$scope.firstNoteRevisionForCompare = null
$scope.secondNoteRevisionForCompare = null
$scope.mergeNoteRevisionsForCompare = null
$scope.currentFirstRevisionForCompare = 'Choose...'
$scope.currentSecondRevisionForCompare = 'Choose...'
$scope.currentRevision = 'Head'
$scope.revisionView = isRevisionPath($location.path())
@ -294,99 +290,6 @@ function NotebookCtrl ($scope, $route, $routeParams, $location, $rootScope,
}
}
// compare revisions
$scope.compareRevisions = function () {
if ($scope.firstNoteRevisionForCompare && $scope.secondNoteRevisionForCompare) {
let paragraphs1 = $scope.firstNoteRevisionForCompare.note.paragraphs
let paragraphs2 = $scope.secondNoteRevisionForCompare.note.paragraphs
let merge = {
added: [],
deleted: [],
compared: []
}
for (let p1 of paragraphs1) {
let p2 = null
for (let p of paragraphs2) {
if (p1.id === p.id) {
p2 = p
break
}
}
if (p2 === null) {
merge.deleted.push({paragraph: p1, firstString: (p1.text || '').split('\n')[0]})
} else {
let colorClass = ''
let span = null
let text1 = p1.text || ''
let text2 = p2.text || ''
let diff = window.JsDiff.diffLines(text1, text2)
let diffHtml = document.createDocumentFragment()
let identical = true
let identicalClass = 'color-black'
diff.forEach(function(part) {
colorClass = part.added ? 'color-green' : part.removed ? 'color-red' : identicalClass
span = document.createElement('span')
span.className = colorClass
if (identical && colorClass !== identicalClass) {
identical = false
}
span.appendChild(document.createTextNode(part.value))
diffHtml.appendChild(span)
})
let pre = document.createElement('pre')
pre.appendChild(diffHtml)
merge.compared.push(
{paragraph: p1, diff: pre.innerHTML, identical: identical, firstString: (p1.text || '').split('\n')[0]})
}
}
for (let p2 of paragraphs2) {
let p1 = null
for (let p of paragraphs1) {
if (p2.id === p.id) {
p1 = p
break
}
}
if (p1 === null) {
merge.added.push({paragraph: p2, firstString: (p2.text || '').split('\n')[0]})
}
}
$scope.mergeNoteRevisionsForCompare = merge
}
}
$scope.getNoteRevisionForReview = function (revision, position) {
if (position) {
if (position === 'first') {
$scope.currentFirstRevisionForCompare = revision.message
} else {
$scope.currentSecondRevisionForCompare = revision.message
}
websocketMsgSrv.getNoteByRevisionForCompare($routeParams.noteId, revision.id, position)
}
}
$scope.$on('noteRevisionForCompare', function (event, data) {
console.debug('received note revision for compare %o', data)
if (data.note && data.position) {
if (data.position === 'first') {
$scope.firstNoteRevisionForCompare = data
} else {
$scope.secondNoteRevisionForCompare = data
}
if ($scope.firstNoteRevisionForCompare !== null && $scope.secondNoteRevisionForCompare !== null &&
$scope.firstNoteRevisionForCompare.revisionId !== $scope.secondNoteRevisionForCompare.revisionId) {
$scope.compareRevisions()
}
}
})
$scope.runAllParagraphs = function (noteId) {
BootstrapDialog.confirm({
closable: true,
@ -678,6 +581,12 @@ function NotebookCtrl ($scope, $route, $routeParams, $location, $rootScope,
orderChanged: function (event) {}
}
$scope.closeAdditionalBoards = function() {
$scope.closeSetting()
$scope.closePermissions()
$scope.closeRevisionsComparator()
}
$scope.openSetting = function () {
$scope.showSetting = true
getInterpreterBindings()
@ -727,8 +636,26 @@ function NotebookCtrl ($scope, $route, $routeParams, $location, $rootScope,
if ($scope.showSetting) {
$scope.closeSetting()
} else {
$scope.closeAdditionalBoards()
$scope.openSetting()
$scope.closePermissions()
angular.element('html, body').animate({ scrollTop: 0 }, 'slow')
}
}
$scope.openRevisionsComparator = function () {
$scope.showRevisionsComparator = true
}
$scope.closeRevisionsComparator = function () {
$scope.showRevisionsComparator = false
}
$scope.toggleRevisionsComparator = function () {
if ($scope.showRevisionsComparator) {
$scope.closeRevisionsComparator()
} else {
$scope.closeAdditionalBoards()
$scope.openRevisionsComparator()
angular.element('html, body').animate({ scrollTop: 0 }, 'slow')
}
}
@ -965,8 +892,8 @@ function NotebookCtrl ($scope, $route, $routeParams, $location, $rootScope,
angular.element('#selectReaders').select2({})
angular.element('#selectWriters').select2({})
} else {
$scope.closeAdditionalBoards()
$scope.openPermissions()
$scope.closeSetting()
}
}
}

View file

@ -13,8 +13,15 @@ limitations under the License.
-->
<!-- Here the controller <NotebookCtrl> is not needed because explicitly set in the app.js (route) -->
<div id="actionbar" ng-include src="'app/notebook/notebook-actionBar.html'"></div>
<div id="note-revisions-comparator-modal-container" ng-include src="'app/notebook/revisions-comparator.html'"></div>
<div id="content" class="notebookContent">
<!-- revisions comparator-->
<div ng-if="showRevisionsComparator" class="revisions-comparator">
<div>
<h4>Revisions comparator</h4>
</div>
<hr />
<revisions-comparator note-revisions="noteRevisions"></revisions-comparator>
</div>
<!-- settings -->
<div ng-if="showSetting" class="setting">
<div>

View file

@ -270,117 +270,6 @@ table.table-shortcut {
font-size: 10px !important;
}
.revisions-comparator-modal-dialog {
width: 80%;
margin: 30px auto;
height: 80%;
}
.revisions-comparator-modal-dialog .modal-content {
height: 100%;
}
.revisions-comparator-modal-header {
min-height: 16.428571429px;
padding: 15px;
border-bottom: 1px solid #9cb4c5;
background-color: #3071a9;
border: 2px solid #3071a9;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.revisions-comparator-modal-header .close {
color: #cfcfcf;
opacity: 1;
}
.revisions-comparator-modal-title {
color: white;
margin-top: 2px;
margin-bottom: 2px;
}
.revisions-comparator-code-panel {
display: inline-block;
width: 50%;
float: left;
height: 300px;
overflow-y: auto;
max-height: 300px
}
.revisions-comparator-code-panel-title {
width: 50%;
float: left;
font-size: 14px;
padding: 5px;
background-color: #f5f5f5;
}
.revisions-comparator-bar {
margin: 10px auto;
width: 400px;
}
.revisions-comparator-status {
font-size: 12px;
padding-left: 10px;
}
#diffPanel {
height: calc(100% - 60px);
}
#diffPanel .panel-group {
height: inherit;
overflow: auto;
}
.revision-name-for-compare {
cursor: default;
overflow: hidden;
display: inline-block;
max-width: 100px;
width: 100px;
padding: 1px 10px;
}
.revisions-comparator-caret {
margin: 0 0 10px 6px;
}
.revisions-comparator-link, .revisions-comparator-link:hover,
.revisions-comparator-link:visited, .revisions-comparator-link:focus {
text-decoration: none;
color: #000;
}
.revisions-comparator-forst-string {
display: block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: 12px;
color: grey;
}
.color-green {
color: green;
}
.color-red {
color: red;
}
.color-black {
color: black;
}
.color-orange {
color: orange;
}
/*
Paragraph Title
*/

View file

@ -1,126 +0,0 @@
<!--
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<div class="modal fade" id="revisionsComparatorModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"
modalvisible previsiblecallback="preVisibleRevisionsComparator">
<div class="revisions-comparator-modal-dialog">
<div class="modal-content">
<div class="revisions-comparator-modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
<h4 class="revisions-comparator-modal-title" id="myModalLabel">Revisions comparator</h4>
</div>
<div class="revisions-comparator-bar">
<div class="btn-group">
<button type="button" ng-if="noteRevisions.length > 0"
class="btn btn-sm btn-default dropdown-toggle"
data-toggle="dropdown" id="firstRevisionDropdown" title="{{currentFirstRevisionForCompare}}">
<div class="revision-name-for-compare">{{currentFirstRevisionForCompare}}</div>
<span class="caret revisions-comparator-caret"></span>
</button>
<ul class="dropdown-menu pull-right" aria-labelledby="firstRevisionDropdown">
<li></li>
<li ng-repeat="revision in noteRevisions | orderBy:'time':true" class="revision">
<a style="cursor:pointer" ng-click="getNoteRevisionForReview(revision, 'first')">
<span style="display: block;">
<strong>{{revision.message}}</strong>
</span>
<span class="revisionDate">
<em>{{formatRevisionDate(revision.time)}}</em>
</span>
</a>
</li>
</ul>
</div>
<span>compare with</span>
<div class="btn-group">
<button type="button" ng-if="noteRevisions.length > 0"
class="btn btn-sm btn-default dropdown-toggle"
ng-disabled="firstNoteRevisionForCompare === null"
data-toggle="dropdown" id="secondRevisionDropdown" title="{{currentSecondRevisionForCompare}}">
<div class="revision-name-for-compare">{{currentSecondRevisionForCompare}}</div>
<span class="caret revisions-comparator-caret"></span>
</button>
<ul class="dropdown-menu pull-right" aria-labelledby="secondRevisionDropdown">
<li ng-repeat="revision in noteRevisions | orderBy:'time':true" class="revision">
<a style="cursor:pointer" ng-click="getNoteRevisionForReview(revision, 'second')">
<span style="display: block;">
<strong>{{revision.message}}</strong>
</span>
<span class="revisionDate">
<em>{{formatRevisionDate(revision.time)}}</em>
</span>
</a>
</li>
</ul>
</div>
</div>
<div id="diffPanel">
<div class="panel-group">
<div class="panel" data-ng-repeat="p in (mergeNoteRevisionsForCompare ? mergeNoteRevisionsForCompare.added : [])">
<div class="panel-heading">
<a class="revisions-comparator-link" data-toggle="collapse" data-parent="#diffPanel" href="#{{p.paragraph.id}}">
<h4 class="panel-title">
{{p.paragraph.id}}<strong style="padding: 5px;" ng-if="p.paragraph.title">({{p.paragraph.title}})</strong>
<i class="revisions-comparator-status color-green">added</i>
<i class="revisions-comparator-forst-string">{{p.firstString}}</i>
</h4>
</a>
</div>
<div id="{{p.paragraph.id}}" class="panel-collapse collapse">
<span class="revisions-comparator-code-panel-title">Revision: <strong>{{currentFirstRevisionForCompare}}</strong></span>
<span class="revisions-comparator-code-panel-title">Revision: <strong>{{currentSecondRevisionForCompare}}</strong></span>
<pre class="revisions-comparator-code-panel"></pre>
<pre class="revisions-comparator-code-panel color-green">{{p.paragraph.text}}</pre>
</div>
</div>
<div class="panel" data-ng-repeat="p in (mergeNoteRevisionsForCompare ? mergeNoteRevisionsForCompare.deleted : [])">
<div class="panel-heading">
<a class="revisions-comparator-link" data-toggle="collapse" data-parent="#diffPanel" href="#{{p.paragraph.id}}">
<h4 class="panel-title">
{{p.paragraph.id}} <strong style="padding: 5px;" ng-if="p.paragraph.title">({{p.paragraph.title}})</strong>
<i class="revisions-comparator-status color-red">deleted</i>
<i class="revisions-comparator-forst-string">{{p.firstString}}</i>
</h4>
</a>
</div>
<div id="{{p.paragraph.id}}" class="panel-collapse collapse">
<span class="revisions-comparator-code-panel-title">Revision: <strong>{{currentFirstRevisionForCompare}}</strong></span>
<span class="revisions-comparator-code-panel-title">Revision: <strong>{{currentSecondRevisionForCompare}}</strong></span>
<pre class="revisions-comparator-code-panel color-red">{{p.paragraph.text}}</pre>
<pre class="revisions-comparator-code-panel"></pre>
</div>
</div>
<div class="panel" data-ng-repeat="p in (mergeNoteRevisionsForCompare ? mergeNoteRevisionsForCompare.compared : [])">
<div class="panel-heading">
<a class="revisions-comparator-link" data-toggle="collapse" data-parent="#diffPanel" href="#{{p.paragraph.id}}">
<h4 class="panel-title">
{{p.paragraph.id}} <strong style="padding: 5px;" ng-if="p.paragraph.title">({{p.paragraph.title}})</strong>
<i class="revisions-comparator-status" ng-show="p.identical">contents are identical</i>
<i class="revisions-comparator-status color-orange" ng-show="!(p.identical)">there are differences</i>
<i class="revisions-comparator-forst-string">{{p.firstString}}</i>
</h4>
</a>
</div>
<div id="{{p.paragraph.id}}" class="panel-collapse collapse">
<span class="revisions-comparator-code-panel-title">Revision: <strong>{{currentFirstRevisionForCompare}}</strong></span>
<span class="revisions-comparator-code-panel-title">Diff with revision: <strong>{{currentSecondRevisionForCompare}}</strong></span>
<pre class="revisions-comparator-code-panel">{{p.paragraph.text}}</pre>
<pre class="revisions-comparator-code-panel" ng-bind-html="p.diff"></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

View file

@ -0,0 +1,159 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import revisionsComparatorTemplate from './revisions-comparator.html'
import './revisions-comparator.css'
import moment from 'moment'
function RevisionsComparatorController($scope, websocketMsgSrv, $routeParams) {
'ngInject'
$scope.firstNoteRevisionForCompare = null
$scope.secondNoteRevisionForCompare = null
$scope.mergeNoteRevisionsForCompare = null
$scope.currentFirstRevisionForCompare = 'Choose...'
$scope.currentSecondRevisionForCompare = 'Choose...'
$scope.getNoteRevisionForReview = function(revision, position) {
if (position) {
if (position === 'first') {
$scope.currentFirstRevisionForCompare = revision.message
} else {
$scope.currentSecondRevisionForCompare = revision.message
}
websocketMsgSrv.getNoteByRevisionForCompare($routeParams.noteId, revision.id, position)
}
}
// compare revisions
$scope.compareRevisions = function() {
if ($scope.firstNoteRevisionForCompare && $scope.secondNoteRevisionForCompare) {
let paragraphs1 = $scope.firstNoteRevisionForCompare.note.paragraphs
let paragraphs2 = $scope.secondNoteRevisionForCompare.note.paragraphs
let added = 'added'
let deleted = 'deleted'
let compared = 'compared'
let merge = []
for (let p1 of paragraphs1) {
let p2 = null
for (let p of paragraphs2) {
if (p1.id === p.id) {
p2 = p
break
}
}
if (p2 === null) {
merge.push({paragraph: p1, firstString: (p1.text || '').split('\n')[0], type: deleted})
} else {
let colorClass = ''
let span = null
let text1 = p1.text || ''
let text2 = p2.text || ''
let diff = window.JsDiff.diffLines(text1, text2)
let diffHtml = document.createDocumentFragment()
let identical = true
let identicalClass = 'color-black'
diff.forEach(function (part) {
colorClass = part.added ? 'color-green' : part.removed ? 'color-red' : identicalClass
span = document.createElement('span')
span.className = colorClass
if (identical && colorClass !== identicalClass) {
identical = false
}
span.appendChild(document.createTextNode(part.value))
diffHtml.appendChild(span)
})
let pre = document.createElement('pre')
pre.appendChild(diffHtml)
merge.push(
{
paragraph: p1,
diff: pre.innerHTML,
identical: identical,
firstString: (p1.text || '').split('\n')[0],
type: compared
})
}
}
for (let p2 of paragraphs2) {
let p1 = null
for (let p of paragraphs1) {
if (p2.id === p.id) {
p1 = p
break
}
}
if (p1 === null) {
merge.push({paragraph: p2, firstString: (p2.text || '').split('\n')[0], type: added})
}
}
merge.sort(function(a, b) {
if (a.type === added) {
return -1
}
if (a.type === compared) {
return 1
}
if (a.type === deleted) {
if (b.type === compared) {
return -1
} else {
return 1
}
}
})
$scope.mergeNoteRevisionsForCompare = merge
}
}
$scope.$on('noteRevisionForCompare', function (event, data) {
console.debug('received note revision for compare %o', data)
if (data.note && data.position) {
if (data.position === 'first') {
$scope.firstNoteRevisionForCompare = data
} else {
$scope.secondNoteRevisionForCompare = data
}
if ($scope.firstNoteRevisionForCompare !== null && $scope.secondNoteRevisionForCompare !== null &&
$scope.firstNoteRevisionForCompare.revisionId !== $scope.secondNoteRevisionForCompare.revisionId) {
$scope.compareRevisions()
}
}
})
$scope.formatRevisionDate = function(date) {
return moment.unix(date).format('MMMM Do YYYY, h:mm a')
}
}
export const RevisionsComparatorComponent = {
template: revisionsComparatorTemplate,
controller: RevisionsComparatorController,
bindings: {
noteRevisions: '<'
}
}
export const RevisionsComparatorModule = angular
.module('zeppelinWebApp')
.component('revisionsComparator', RevisionsComparatorComponent)
.name

View file

@ -0,0 +1,115 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.revisions-comparator {
background: white;
padding: 10px 15px 15px 15px;
margin-left: -10px;
margin-right: -10px;
font-family: 'Roboto', sans-serif;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
border-bottom: 1px solid #E5E5E5;
}
.revisions-comparator-panel-heading {
padding: 10px 0px;
}
.revisions-comparator-code-panel {
display: inline-block;
width: 50%;
float: left;
height: 300px;
overflow-y: auto;
max-height: 300px
}
.revisions-comparator-code-panel-title {
width: 50%;
float: left;
font-size: 14px;
padding: 5px;
background-color: #f5f5f5;
}
.revisions-comparator-bar {
width: 400px;
padding-bottom: 10px;
}
.revisions-comparator-status {
font-size: 12px;
padding-left: 10px;
}
#diffPanel {
height: 100%;
}
#diffPanel .panel-group {
height: inherit;
overflow: auto;
}
.revision-name-for-compare {
cursor: default;
overflow: hidden;
vertical-align: bottom;
display: inline-block;
max-width: 100px;
padding: 1px 5px;
}
.revisions-comparator-caret {
padding-bottom: 5px;
}
.revisions-comparator-link, .revisions-comparator-link:hover,
.revisions-comparator-link:visited, .revisions-comparator-link:focus {
text-decoration: none;
outline: none;
color: #000;
}
.revisions-comparator-first-string {
display: block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: 12px;
color: grey;
}
.revisions-comparator-dropdown {
padding: 5px;
font-size: 12px;
border-radius: 3px;
}
.color-green {
color: green;
}
.color-red {
color: red;
}
.color-black {
color: black;
}
.color-orange {
color: orange;
}

View file

@ -0,0 +1,87 @@
<!--
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<div class="revisions-comparator-bar">
<div class="btn-group">
<button type="button" ng-if="$ctrl.noteRevisions.length > 0"
class="btn btn-default revisions-comparator-dropdown dropdown-toggle"
data-toggle="dropdown" id="firstRevisionDropdown" title="{{currentFirstRevisionForCompare}}">
<div class="revision-name-for-compare">{{currentFirstRevisionForCompare}}</div>
<span class="caret revisions-comparator-caret"></span>
</button>
<ul class="dropdown-menu dropdown-menu-left" aria-labelledby="firstRevisionDropdown">
<li></li>
<li ng-repeat="revision in $ctrl.noteRevisions | orderBy:'time':true" class="revision">
<a style="cursor:pointer" ng-click="getNoteRevisionForReview(revision, 'first')">
<span style="display: block;">
<strong>{{revision.message}}</strong>
</span>
<span class="revisionDate">
<em>{{formatRevisionDate(revision.time)}}</em>
</span>
</a>
</li>
</ul>
</div>
<span>compare with</span>
<div class="btn-group">
<button type="button" ng-if="$ctrl.noteRevisions.length > 0"
class="btn btn-default revisions-comparator-dropdown dropdown-toggle"
ng-disabled="firstNoteRevisionForCompare === null"
data-toggle="dropdown" id="secondRevisionDropdown" title="{{currentSecondRevisionForCompare}}">
<div class="revision-name-for-compare">{{currentSecondRevisionForCompare}}</div>
<span class="caret revisions-comparator-caret"></span>
</button>
<ul class="dropdown-menu dropdown-menu-left" aria-labelledby="secondRevisionDropdown">
<li ng-repeat="revision in $ctrl.noteRevisions | orderBy:'time':true" class="revision">
<a style="cursor:pointer" ng-click="getNoteRevisionForReview(revision, 'second')">
<span style="display: block;">
<strong>{{revision.message}}</strong>
</span>
<span class="revisionDate">
<em>{{formatRevisionDate(revision.time)}}</em>
</span>
</a>
</li>
</ul>
</div>
</div>
<div id="diffPanel">
<div class="panel-group">
<div class="panel" data-ng-repeat="p in mergeNoteRevisionsForCompare">
<div class="revisions-comparator-panel-heading">
<a class="revisions-comparator-link" data-toggle="collapse" data-parent="#diffPanel" href="#{{p.paragraph.id}}">
<h4 class="panel-title">
{{p.paragraph.id}}<strong style="padding: 5px;" ng-if="p.paragraph.title">({{p.paragraph.title}})</strong>
<i ng-if="p.type === 'added'" class="revisions-comparator-status color-green">added</i>
<i ng-if="p.type === 'deleted'" class="revisions-comparator-status color-red">deleted</i>
<i ng-if="p.type === 'compared' && !(p.identical)" class="revisions-comparator-status color-orange">there are differences</i>
<i ng-if="p.type === 'compared' && p.identical" class="revisions-comparator-status">contents are identical</i>
<i class="revisions-comparator-first-string">{{p.firstString}}</i>
</h4>
</a>
</div>
<div id="{{p.paragraph.id}}" class="panel-collapse collapse">
<span class="revisions-comparator-code-panel-title">Revision: <strong>{{currentFirstRevisionForCompare}}</strong></span>
<span class="revisions-comparator-code-panel-title">Revision: <strong>{{currentSecondRevisionForCompare}}</strong></span>
<pre ng-if="p.type === 'added'" class="revisions-comparator-code-panel"></pre>
<pre ng-if="p.type === 'added'" class="revisions-comparator-code-panel color-green">{{p.paragraph.text}}</pre>
<pre ng-if="p.type === 'deleted'" class="revisions-comparator-code-panel color-red">{{p.paragraph.text}}</pre>
<pre ng-if="p.type === 'deleted'" class="revisions-comparator-code-panel"></pre>
<pre ng-if="p.type === 'compared'" class="revisions-comparator-code-panel">{{p.paragraph.text}}</pre>
<pre ng-if="p.type === 'compared'" class="revisions-comparator-code-panel" ng-bind-html="p.diff"></pre>
</div>
</div>
</div>
</div>

View file

@ -42,6 +42,7 @@ import './app/interpreter/interpreter-item.directive.js'
import './app/interpreter/widget/number-widget.directive.js'
import './app/credential/credential.controller.js'
import './app/configuration/configuration.controller.js'
import './app/notebook/revisions-comparator/revisions-comparator.component.js'
import './app/notebook/paragraph/paragraph.controller.js'
import './app/notebook/paragraph/clipboard.controller.js'
import './app/notebook/paragraph/resizable.directive.js'