mirror of
https://github.com/apache/zeppelin
synced 2026-05-24 09:38:26 +00:00
[ZEPPELIN-2813] refactoring
This commit is contained in:
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 |
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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">×</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>
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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>
|
||||
|
|
@ -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'
|
||||
|
|
|
|||
Loading…
Reference in a new issue