Implement selection of patch set in diff view
Feature: Issue 3645 Change-Id: Ic7f408069abce6005392a4a222cc2a1fd4f7573b
This commit is contained in:
parent
0761fd5ce4
commit
8061a65720
@ -55,6 +55,7 @@ limitations under the License.
|
|||||||
change-num="[[_changeNum]]"
|
change-num="[[_changeNum]]"
|
||||||
patch-range="[[_patchRange]]"
|
patch-range="[[_patchRange]]"
|
||||||
path="[[_path]]"
|
path="[[_path]]"
|
||||||
|
available-patches="[[_computeAvailablePatches(_change.revisions)]]"
|
||||||
on-render="_handleDiffRender">
|
on-render="_handleDiffRender">
|
||||||
</gr-diff>
|
</gr-diff>
|
||||||
</template>
|
</template>
|
||||||
@ -156,6 +157,14 @@ limitations under the License.
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_computeAvailablePatches: function(revisions) {
|
||||||
|
var patchNums = [];
|
||||||
|
for (var rev in revisions) {
|
||||||
|
patchNums.push(revisions[rev]._number);
|
||||||
|
}
|
||||||
|
return patchNums.sort(function(a, b) { return a - b; });
|
||||||
|
},
|
||||||
|
|
||||||
_computeChangePath: function(changeNum) {
|
_computeChangePath: function(changeNum) {
|
||||||
return '/c/' + changeNum;
|
return '/c/' + changeNum;
|
||||||
},
|
},
|
||||||
|
@ -17,12 +17,16 @@ limitations under the License.
|
|||||||
<link rel="import" href="../bower_components/polymer/polymer.html">
|
<link rel="import" href="../bower_components/polymer/polymer.html">
|
||||||
<link rel="import" href="gr-ajax.html">
|
<link rel="import" href="gr-ajax.html">
|
||||||
<link rel="import" href="gr-diff-side.html">
|
<link rel="import" href="gr-diff-side.html">
|
||||||
|
<link rel="import" href="gr-patch-range-select.html">
|
||||||
<link rel="import" href="gr-request.html">
|
<link rel="import" href="gr-request.html">
|
||||||
|
|
||||||
<dom-module id="gr-diff">
|
<dom-module id="gr-diff">
|
||||||
<template>
|
<template>
|
||||||
<style>
|
<style>
|
||||||
:host {
|
gr-patch-range-select {
|
||||||
|
margin: 0 var(--default-horizontal-margin) .75em;
|
||||||
|
}
|
||||||
|
.diffContainer {
|
||||||
border-bottom: 1px solid #eee;
|
border-bottom: 1px solid #eee;
|
||||||
border-top: 1px solid #eee;
|
border-top: 1px solid #eee;
|
||||||
font-family: 'Source Code Pro', monospace;
|
font-family: 'Source Code Pro', monospace;
|
||||||
@ -51,14 +55,22 @@ limitations under the License.
|
|||||||
url="[[_computeDraftsPath(changeNum, patchRange.basePatchNum)]]"></gr-ajax>
|
url="[[_computeDraftsPath(changeNum, patchRange.basePatchNum)]]"></gr-ajax>
|
||||||
<gr-ajax id="draftsXHR"
|
<gr-ajax id="draftsXHR"
|
||||||
url="[[_computeDraftsPath(changeNum, patchRange.patchNum)]]"></gr-ajax>
|
url="[[_computeDraftsPath(changeNum, patchRange.patchNum)]]"></gr-ajax>
|
||||||
<gr-diff-side id="leftDiff"
|
|
||||||
content="{{_diff.leftSide}}"
|
<gr-patch-range-select
|
||||||
width="[[sideWidth]]"
|
path="[[path]]"
|
||||||
can-comment="[[_loggedIn]]"></gr-diff-side>
|
change-num="[[changeNum]]"
|
||||||
<gr-diff-side id="rightDiff"
|
patch-range="[[patchRange]]"
|
||||||
content="{{_diff.rightSide}}"
|
available-patches="[[availablePatches]]"></gr-patch-range-select>
|
||||||
width="[[sideWidth]]"
|
<div class="diffContainer">
|
||||||
can-comment="[[_loggedIn]]"></gr-diff-side>
|
<gr-diff-side id="leftDiff"
|
||||||
|
content="{{_diff.leftSide}}"
|
||||||
|
width="[[sideWidth]]"
|
||||||
|
can-comment="[[_loggedIn]]"></gr-diff-side>
|
||||||
|
<gr-diff-side id="rightDiff"
|
||||||
|
content="{{_diff.rightSide}}"
|
||||||
|
width="[[sideWidth]]"
|
||||||
|
can-comment="[[_loggedIn]]"></gr-diff-side>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
(function() {
|
(function() {
|
||||||
@ -78,6 +90,7 @@ limitations under the License.
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: false,
|
value: false,
|
||||||
},
|
},
|
||||||
|
availablePatches: Array,
|
||||||
changeNum: String,
|
changeNum: String,
|
||||||
/*
|
/*
|
||||||
* A single object to encompass basePatchNum and patchNum is used
|
* A single object to encompass basePatchNum and patchNum is used
|
||||||
@ -190,7 +203,7 @@ limitations under the License.
|
|||||||
}.bind(this)));
|
}.bind(this)));
|
||||||
|
|
||||||
if (basePatchNum != 'PARENT') {
|
if (basePatchNum != 'PARENT') {
|
||||||
draftsPromise = this.$baseDraftsXHR.generateRequest().completes;
|
draftsPromise = this.$.baseDraftsXHR.generateRequest().completes;
|
||||||
promises.push(draftsPromise.then(function(req) {
|
promises.push(draftsPromise.then(function(req) {
|
||||||
this._baseDrafts =
|
this._baseDrafts =
|
||||||
(req.response[this.path] || []).filter(withoutParent);
|
(req.response[this.path] || []).filter(withoutParent);
|
||||||
|
95
polygerrit-ui/app/elements/gr-patch-range-select.html
Normal file
95
polygerrit-ui/app/elements/gr-patch-range-select.html
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2015 The Android Open Source Project
|
||||||
|
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<link rel="import" href="../bower_components/polymer/polymer.html">
|
||||||
|
|
||||||
|
<dom-module id="gr-patch-range-select">
|
||||||
|
<template>
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.patchRange {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
Patch set:
|
||||||
|
<span class="patchRange">
|
||||||
|
<select id="leftPatchSelect" on-change="_handlePatchChange">
|
||||||
|
<option value="PARENT"
|
||||||
|
selected$="[[_computeLeftSelected('PARENT', patchRange)]]">Base</option>
|
||||||
|
<template is="dom-repeat" items="{{availablePatches}}" as="patchNum">
|
||||||
|
<option value$="[[patchNum]]"
|
||||||
|
selected$="[[_computeLeftSelected(patchNum, patchRange)]]"
|
||||||
|
disabled$="[[_computeLeftDisabled(patchNum, patchRange)]]">[[patchNum]]</option>
|
||||||
|
</template>
|
||||||
|
</select>
|
||||||
|
</span>
|
||||||
|
→
|
||||||
|
<span class="patchRange">
|
||||||
|
<select id="rightPatchSelect" on-change="_handlePatchChange">
|
||||||
|
<template is="dom-repeat" items="{{availablePatches}}" as="patchNum">
|
||||||
|
<option value$="[[patchNum]]"
|
||||||
|
selected$="[[_computeRightSelected(patchNum, patchRange)]]"
|
||||||
|
disabled$="[[_computeRightDisabled(patchNum, patchRange)]]">[[patchNum]]</option>
|
||||||
|
</template>
|
||||||
|
</select>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
Polymer({
|
||||||
|
is: 'gr-patch-range-select',
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
availablePatches: Array,
|
||||||
|
changeNum: String,
|
||||||
|
patchRange: Object,
|
||||||
|
path: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
_handlePatchChange: function(e) {
|
||||||
|
var leftPatch = this.$.leftPatchSelect.value;
|
||||||
|
var rightPatch = this.$.rightPatchSelect.value;
|
||||||
|
var rangeStr = rightPatch;
|
||||||
|
if (leftPatch != 'PARENT') {
|
||||||
|
rangeStr = leftPatch + '..' + rangeStr;
|
||||||
|
}
|
||||||
|
page.show('/c/' + this.changeNum + '/' + rangeStr + '/' + this.path);
|
||||||
|
},
|
||||||
|
|
||||||
|
_computeLeftSelected: function(patchNum, patchRange) {
|
||||||
|
return patchNum == patchRange.basePatchNum;
|
||||||
|
},
|
||||||
|
|
||||||
|
_computeRightSelected: function(patchNum, patchRange) {
|
||||||
|
return patchNum == patchRange.patchNum;
|
||||||
|
},
|
||||||
|
|
||||||
|
_computeLeftDisabled: function(patchNum, patchRange) {
|
||||||
|
return parseInt(patchNum, 10) >= parseInt(patchRange.patchNum, 10);
|
||||||
|
},
|
||||||
|
|
||||||
|
_computeRightDisabled: function(patchNum, patchRange) {
|
||||||
|
if (patchRange.basePatchNum == 'PARENT') { return false; }
|
||||||
|
return parseInt(patchNum, 10) <= parseInt(patchRange.basePatchNum, 10);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</dom-module>
|
93
polygerrit-ui/app/test/gr-patch-range-select-test.html
Normal file
93
polygerrit-ui/app/test/gr-patch-range-select-test.html
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2015 The Android Open Source Project
|
||||||
|
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
|
||||||
|
<title>gr-patch-range-select</title>
|
||||||
|
|
||||||
|
<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
|
||||||
|
<script src="../../bower_components/web-component-tester/browser.js"></script>
|
||||||
|
<script src="../../bower_components/page/page.js"></script>
|
||||||
|
|
||||||
|
<link rel="import" href="../../bower_components/iron-test-helpers/iron-test-helpers.html">
|
||||||
|
<link rel="import" href="../elements/gr-patch-range-select.html">
|
||||||
|
|
||||||
|
<test-fixture id="basic">
|
||||||
|
<template>
|
||||||
|
<gr-patch-range-select auto></gr-patch-range-select>
|
||||||
|
</template>
|
||||||
|
</test-fixture>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
suite('gr-patch-range-select tests', function() {
|
||||||
|
var element;
|
||||||
|
|
||||||
|
setup(function() {
|
||||||
|
element = fixture('basic');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('enabled/disabled options', function() {
|
||||||
|
var patchRange = {
|
||||||
|
basePatchNum: 'PARENT',
|
||||||
|
patchNum: '3',
|
||||||
|
};
|
||||||
|
['1', '2', '3'].forEach(function(patchNum) {
|
||||||
|
assert.isFalse(element._computeRightDisabled(patchNum, patchRange));
|
||||||
|
});
|
||||||
|
['PARENT', '1', '2'].forEach(function(patchNum) {
|
||||||
|
assert.isFalse(element._computeLeftDisabled(patchNum, patchRange));
|
||||||
|
});
|
||||||
|
assert.isTrue(element._computeLeftDisabled('3', patchRange));
|
||||||
|
|
||||||
|
patchRange.basePatchNum = '2';
|
||||||
|
assert.isTrue(element._computeLeftDisabled('3', patchRange));
|
||||||
|
assert.isTrue(element._computeRightDisabled('1', patchRange));
|
||||||
|
assert.isTrue(element._computeRightDisabled('2', patchRange));
|
||||||
|
assert.isFalse(element._computeRightDisabled('3', patchRange));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('navigation', function(done) {
|
||||||
|
var showStub = sinon.stub(page, 'show');
|
||||||
|
var leftSelectEl = element.$.leftPatchSelect;
|
||||||
|
var rightSelectEl = element.$.rightPatchSelect;
|
||||||
|
element.changeNum = '42';
|
||||||
|
element.path = 'path/to/file.txt';
|
||||||
|
element.availablePatches = ['1', '2', '3'];
|
||||||
|
flushAsynchronousOperations();
|
||||||
|
|
||||||
|
var numEvents = 0;
|
||||||
|
leftSelectEl.addEventListener('change', function(e) {
|
||||||
|
numEvents++;
|
||||||
|
if (numEvents == 1) {
|
||||||
|
assert(showStub.lastCall.calledWithExactly(
|
||||||
|
'/c/42/3/path/to/file.txt'),
|
||||||
|
'Should navigate to /c/42/3/path/to/file.txt');
|
||||||
|
leftSelectEl.value = '1';
|
||||||
|
element.fire('change', {}, {node: leftSelectEl});
|
||||||
|
} else if (numEvents == 2) {
|
||||||
|
assert(showStub.lastCall.calledWithExactly(
|
||||||
|
'/c/42/1..3/path/to/file.txt'),
|
||||||
|
'Should navigate to /c/42/1..3/path/to/file.txt');
|
||||||
|
showStub.restore();
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
leftSelectEl.value = 'PARENT';
|
||||||
|
rightSelectEl.value = '3';
|
||||||
|
element.fire('change', {}, {node: leftSelectEl});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
@ -34,6 +34,7 @@ limitations under the License.
|
|||||||
'gr-diff-test.html',
|
'gr-diff-test.html',
|
||||||
'gr-diff-view-test.html',
|
'gr-diff-view-test.html',
|
||||||
'gr-file-list-test.html',
|
'gr-file-list-test.html',
|
||||||
|
'gr-patch-range-select-test.html',
|
||||||
'gr-reply-dropdown-test.html',
|
'gr-reply-dropdown-test.html',
|
||||||
'gr-search-bar-test.html',
|
'gr-search-bar-test.html',
|
||||||
].forEach(function(file) {
|
].forEach(function(file) {
|
||||||
|
Loading…
Reference in New Issue
Block a user