Merge changes I8c3b977a,I7a4d19d2

* changes:
  Specify event detail type for show-alert events
  Add option to dismiss new messages toast
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.ts b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.ts
index eca0b70..96714e3 100644
--- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.ts
@@ -115,6 +115,7 @@
   getVotingRange,
 } from '../../../utils/label-util';
 import {CommentThread} from '../../../utils/comment-util';
+import {ShowAlertEventDetail} from '../../../types/events';
 
 const ERR_BRANCH_EMPTY = 'The destination branch can’t be empty.';
 const ERR_COMMIT_EMPTY = 'The commit message can’t be empty.';
@@ -1753,7 +1754,7 @@
     return fetchChangeUpdates(change, this.restApiService).then(result => {
       if (!result.isLatest) {
         this.dispatchEvent(
-          new CustomEvent('show-alert', {
+          new CustomEvent<ShowAlertEventDetail>('show-alert', {
             detail: {
               message:
                 'Cannot set label: a newer patch has been ' +
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.ts b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.ts
index e361f9f..0ee9ad3 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.ts
@@ -146,6 +146,7 @@
   CustomKeyboardEvent,
   EditableContentSaveEvent,
   OpenFixPreviewEvent,
+  ShowAlertEventDetail,
   SwitchTabEvent,
   ThreadListModifiedEvent,
 } from '../../../types/events';
@@ -2590,11 +2591,12 @@
 
         this._cancelUpdateCheckTimer();
         this.dispatchEvent(
-          new CustomEvent('show-alert', {
+          new CustomEvent<ShowAlertEventDetail>('show-alert', {
             detail: {
               message: toastMessage,
               // Persist this alert.
               dismissOnNavigation: true,
+              showDismiss: true,
               action: 'Reload',
               callback: () => {
                 this._reload(
diff --git a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.ts b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.ts
index 71d92d0..264034c 100644
--- a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.ts
+++ b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.ts
@@ -33,7 +33,11 @@
 import {ErrorType, FixIronA11yAnnouncer} from '../../../types/types';
 import {AccountId} from '../../../types/common';
 import {EventType} from '../../../utils/event-util';
-import {NetworkErrorEvent, ServerErrorEvent} from '../../../types/events';
+import {
+  NetworkErrorEvent,
+  ServerErrorEvent,
+  ShowAlertEvent,
+} from '../../../types/events';
 
 const HIDE_ALERT_TIMEOUT_MS = 5000;
 const CHECK_SIGN_IN_INTERVAL_MS = 60 * 1000;
@@ -274,12 +278,14 @@
     return err;
   }
 
-  _handleShowAlert(e: CustomEvent) {
+  _handleShowAlert(e: ShowAlertEvent) {
     this._showAlert(
       e.detail.message,
       e.detail.action,
       e.detail.callback,
-      e.detail.dismissOnNavigation
+      e.detail.dismissOnNavigation,
+      undefined,
+      e.detail.showDismiss
     );
   }
 
@@ -299,7 +305,8 @@
     actionText?: string,
     actionCallback?: () => void,
     dismissOnNavigation?: boolean,
-    type?: ErrorType
+    type?: ErrorType,
+    showDismiss?: boolean
   ) {
     if (this._alertElement) {
       // check priority before hiding
@@ -317,7 +324,7 @@
         HIDE_ALERT_TIMEOUT_MS
       );
     }
-    const el = this._createToastAlert();
+    const el = this._createToastAlert(showDismiss);
     el.show(text, actionText, actionCallback);
     this._alertElement = el;
     this.fire('iron-announce', {text: `Alert: ${text}`}, {bubbles: true});
@@ -363,9 +370,10 @@
     }
   }
 
-  _createToastAlert() {
+  _createToastAlert(showDismiss?: boolean) {
     const el = document.createElement('gr-alert');
     el.toast = true;
+    el.showDismiss = !!showDismiss;
     return el;
   }
 
diff --git a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts
index 5cef814..3f8fe6b 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts
+++ b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts
@@ -31,6 +31,7 @@
 import {hasOwnProperty} from '../../../utils/common-util';
 import {fireEvent} from '../../../utils/event-util';
 import {isInvolved} from '../../../utils/change-util';
+import {ShowAlertEventDetail} from '../../../types/events';
 
 @customElement('gr-account-label')
 export class GrAccountLabel extends GestureEventListeners(
@@ -213,7 +214,7 @@
     if (!this.account._account_id) return;
 
     this.dispatchEvent(
-      new CustomEvent('show-alert', {
+      new CustomEvent<ShowAlertEventDetail>('show-alert', {
         detail: {
           message: 'Saving attention set update ...',
           dismissOnNavigation: true,
diff --git a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.ts b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.ts
index e5806f0..a0fddcd 100644
--- a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.ts
+++ b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.ts
@@ -62,6 +62,9 @@
   @property({type: Boolean})
   _hideActionButton?: boolean;
 
+  @property({type: Boolean})
+  showDismiss = false;
+
   @property()
   _boundTransitionEndHandler?: (
     this: HTMLElement,
@@ -105,6 +108,10 @@
     }
   }
 
+  _handleDismissTap() {
+    this.hide();
+  }
+
   _hasZeroTransitionDuration() {
     const style = window.getComputedStyle(this);
     // transitionDuration is always given in seconds.
diff --git a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_html.ts b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_html.ts
index d2aed40..b66a1dd 100644
--- a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_html.ts
+++ b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_html.ts
@@ -74,6 +74,10 @@
       hidden$="[[_hideActionButton]]"
       on-click="_handleActionTap"
       >[[actionText]]</gr-button
+    ><template is="dom-if" if="[[showDismiss]]"
+      ><gr-button link="" class="action" on-click="_handleDismissTap"
+        >Dismiss</gr-button
+      ></template
     >
   </div>
 `;
diff --git a/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard-behavior.ts b/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard-behavior.ts
index 78b6cda..94f99d3 100644
--- a/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard-behavior.ts
+++ b/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard-behavior.ts
@@ -28,12 +28,7 @@
   pushScrollLock,
   removeScrollLock,
 } from '@polymer/iron-overlay-behavior/iron-scroll-manager';
-
-interface ShowAlertEventDetail {
-  message: string;
-  dismissOnNavigation?: boolean;
-}
-
+import {ShowAlertEventDetail} from '../../../types/events';
 interface ReloadEventDetail {
   clearPatchset?: boolean;
 }
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-action-context.ts b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-action-context.ts
index ffdf710..2149fe4 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-action-context.ts
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-action-context.ts
@@ -16,6 +16,7 @@
  */
 
 import {RevisionInfo, ChangeInfo, RequestPayload} from '../../../types/common';
+import {ShowAlertEventDetail} from '../../../types/events';
 import {PluginApi} from '../../plugins/gr-plugin-types';
 import {UIActionInfo} from './gr-change-actions-js-api';
 
@@ -117,7 +118,7 @@
       .then(onSuccess)
       .catch((error: unknown) => {
         document.dispatchEvent(
-          new CustomEvent('show-alert', {
+          new CustomEvent<ShowAlertEventDetail>('show-alert', {
             detail: {
               message: `Plugin network error: ${error}`,
             },
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-loader.ts b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-loader.ts
index bdca0ed..aacef0e 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-loader.ts
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-loader.ts
@@ -27,6 +27,7 @@
 import {PluginApi} from '../../plugins/gr-plugin-types';
 import {ReportingService} from '../../../services/gr-reporting/gr-reporting';
 import {hasOwnProperty} from '../../../utils/common-util';
+import {ShowAlertEventDetail} from '../../../types/events';
 
 enum PluginState {
   /** State that indicates the plugin is pending to be loaded. */
@@ -248,7 +249,7 @@
   _failToLoad(message: string, pluginUrl?: string) {
     // Show an alert with the error
     document.dispatchEvent(
-      new CustomEvent('show-alert', {
+      new CustomEvent<ShowAlertEventDetail>('show-alert', {
         detail: {
           message: `Plugin install error: ${message} from ${pluginUrl}`,
         },
diff --git a/polygerrit-ui/app/types/events.ts b/polygerrit-ui/app/types/events.ts
index e9b2900..163c760 100644
--- a/polygerrit-ui/app/types/events.ts
+++ b/polygerrit-ui/app/types/events.ts
@@ -180,6 +180,10 @@
 
 export interface ShowAlertEventDetail {
   message: string;
+  dismissOnNavigation?: boolean;
+  showDismiss?: boolean;
+  action?: string;
+  callback?: () => void;
 }
 
 export type ShowAlertEvent = CustomEvent<ShowAlertEventDetail>;