Upload help dialog

Provide a dialog with explanation and copyable commands for how to
update an existing change from local modifications. The button to show
the dialog only appears when a user views their own unmerged change.

Feature: Issue 9532
Change-Id: I841197468f9663d75db9b0e5d20b11943959f5d7
This commit is contained in:
Wyatt Allen
2018-08-03 10:17:35 -07:00
parent 622291b5c8
commit 4299ccc65d
8 changed files with 234 additions and 6 deletions

View File

@@ -51,6 +51,7 @@ limitations under the License.
<link rel="import" href="../gr-related-changes-list/gr-related-changes-list.html">
<link rel="import" href="../gr-reply-dialog/gr-reply-dialog.html">
<link rel="import" href="../gr-thread-list/gr-thread-list.html">
<link rel="import" href="../gr-upload-help-dialog/gr-upload-help-dialog.html">
<dom-module id="gr-change-view">
<template>
@@ -243,6 +244,9 @@ limitations under the License.
#includedInOverlay {
width: 65em;
}
#uploadHelpOverlay {
width: 50em;
}
@media screen and (min-width: 80em) {
.commitMessage {
max-width: var(--commit-message-max-width, 100ch);
@@ -527,6 +531,7 @@ limitations under the License.
files-expanded="[[_filesExpanded]]"
on-open-diff-prefs="_handleOpenDiffPrefs"
on-open-download-dialog="_handleOpenDownloadDialog"
on-open-upload-help-dialog="_handleOpenUploadHelpDialog"
on-open-included-in-dialog="_handleOpenIncludedInDialog"
on-expand-diffs="_expandAllDiffs"
on-collapse-diffs="_collapseAllDiffs">
@@ -599,6 +604,10 @@ limitations under the License.
config="[[_serverConfig.download]]"
on-close="_handleDownloadDialogClose"></gr-download-dialog>
</gr-overlay>
<gr-overlay id="uploadHelpOverlay" with-backdrop>
<gr-upload-help-dialog
on-close="_handleCloseUploadHelpDialog"></gr-upload-help-dialog>
</gr-overlay>
<gr-overlay id="includedInOverlay" with-backdrop>
<gr-included-in-dialog
id="includedInDialog"

View File

@@ -536,6 +536,14 @@
this.$.downloadOverlay.close();
},
_handleOpenUploadHelpDialog(e) {
this.$.uploadHelpOverlay.open();
},
_handleCloseUploadHelpDialog(e) {
this.$.uploadHelpOverlay.close();
},
_handleMessageReply(e) {
const msg = e.detail.message.message;
const quoteStr = msg.split('\n').map(

View File

@@ -78,13 +78,13 @@ limitations under the License.
align-items: center;
display: flex;
}
.downloadContainer {
margin-right: 16px;
}
.downloadContainer,
.uploadContainer,
.includedInContainer {
margin-right: 16px;
}
.includedInContainer.hide {
.includedInContainer.hide,
.uploadContainer.hide {
display: none;
}
.rightControls {
@@ -211,6 +211,11 @@ limitations under the License.
change="[[change]]"></gr-edit-controls>
<span class="separator"></span>
</span>
<span class$="[[_computeUploadHelpContainerClass(change, account)]]">
<gr-button link
class="upload"
on-tap="_handleUploadTap">Update Change</gr-button>
</span>
<span class="downloadContainer desktop">
<gr-button link
class="download"

View File

@@ -19,10 +19,35 @@
// Maximum length for patch set descriptions.
const PATCH_DESC_MAX_LENGTH = 500;
const MERGED_STATUS = 'MERGED';
Polymer({
is: 'gr-file-list-header',
/**
* @event expand-diffs
*/
/**
* @event collapse-diffs
*/
/**
* @event open-diff-prefs
*/
/**
* @event open-included-in-dialog
*/
/**
* @event open-download-dialog
*/
/**
* @event open-upload-help-dialog
*/
properties: {
account: Object,
allPatchSets: Array,
@@ -189,7 +214,8 @@
_handleDownloadTap(e) {
e.preventDefault();
this.fire('open-download-dialog');
this.dispatchEvent(
new CustomEvent('open-download-dialog', {bubbles: false}));
},
_computeEditModeClass(editMode) {
@@ -209,7 +235,23 @@
},
_hideIncludedIn(change) {
return change && change.status === 'MERGED' ? '' : 'hide';
return change && change.status === MERGED_STATUS ? '' : 'hide';
},
_handleUploadTap(e) {
e.preventDefault();
this.dispatchEvent(
new CustomEvent('open-upload-help-dialog', {bubbles: false}));
},
_computeUploadHelpContainerClass(change, account) {
const changeIsMerged = change && change.status === MERGED_STATUS;
const ownerId = change && change.owner && change.owner._account_id ?
change.owner._account_id : null;
const userId = account && account._account_id;
const userIsOwner = ownerId && userId && ownerId === userId;
const hideContainer = !userIsOwner || changeIsMerged;
return 'uploadContainer desktop' + (hideContainer ? ' hide' : '');
},
});
})();

View File

@@ -298,6 +298,17 @@ limitations under the License.
flushAsynchronousOperations();
assert.isFalse(isVisible(element.$.editControls.parentElement));
});
test('_computeUploadHelpContainerClass', () => {
// Only show the upload helper button when an unmerged change is viewed
// by its owner.
const accountA = {_account_id: 1};
const accountB = {_account_id: 2};
assert.notInclude(element._computeUploadHelpContainerClass(
{owner: accountA}, accountA), 'hide');
assert.include(element._computeUploadHelpContainerClass(
{owner: accountA}, accountB), 'hide');
});
});
});
</script>

View File

@@ -0,0 +1,102 @@
<!--
@license
Copyright (C) 2018 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">
<link rel="import" href="../../shared/gr-dialog/gr-dialog.html">
<link rel="import" href="../../../styles/shared-styles.html">
<dom-module id="gr-upload-help-dialog">
<template>
<style include="shared-styles">
:host {
background-color: var(--dialog-background-color);
display: block;
}
.main {
width: 100%;
}
ol {
margin-left: 1em;
list-style: decimal;
}
p,
.commandContainer {
margin-bottom: .75em;
}
.commandContainer {
background: #f5f5f5;
padding: .5em .5em .5em 2.5em;
position: relative;
width: 100%;
}
.commandContainer:before {
background: #ebebeb;
bottom: 0;
content: '$';
display: block;
left: 0;
padding: .8em;
position: absolute;
top: 0;
width: 2em;
}
.commandContainer gr-copy-clipboard {
--text-container-style: {
border: none;
}
}
</style>
<gr-dialog
confirm-label="Done"
cancel-label=""
on-confirm="_handleCloseTap">
<div class="header" slot="header">How to update this change:</div>
<div class="main" slot="main">
<ol>
<li>
<p>
Checkout this change locally and make your desired modifications to
the files.
</p>
</li>
<li>
<p>
Update the local commit with your modifications using the following
command.
</p>
<div class="commandContainer">
<gr-copy-clipboard text="[[_commitCommand]]"></gr-copy-clipboard>
</div>
<p>
Leave the "Change-Id:" line of the commit message as is.
</p>
</li>
<li>
<p>Push the updated commit to Gerrit.</p>
<div class="commandContainer">
<gr-copy-clipboard text="[[_pushCommand]]"></gr-copy-clipboard>
</div>
</li>
<li>
<p>Refresh this page to view the the update.</p>
</li>
</ol>
</div>
</gr-dialog>
</template>
<script src="gr-upload-help-dialog.js"></script>
</dom-module>

View File

@@ -0,0 +1,50 @@
/**
* @license
* Copyright (C) 2018 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.
*/
(function() {
'use strict';
const COMMIT_COMMAND = 'git add . && git commit --amend --no-edit';
const PUSH_COMMAND = 'git push origin HEAD:refs/for/master';
Polymer({
is: 'gr-upload-help-dialog',
/**
* Fired when the user presses the close button.
*
* @event close
*/
properties: {
_commitCommand: {
type: String,
value: COMMIT_COMMAND,
readOnly: true,
},
_pushCommand: {
type: String,
value: PUSH_COMMAND,
readOnly: true,
},
},
_handleCloseTap(e) {
e.preventDefault();
this.fire('close', null, {bubbles: false});
},
});
})();

View File

@@ -44,6 +44,7 @@ limitations under the License.
input {
font-family: var(--monospace-font-family);
font-size: inherit;
@apply --text-container-style;
}
#icon {
height: 1.2em;