Change when and how attention can be modified in the reply dialog
You cannot change the attention set in the reply dialog anymore without making one of these three modifications: vote, comment, add/remove reviewer/cc. The 'Modify' button is disabled, iff the 'Send' button is disabled. If the 'Modify' button is disabled, then the message is always: 'No changes to the attention set.' Change-Id: Ib86a3db823641b2ca518bcbf688610e1e88e943c
This commit is contained in:
@@ -899,6 +899,13 @@ export class GrReplyDialog extends KeyboardShortcutMixin(
|
|||||||
return isAttentionSetEnabled(config) && attentionExpanded;
|
return isAttentionSetEnabled(config) && attentionExpanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_computeAttentionButtonTitle(sendDisabled?: boolean) {
|
||||||
|
return sendDisabled
|
||||||
|
? 'Modify the attention set by adding a comment or use the account ' +
|
||||||
|
'hovercard in the change page.'
|
||||||
|
: 'Edit attention set changes';
|
||||||
|
}
|
||||||
|
|
||||||
_handleAttentionClick(e: Event) {
|
_handleAttentionClick(e: Event) {
|
||||||
const id = (e.target as GrAccountChip)?.account?._account_id;
|
const id = (e.target as GrAccountChip)?.account?._account_id;
|
||||||
if (!id) return;
|
if (!id) return;
|
||||||
@@ -1064,12 +1071,14 @@ export class GrReplyDialog extends KeyboardShortcutMixin(
|
|||||||
return accountIds;
|
return accountIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
_isNewAttentionEmpty(
|
_computeShowNoAttentionUpdate(
|
||||||
config?: ServerInfo,
|
config?: ServerInfo,
|
||||||
currentAttentionSet?: Set<AccountId>,
|
currentAttentionSet?: Set<AccountId>,
|
||||||
newAttentionSet?: Set<AccountId>
|
newAttentionSet?: Set<AccountId>,
|
||||||
|
sendDisabled?: boolean
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
|
sendDisabled ||
|
||||||
this._computeNewAttentionAccounts(
|
this._computeNewAttentionAccounts(
|
||||||
config,
|
config,
|
||||||
currentAttentionSet,
|
currentAttentionSet,
|
||||||
@@ -1080,10 +1089,11 @@ export class GrReplyDialog extends KeyboardShortcutMixin(
|
|||||||
|
|
||||||
_computeDoNotUpdateMessage(
|
_computeDoNotUpdateMessage(
|
||||||
currentAttentionSet?: Set<AccountId>,
|
currentAttentionSet?: Set<AccountId>,
|
||||||
newAttentionSet?: Set<AccountId>
|
newAttentionSet?: Set<AccountId>,
|
||||||
|
sendDisabled?: boolean
|
||||||
) {
|
) {
|
||||||
if (!currentAttentionSet || !newAttentionSet) return '';
|
if (!currentAttentionSet || !newAttentionSet) return '';
|
||||||
if (areSetsEqual(currentAttentionSet, newAttentionSet)) {
|
if (sendDisabled || areSetsEqual(currentAttentionSet, newAttentionSet)) {
|
||||||
return 'No changes to the attention set.';
|
return 'No changes to the attention set.';
|
||||||
}
|
}
|
||||||
if (containsAll(currentAttentionSet, newAttentionSet)) {
|
if (containsAll(currentAttentionSet, newAttentionSet)) {
|
||||||
@@ -1398,10 +1408,7 @@ export class GrReplyDialog extends KeyboardShortcutMixin(
|
|||||||
labelsChanged?: boolean,
|
labelsChanged?: boolean,
|
||||||
includeComments?: boolean,
|
includeComments?: boolean,
|
||||||
disabled?: boolean,
|
disabled?: boolean,
|
||||||
commentEditing?: boolean,
|
commentEditing?: boolean
|
||||||
attentionExpanded?: boolean,
|
|
||||||
_currentAttentionSet?: Set<AccountId>,
|
|
||||||
_newAttentionSet?: Set<AccountId>
|
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
canBeStarted === undefined ||
|
canBeStarted === undefined ||
|
||||||
@@ -1411,10 +1418,7 @@ export class GrReplyDialog extends KeyboardShortcutMixin(
|
|||||||
labelsChanged === undefined ||
|
labelsChanged === undefined ||
|
||||||
includeComments === undefined ||
|
includeComments === undefined ||
|
||||||
disabled === undefined ||
|
disabled === undefined ||
|
||||||
commentEditing === undefined ||
|
commentEditing === undefined
|
||||||
attentionExpanded === undefined ||
|
|
||||||
_currentAttentionSet === undefined ||
|
|
||||||
_newAttentionSet === undefined
|
|
||||||
) {
|
) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@@ -1425,29 +1429,7 @@ export class GrReplyDialog extends KeyboardShortcutMixin(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const hasDrafts = includeComments && draftCommentThreads.length;
|
const hasDrafts = includeComments && draftCommentThreads.length;
|
||||||
// Changing the attention set is also sufficient to enable the 'Send'
|
return !hasDrafts && !text.length && !reviewersMutated && !labelsChanged;
|
||||||
// button, but only if the attention set detail section was expanded and
|
|
||||||
// either someone other than the owner was added, or someone other than the
|
|
||||||
// current user was removed.
|
|
||||||
const isNotCurrentUser = (id: AccountId) =>
|
|
||||||
id !== this._account?._account_id;
|
|
||||||
const isNotOwner = (id: AccountId) => id !== this._owner?._account_id;
|
|
||||||
const attentionAdditions = [..._newAttentionSet]
|
|
||||||
.filter(id => !_currentAttentionSet.has(id))
|
|
||||||
.filter(isNotOwner);
|
|
||||||
const attentionRemovals = [..._currentAttentionSet]
|
|
||||||
.filter(id => !_newAttentionSet.has(id))
|
|
||||||
.filter(isNotCurrentUser);
|
|
||||||
const hasAttentionChange =
|
|
||||||
attentionExpanded &&
|
|
||||||
(attentionAdditions.length > 0 || attentionRemovals.length > 0);
|
|
||||||
return (
|
|
||||||
!hasDrafts &&
|
|
||||||
!text.length &&
|
|
||||||
!reviewersMutated &&
|
|
||||||
!labelsChanged &&
|
|
||||||
!hasAttentionChange
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_computePatchSetWarning(patchNum?: PatchSetNum, labelsChanged?: boolean) {
|
_computePatchSetWarning(patchNum?: PatchSetNum, labelsChanged?: boolean) {
|
||||||
|
|||||||
@@ -376,16 +376,16 @@ export const htmlTemplate = html`
|
|||||||
<div>
|
<div>
|
||||||
<template
|
<template
|
||||||
is="dom-if"
|
is="dom-if"
|
||||||
if="[[_isNewAttentionEmpty(serverConfig, _currentAttentionSet, _newAttentionSet)]]"
|
if="[[_computeShowNoAttentionUpdate(serverConfig, _currentAttentionSet, _newAttentionSet, _sendDisabled)]]"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
>[[_computeDoNotUpdateMessage(_currentAttentionSet,
|
>[[_computeDoNotUpdateMessage(_currentAttentionSet,
|
||||||
_newAttentionSet)]]</span
|
_newAttentionSet, _sendDisabled)]]</span
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
<template
|
<template
|
||||||
is="dom-if"
|
is="dom-if"
|
||||||
if="[[!_isNewAttentionEmpty(serverConfig, _currentAttentionSet, _newAttentionSet)]]"
|
if="[[!_computeShowNoAttentionUpdate(serverConfig, _currentAttentionSet, _newAttentionSet, _sendDisabled)]]"
|
||||||
>
|
>
|
||||||
<span>Bring to attention of</span>
|
<span>Bring to attention of</span>
|
||||||
<template
|
<template
|
||||||
@@ -406,12 +406,13 @@ export const htmlTemplate = html`
|
|||||||
<gr-button
|
<gr-button
|
||||||
class="edit-attention-button"
|
class="edit-attention-button"
|
||||||
on-click="_handleAttentionModify"
|
on-click="_handleAttentionModify"
|
||||||
|
disabled="[[_sendDisabled]]"
|
||||||
link=""
|
link=""
|
||||||
position-below=""
|
position-below=""
|
||||||
data-label="Edit"
|
data-label="Edit"
|
||||||
data-action-type="change"
|
data-action-type="change"
|
||||||
data-action-key="edit"
|
data-action-key="edit"
|
||||||
title="Edit attention set changes"
|
title="[[_computeAttentionButtonTitle(_sendDisabled)]]"
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -999,11 +999,18 @@ suite('gr-reply-dialog tests', () => {
|
|||||||
element._reviewers = [makeAccount(), makeAccount()];
|
element._reviewers = [makeAccount(), makeAccount()];
|
||||||
element._ccs = [makeAccount(), makeAccount()];
|
element._ccs = [makeAccount(), makeAccount()];
|
||||||
element.draftCommentThreads = [];
|
element.draftCommentThreads = [];
|
||||||
MockInteractions.tap(
|
const modifyButton =
|
||||||
element.shadowRoot.querySelector('.edit-attention-button'));
|
element.shadowRoot.querySelector('.edit-attention-button');
|
||||||
|
MockInteractions.tap(modifyButton);
|
||||||
flush();
|
flush();
|
||||||
|
|
||||||
|
// "Modify" button disabled, because "Send" button is disabled.
|
||||||
|
assert.isFalse(element._attentionExpanded);
|
||||||
|
element.draft = 'a test comment';
|
||||||
|
MockInteractions.tap(modifyButton);
|
||||||
|
flush();
|
||||||
assert.isTrue(element._attentionExpanded);
|
assert.isTrue(element._attentionExpanded);
|
||||||
|
|
||||||
let accountLabels = Array.from(element.shadowRoot.querySelectorAll(
|
let accountLabels = Array.from(element.shadowRoot.querySelectorAll(
|
||||||
'.attention-detail gr-account-label'));
|
'.attention-detail gr-account-label'));
|
||||||
assert.equal(accountLabels.length, 5);
|
assert.equal(accountLabels.length, 5);
|
||||||
@@ -1368,10 +1375,7 @@ suite('gr-reply-dialog tests', () => {
|
|||||||
/* labelsChanged= */ false,
|
/* labelsChanged= */ false,
|
||||||
/* includeComments= */ false,
|
/* includeComments= */ false,
|
||||||
/* disabled= */ false,
|
/* disabled= */ false,
|
||||||
/* commentEditing= */ false,
|
/* commentEditing= */ false
|
||||||
/* attentionExpanded= */ false,
|
|
||||||
/* _currentAttentionSet */ new Set(),
|
|
||||||
/* _newAttentionSet */ new Set()
|
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1386,28 +1390,7 @@ suite('gr-reply-dialog tests', () => {
|
|||||||
/* labelsChanged= */ false,
|
/* labelsChanged= */ false,
|
||||||
/* includeComments= */ false,
|
/* includeComments= */ false,
|
||||||
/* disabled= */ false,
|
/* disabled= */ false,
|
||||||
/* commentEditing= */ false,
|
/* commentEditing= */ false
|
||||||
/* attentionExpanded= */ false,
|
|
||||||
/* _currentAttentionSet */ new Set(),
|
|
||||||
/* _newAttentionSet */ new Set()
|
|
||||||
));
|
|
||||||
});
|
|
||||||
|
|
||||||
test('_computeSendButtonDisabled_attentionExpanded true', () => {
|
|
||||||
const fn = element._computeSendButtonDisabled.bind(element);
|
|
||||||
// Mock everything false
|
|
||||||
assert.isFalse(fn(
|
|
||||||
/* canBeStarted= */ false,
|
|
||||||
/* draftCommentThreads= */ [],
|
|
||||||
/* text= */ '',
|
|
||||||
/* reviewersMutated= */ false,
|
|
||||||
/* labelsChanged= */ false,
|
|
||||||
/* includeComments= */ false,
|
|
||||||
/* disabled= */ false,
|
|
||||||
/* commentEditing= */ false,
|
|
||||||
/* attentionExpanded= */ true,
|
|
||||||
/* _currentAttentionSet */ new Set(),
|
|
||||||
/* _newAttentionSet */ new Set([1])
|
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1422,10 +1405,7 @@ suite('gr-reply-dialog tests', () => {
|
|||||||
/* labelsChanged= */ false,
|
/* labelsChanged= */ false,
|
||||||
/* includeComments= */ true,
|
/* includeComments= */ true,
|
||||||
/* disabled= */ false,
|
/* disabled= */ false,
|
||||||
/* commentEditing= */ false,
|
/* commentEditing= */ false
|
||||||
/* attentionExpanded= */ false,
|
|
||||||
/* _currentAttentionSet */ new Set(),
|
|
||||||
/* _newAttentionSet */ new Set()
|
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1440,10 +1420,7 @@ suite('gr-reply-dialog tests', () => {
|
|||||||
/* labelsChanged= */ false,
|
/* labelsChanged= */ false,
|
||||||
/* includeComments= */ false,
|
/* includeComments= */ false,
|
||||||
/* disabled= */ false,
|
/* disabled= */ false,
|
||||||
/* commentEditing= */ false,
|
/* commentEditing= */ false
|
||||||
/* attentionExpanded= */ false,
|
|
||||||
/* _currentAttentionSet */ new Set(),
|
|
||||||
/* _newAttentionSet */ new Set()
|
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1458,10 +1435,7 @@ suite('gr-reply-dialog tests', () => {
|
|||||||
/* labelsChanged= */ false,
|
/* labelsChanged= */ false,
|
||||||
/* includeComments= */ false,
|
/* includeComments= */ false,
|
||||||
/* disabled= */ false,
|
/* disabled= */ false,
|
||||||
/* commentEditing= */ false,
|
/* commentEditing= */ false
|
||||||
/* attentionExpanded= */ false,
|
|
||||||
/* _currentAttentionSet */ new Set(),
|
|
||||||
/* _newAttentionSet */ new Set()
|
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1476,10 +1450,7 @@ suite('gr-reply-dialog tests', () => {
|
|||||||
/* labelsChanged= */ false,
|
/* labelsChanged= */ false,
|
||||||
/* includeComments= */ false,
|
/* includeComments= */ false,
|
||||||
/* disabled= */ false,
|
/* disabled= */ false,
|
||||||
/* commentEditing= */ false,
|
/* commentEditing= */ false
|
||||||
/* attentionExpanded= */ false,
|
|
||||||
/* _currentAttentionSet */ new Set(),
|
|
||||||
/* _newAttentionSet */ new Set()
|
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1494,10 +1465,7 @@ suite('gr-reply-dialog tests', () => {
|
|||||||
/* labelsChanged= */ true,
|
/* labelsChanged= */ true,
|
||||||
/* includeComments= */ false,
|
/* includeComments= */ false,
|
||||||
/* disabled= */ false,
|
/* disabled= */ false,
|
||||||
/* commentEditing= */ false,
|
/* commentEditing= */ false
|
||||||
/* attentionExpanded= */ false,
|
|
||||||
/* _currentAttentionSet */ new Set(),
|
|
||||||
/* _newAttentionSet */ new Set()
|
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1512,10 +1480,7 @@ suite('gr-reply-dialog tests', () => {
|
|||||||
/* labelsChanged= */ true,
|
/* labelsChanged= */ true,
|
||||||
/* includeComments= */ false,
|
/* includeComments= */ false,
|
||||||
/* disabled= */ true,
|
/* disabled= */ true,
|
||||||
/* commentEditing= */ false,
|
/* commentEditing= */ false
|
||||||
/* attentionExpanded= */ false,
|
|
||||||
/* _currentAttentionSet */ new Set(),
|
|
||||||
/* _newAttentionSet */ new Set()
|
|
||||||
));
|
));
|
||||||
assert.isTrue(fn(
|
assert.isTrue(fn(
|
||||||
/* buttonLabel= */ 'Send',
|
/* buttonLabel= */ 'Send',
|
||||||
@@ -1525,10 +1490,7 @@ suite('gr-reply-dialog tests', () => {
|
|||||||
/* labelsChanged= */ true,
|
/* labelsChanged= */ true,
|
||||||
/* includeComments= */ false,
|
/* includeComments= */ false,
|
||||||
/* disabled= */ false,
|
/* disabled= */ false,
|
||||||
/* commentEditing= */ true,
|
/* commentEditing= */ true
|
||||||
/* attentionExpanded= */ false,
|
|
||||||
/* _currentAttentionSet */ new Set(),
|
|
||||||
/* _newAttentionSet */ new Set()
|
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user