Add support for EmailAddress in handleAttentionClick

accountOrGroupKey method falls back to email when account_id is
not set.
Use the method for calculating id so that mention users do not
return early.

Release-Notes: skip
Google-bug-id: b/236921879
Change-Id: Iec6a6c188cf5f2d4d79ab716cbfda324ef7249b8
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts
index e89b418..1514e20 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts
@@ -1588,14 +1588,15 @@
   }
 
   handleAttentionClick(e: Event) {
-    const id = (e.target as GrAccountChip)?.account?._account_id;
-    if (!id) return;
+    const targetAccount = (e.target as GrAccountChip)?.account;
+    if (!targetAccount) return;
+    // TODO: Remove cast and add support for GroupId as id type
+    const id = accountOrGroupKey(targetAccount) as AccountId | EmailAddress;
+    if (!id || !this.account || !this.change?.owner) return;
 
-    const selfId = (this.account && this.account._account_id) || -1;
-    const ownerId =
-      (this.change && this.change.owner && this.change.owner._account_id) || -1;
-    const self = id === selfId ? '_SELF' : '';
-    const role = id === ownerId ? 'OWNER' : '_REVIEWER';
+    const self = id === accountOrGroupKey(this.account) ? '_SELF' : '';
+    const role =
+      id === accountOrGroupKey(this.change.owner) ? 'OWNER' : '_REVIEWER';
 
     if (this.newAttentionSet.has(id)) {
       this.newAttentionSet.delete(id);
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.ts b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.ts
index 000df94..8674f5f 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.ts
@@ -63,6 +63,7 @@
 import {fixture, html, waitUntil} from '@open-wc/testing-helpers';
 import {accountKey} from '../../../utils/account-util';
 import {GrButton} from '../../shared/gr-button/gr-button';
+import {GrAccountLabel} from '../../shared/gr-account-label/gr-account-label';
 
 function cloneableResponse(status: number, text: string) {
   return {
@@ -2477,6 +2478,53 @@
       );
     });
 
+    test('mention user can be manually removed from attention set', async () => {
+      const draft = {
+        ...createDraft(),
+        message: 'hey @abcd@def.com take a look at this',
+        unresolved: true,
+      };
+      element.getCommentsModel().setState({
+        comments: {},
+        robotComments: {},
+        drafts: {
+          a: [draft],
+        },
+        portedComments: {},
+        portedDrafts: {},
+        discardedDrafts: [],
+      });
+      element.draftCommentThreads = [createCommentThread([draft])];
+      await waitUntil(() => element.mentionedUsers.length > 0);
+
+      await element.updateComplete;
+
+      // owner(999) is added since (accountId = 1) replied to the change
+      assert.sameMembers(
+        [...element.newAttentionSet],
+        [999 as AccountId, 'abcd@def.com' as EmailAddress]
+      );
+
+      const modifyButton = queryAndAssert<GrButton>(
+        element,
+        '.edit-attention-button'
+      );
+      modifyButton.click();
+      await element.updateComplete;
+
+      const accountsChips = Array.from(
+        queryAll<GrAccountLabel>(element, '.attention-detail gr-account-label')
+      );
+      assert.deepEqual(accountsChips[1].account, {
+        email: 'abcd@def.com' as EmailAddress,
+      });
+      accountsChips[1].click();
+
+      await element.updateComplete;
+
+      assert.sameMembers([...element.newAttentionSet], [999 as AccountId]);
+    });
+
     test('mention user who is already CCed', async () => {
       element.getCommentsModel().setState({
         comments: {},