blob: 59dcd0e518d516f8db5790fc696c607510edad99 [file] [log] [blame]
/**
* @license
* Copyright (C) 2020 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.
*/
import {html} from '@polymer/polymer/lib/utils/html-tag';
export const htmlTemplate = html`
<style include="shared-styles">
:host {
background-color: var(--dialog-background-color);
display: block;
max-height: 90vh;
}
:host([disabled]) {
pointer-events: none;
}
:host([disabled]) .container {
opacity: 0.5;
}
section {
border-top: 1px solid var(--border-color);
flex-shrink: 0;
padding: var(--spacing-m) var(--spacing-xl);
width: 100%;
}
section.labelsContainer {
/* We want the :hover highlight to extend to the border of the dialog. */
padding: var(--spacing-m) 0;
}
.stickyBottom {
background-color: var(--dialog-background-color);
box-shadow: 0px 0px 8px 0px rgba(60, 64, 67, 0.15);
margin-top: var(--spacing-s);
bottom: 0;
position: sticky;
/* @see Issue 8602 */
z-index: 1;
}
.stickyBottom.newReplyDialog {
margin-top: unset;
}
.actions {
display: flex;
justify-content: space-between;
}
.actions .right gr-button {
margin-left: var(--spacing-l);
}
.peopleContainer,
.labelsContainer {
flex-shrink: 0;
}
.peopleContainer {
border-top: none;
display: table;
}
.peopleList {
display: flex;
}
.peopleListLabel {
color: var(--deemphasized-text-color);
margin-top: var(--spacing-xs);
min-width: 6em;
padding-right: var(--spacing-m);
}
gr-account-list {
display: flex;
flex-wrap: wrap;
flex: 1;
}
#reviewerConfirmationOverlay {
padding: var(--spacing-l);
text-align: center;
}
.reviewerConfirmationButtons {
margin-top: var(--spacing-l);
}
.groupName {
font-weight: var(--font-weight-bold);
}
.groupSize {
font-style: italic;
}
.textareaContainer {
min-height: 12em;
position: relative;
}
.newReplyDialog.textareaContainer {
min-height: unset;
}
textareaContainer,
#textarea,
gr-endpoint-decorator[name='reply-text'] {
display: flex;
width: 100%;
}
.newReplyDialog .textareaContainer,
#textarea,
gr-endpoint-decorator[name='reply-text'] {
display: block;
width: unset;
font-family: var(--monospace-font-family);
font-size: var(--font-size-code);
line-height: calc(var(--font-size-code) + var(--spacing-s));
font-weight: var(--font-weight-normal);
}
.newReplyDialog#textarea {
padding: var(--spacing-m);
}
gr-endpoint-decorator[name='reply-text'] {
flex-direction: column;
}
#textarea {
flex: 1;
}
.previewContainer {
border-top: none;
}
.previewContainer gr-formatted-text {
background: var(--table-header-background-color);
padding: var(--spacing-l);
}
#checkingStatusLabel,
#notLatestLabel {
margin-left: var(--spacing-l);
}
#checkingStatusLabel {
color: var(--deemphasized-text-color);
font-style: italic;
}
#notLatestLabel,
#savingLabel {
color: var(--error-text-color);
}
#savingLabel {
display: none;
}
#savingLabel.saving {
display: inline;
}
#pluginMessage {
color: var(--deemphasized-text-color);
margin-left: var(--spacing-l);
margin-bottom: var(--spacing-m);
}
#pluginMessage:empty {
display: none;
}
.preview-formatting {
margin-left: var(--spacing-m);
}
.attention-icon {
width: 14px;
height: 14px;
vertical-align: top;
position: relative;
top: 3px;
--iron-icon-height: 24px;
--iron-icon-width: 24px;
}
.attention .edit-attention-button {
vertical-align: top;
--gr-button-padding: 0px 4px;
}
.attention .edit-attention-button iron-icon {
color: inherit;
}
.attention a,
.attention-detail a {
text-decoration: none;
}
.attentionSummary {
display: flex;
justify-content: space-between;
}
.attentionSummary {
/* The account label for selection is misbehaving currently: It consumes
26px height instead of 20px, which is the default line-height and thus
the max that can be nicely fit into an inline layout flow. We
acknowledge that using a fixed 26px value here is a hack and not a
great solution. */
line-height: 26px;
}
.attentionSummary gr-account-label,
.attention-detail gr-account-label {
--account-max-length: 120px;
display: inline-block;
padding: var(--spacing-xs) var(--spacing-m);
user-select: none;
--label-border-radius: 8px;
}
.attentionSummary gr-account-label {
margin: 0 var(--spacing-xs);
line-height: var(--line-height-normal);
vertical-align: top;
}
.attention-detail .peopleListValues {
line-height: calc(var(--line-height-normal) + 10px);
}
.attention-detail gr-account-label {
line-height: var(--line-height-normal);
}
.attentionSummary gr-account-label:focus,
.attention-detail gr-account-label:focus {
outline: none;
}
.attentionSummary gr-account-label:hover,
.attention-detail gr-account-label:hover {
box-shadow: var(--elevation-level-1);
cursor: pointer;
}
.attention-detail .attentionDetailsTitle {
display: flex;
justify-content: space-between;
}
.attention-detail .selectUsers {
color: var(--deemphasized-text-color);
margin-bottom: var(--spacing-m);
}
.attentionTip {
padding: var(--spacing-m);
border: 1px solid var(--border-color);
border-radius: var(--border-radius);
margin-top: var(--spacing-m);
background-color: var(--assignee-highlight-color);
}
.attentionTip div iron-icon {
margin-right: var(--spacing-s);
}
.patchsetLevelContainer {
width: 80ch;
border-radius: var(--border-radius);
box-shadow: var(--elevation-level-2);
}
.patchsetLevelContainer.resolved{
background-color: var(--comment-background-color);
}
.patchsetLevelContainer.unresolved{
background-color: var(--unresolved-comment-background-color);
}
.labelContainer {
padding-left: var(--spacing-m);
padding-bottom: var(--spacing-m);
}
</style>
<div tabindex="-1">
<section class="peopleContainer">
<gr-endpoint-decorator name="reply-reviewers">
<gr-endpoint-param name="change" value="[[change]]"></gr-endpoint-param>
<gr-endpoint-param name="reviewers" value="[[_allReviewers]]">
</gr-endpoint-param>
<div class="peopleList">
<div class="peopleListLabel">Reviewers</div>
<gr-account-list
id="reviewers"
accounts="{{_reviewers}}"
removable-values="[[change.removable_reviewers]]"
filter="[[filterReviewerSuggestion]]"
pending-confirmation="{{_reviewerPendingConfirmation}}"
placeholder="Add reviewer..."
on-account-text-changed="_handleAccountTextEntry"
suggestions-provider="[[_getReviewerSuggestionsProvider(change)]]"
>
</gr-account-list>
<gr-endpoint-slot name="right"></gr-endpoint-slot>
</div>
<gr-endpoint-slot name="below"></gr-endpoint-slot>
</gr-endpoint-decorator>
<div class="peopleList">
<div class="peopleListLabel">CC</div>
<gr-account-list
id="ccs"
accounts="{{_ccs}}"
filter="[[filterCCSuggestion]]"
pending-confirmation="{{_ccPendingConfirmation}}"
allow-any-input=""
placeholder="Add CC..."
on-account-text-changed="_handleAccountTextEntry"
suggestions-provider="[[_getCcSuggestionsProvider(change)]]"
>
</gr-account-list>
</div>
<gr-overlay
id="reviewerConfirmationOverlay"
on-iron-overlay-canceled="_cancelPendingReviewer"
>
<div class="reviewerConfirmation">
Group
<span class="groupName">
[[_pendingConfirmationDetails.group.name]]
</span>
has
<span class="groupSize"> [[_pendingConfirmationDetails.count]] </span>
members.
<br />
Are you sure you want to add them all?
</div>
<div class="reviewerConfirmationButtons">
<gr-button on-click="_confirmPendingReviewer">Yes</gr-button>
<gr-button on-click="_cancelPendingReviewer">No</gr-button>
</div>
</gr-overlay>
</section>
<section class="labelsContainer">
<gr-endpoint-decorator name="reply-label-scores">
<gr-label-scores
id="labelScores"
account="[[_account]]"
change="[[change]]"
on-labels-changed="_handleLabelsChanged"
permitted-labels="[[permittedLabels]]"
></gr-label-scores>
<gr-endpoint-param name="change" value="[[change]]"></gr-endpoint-param>
</gr-endpoint-decorator>
<div id="pluginMessage">[[_pluginMessage]]</div>
</section>
<section class="newReplyDialog textareaContainer">
<div class$="patchsetLevelContainer [[getUnresolvedPatchsetLevelClass(_isResolvedPatchsetLevelComment)]]">
<gr-endpoint-decorator name="reply-text">
<gr-textarea
id="textarea"
class="message newReplyDialog"
autocomplete="on"
placeholder="[[_messagePlaceholder]]"
monospace="true"
disabled="{{disabled}}"
rows="4"
text="{{draft}}"
on-bind-value-changed="_handleHeightChanged"
>
</gr-textarea>
<gr-endpoint-param name="change" value="[[change]]">
</gr-endpoint-param>
</gr-endpoint-decorator>
<div class="labelContainer">
<label>
<input
id="resolvedPatchsetLevelCommentCheckbox"
type="checkbox"
checked="{{_isResolvedPatchsetLevelComment::change}}"
/>
Resolved
</label>
<label class="preview-formatting">
<input type="checkbox" checked="{{_previewFormatting::change}}" />
Preview formatting
</label>
</div>
</div>
</section>
<template is="dom-if" if="[[_previewFormatting]]">
<section class="previewContainer">
<gr-formatted-text
content="[[draft]]"
config="[[projectConfig.commentlinks]]"
></gr-formatted-text>
</template>
</section>
<section
class="draftsContainer"
hidden$="[[_computeHideDraftList(draftCommentThreads)]]"
>
<div class="includeComments">
<input
type="checkbox"
id="includeComments"
checked="{{_includeComments::change}}"
/>
<label for="includeComments"
>Publish [[_computeDraftsTitle(draftCommentThreads)]]</label
>
</div>
<gr-thread-list
id="commentList"
hidden$="[[!_includeComments]]"
threads="[[draftCommentThreads]]"
hide-dropdown=""
>
</gr-thread-list>
<span
id="savingLabel"
class$="[[_computeSavingLabelClass(_savingComments)]]"
>
Saving comments...
</span>
</section>
<div class="stickyBottom newReplyDialog">
<gr-endpoint-decorator name="reply-bottom">
<gr-endpoint-param name="change" value="[[change]]"></gr-endpoint-param>
<section
hidden$="[[!_showAttentionSummary(_attentionExpanded)]]"
class="attention"
>
<div class="attentionSummary">
<div>
<template
is="dom-if"
if="[[_computeShowNoAttentionUpdate(serverConfig, _currentAttentionSet, _newAttentionSet, _sendDisabled)]]"
>
<span
>[[_computeDoNotUpdateMessage(_currentAttentionSet,
_newAttentionSet, _sendDisabled)]]</span
>
</template>
<template
is="dom-if"
if="[[!_computeShowNoAttentionUpdate(serverConfig, _currentAttentionSet, _newAttentionSet, _sendDisabled)]]"
>
<span>Bring to attention of</span>
<template
is="dom-repeat"
items="[[_computeNewAttentionAccounts(serverConfig, _currentAttentionSet, _newAttentionSet)]]"
as="account"
>
<gr-account-label
account="[[account]]"
force-attention="[[_computeHasNewAttention(account, _newAttentionSet)]]"
selected="[[_computeHasNewAttention(account, _newAttentionSet)]]"
hideHovercard
selectionChipStyle
on-click="_handleAttentionClick"
></gr-account-label>
</template>
</template>
<gr-tooltip-content
has-tooltip
title="[[_computeAttentionButtonTitle(_sendDisabled)]]"
>
<gr-button
class="edit-attention-button"
on-click="_handleAttentionModify"
disabled="[[_sendDisabled]]"
link=""
position-below=""
data-label="Edit"
data-action-type="change"
data-action-key="edit"
role="button"
tabindex="0"
>
<iron-icon icon="gr-icons:edit"></iron-icon>
Modify
</gr-button>
</gr-tooltip-content>
</div>
<div>
<a
href="https://gerrit-review.googlesource.com/Documentation/user-attention-set.html"
target="_blank"
>
<iron-icon
icon="gr-icons:help-outline"
title="read documentation"
></iron-icon>
</a>
</div>
</div>
</section>
<section
hidden$="[[!_showAttentionDetails(_attentionExpanded)]]"
class="attention-detail"
>
<div class="attentionDetailsTitle">
<div>
<span>Modify attention to</span>
</div>
<div></div>
<div>
<a
href="https://gerrit-review.googlesource.com/Documentation/user-attention-set.html"
target="_blank"
>
<iron-icon
icon="gr-icons:help-outline"
title="read documentation"
></iron-icon>
</a>
</div>
</div>
<div class="selectUsers">
<span
>Select chips to set who will be in the attention set after sending
this reply</span
>
</div>
<div class="peopleList">
<div class="peopleListLabel">Owner</div>
<div class="peopleListValues">
<gr-account-label
account="[[_owner]]"
force-attention="[[_computeHasNewAttention(_owner, _newAttentionSet)]]"
selected="[[_computeHasNewAttention(_owner, _newAttentionSet)]]"
hideHovercard
selectionChipStyle
on-click="_handleAttentionClick"
>
</gr-account-label>
</div>
</div>
<template is="dom-if" if="[[_uploader]]">
<div class="peopleList">
<div class="peopleListLabel">Uploader</div>
<div class="peopleListValues">
<gr-account-label
account="[[_uploader]]"
force-attention="[[_computeHasNewAttention(_uploader, _newAttentionSet)]]"
selected="[[_computeHasNewAttention(_uploader, _newAttentionSet)]]"
hideHovercard
selectionChipStyle
on-click="_handleAttentionClick"
>
</gr-account-label>
</div>
</div>
</template>
<div class="peopleList">
<div class="peopleListLabel">Reviewers</div>
<div class="peopleListValues">
<template
is="dom-repeat"
items="[[_removeServiceUsers(_reviewers, _newAttentionSet)]]"
as="account"
>
<gr-account-label
account="[[account]]"
force-attention="[[_computeHasNewAttention(account, _newAttentionSet)]]"
selected="[[_computeHasNewAttention(account, _newAttentionSet)]]"
hideHovercard
selectionChipStyle
on-click="_handleAttentionClick"
>
</gr-account-label>
</template>
</div>
</div>
<template is="dom-if" if="[[_attentionCcsCount]]">
<div class="peopleList">
<div class="peopleListLabel">CC</div>
<div class="peopleListValues">
<template
is="dom-repeat"
items="[[_removeServiceUsers(_ccs, _newAttentionSet)]]"
as="account"
>
<gr-account-label
account="[[account]]"
force-attention="[[_computeHasNewAttention(account, _newAttentionSet)]]"
selected="[[_computeHasNewAttention(account, _newAttentionSet)]]"
hideHovercard
selectionChipStyle
on-click="_handleAttentionClick"
>
</gr-account-label>
</template>
</div>
</div>
</template>
<template
is="dom-if"
if="[[_computeShowAttentionTip(_account, _owner, _currentAttentionSet, _newAttentionSet)]]"
>
<div class="attentionTip">
<iron-icon
class="pointer"
icon="gr-icons:lightbulb-outline"
></iron-icon>
Be mindful of requiring attention from too many users.
</div>
</template>
</section>
<gr-endpoint-slot name="above-actions"></gr-endpoint-slot>
<section class="actions">
<div class="left">
<span
id="checkingStatusLabel"
hidden$="[[!_isState(knownLatestState, 'checking')]]"
>
Checking whether patch [[patchNum]] is latest...
</span>
<span
id="notLatestLabel"
hidden$="[[!_isState(knownLatestState, 'not-latest')]]"
>
[[_computePatchSetWarning(patchNum, _labelsChanged)]]
<gr-button link="" on-click="_reload">Reload</gr-button>
</span>
</div>
<div class="right">
<gr-button
link=""
id="cancelButton"
class="action cancel"
on-click="_cancelTapHandler"
>Cancel</gr-button
>
<template is="dom-if" if="[[canBeStarted]]">
<!-- Use 'Send' here as the change may only about reviewers / ccs
and when this button is visible, the next button will always
be 'Start review' -->
<gr-tooltip-content
has-tooltip=""
title$="[[_saveTooltip]]"
>
<gr-button
link=""
disabled="[[_isState(knownLatestState, 'not-latest')]]"
class="action save"
on-click="_saveClickHandler"
>Send As WIP</gr-button
>
</gr-tooltip-content>
</template>
<gr-tooltip-content
has-tooltip=""
title$="[[_computeSendButtonTooltip(canBeStarted, _commentEditing)]]"
>
<gr-button
id="sendButton"
primary=""
disabled="[[_sendDisabled]]"
class="action send"
on-click="_sendTapHandler"
>[[_sendButtonLabel]]
</gr-button>
</gr-tooltip-content>
</div>
</section>
</gr-endpoint-decorator>
</div>
</div>
`;