Convert files to typescript

The change converts the following files to typescript:

* elements/change-list/gr-user-header/gr-user-header.ts

Change-Id: Ie9155a311e8185e41119e7eaae1b23586f283956
diff --git a/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header.ts b/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header.ts
index 7901c53..25369b8 100644
--- a/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header.ts
+++ b/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header.ts
@@ -15,102 +15,99 @@
  * limitations under the License.
  */
 
-import '../../../styles/shared-styles.js';
-import '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator.js';
-import '../../plugins/gr-endpoint-param/gr-endpoint-param.js';
-import '../../shared/gr-avatar/gr-avatar.js';
-import '../../shared/gr-date-formatter/gr-date-formatter.js';
-import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
-import '../../../styles/dashboard-header-styles.js';
-import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
-import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
-import {PolymerElement} from '@polymer/polymer/polymer-element.js';
-import {htmlTemplate} from './gr-user-header_html.js';
-import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
+import '../../../styles/shared-styles';
+import '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator';
+import '../../plugins/gr-endpoint-param/gr-endpoint-param';
+import '../../shared/gr-avatar/gr-avatar';
+import '../../shared/gr-date-formatter/gr-date-formatter';
+import '../../shared/gr-rest-api-interface/gr-rest-api-interface';
+import '../../../styles/dashboard-header-styles';
+import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners';
+import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin';
+import {PolymerElement} from '@polymer/polymer/polymer-element';
+import {htmlTemplate} from './gr-user-header_html';
+import {GerritNav} from '../../core/gr-navigation/gr-navigation';
+import {customElement, property} from '@polymer/decorators';
+import {RestApiService} from '../../../services/services/gr-rest-api/gr-rest-api';
+import {AccountDetailInfo, AccountId} from '../../../types/common';
 
-/**
- * @extends PolymerElement
- */
-class GrUserHeader extends GestureEventListeners(
-    LegacyElementMixin(
-        PolymerElement)) {
-  static get template() { return htmlTemplate; }
+export interface GrUserHeader {
+  $: {
+    restAPI: RestApiService & Element;
+  };
+}
 
-  static get is() { return 'gr-user-header'; }
-
-  static get properties() {
-    return {
-    /** @type {?string} */
-      userId: {
-        type: String,
-        observer: '_accountChanged',
-      },
-
-      showDashboardLink: {
-        type: Boolean,
-        value: false,
-      },
-
-      loggedIn: {
-        type: Boolean,
-        value: false,
-      },
-
-      /**
-       * @type {?{name: ?, email: ?, registered_on: ?}}
-       */
-      _accountDetails: {
-        type: Object,
-        value: null,
-      },
-
-      /** @type {?string} */
-      _status: {
-        type: String,
-        value: null,
-      },
-    };
+@customElement('gr-user-header')
+export class GrUserHeader extends GestureEventListeners(
+  LegacyElementMixin(PolymerElement)
+) {
+  static get template() {
+    return htmlTemplate;
   }
 
-  _accountChanged(userId) {
+  @property({type: String, observer: '_accountChanged'})
+  userId?: AccountId;
+
+  @property({type: Boolean})
+  showDashboardLink = false;
+
+  @property({type: Boolean})
+  loggedIn = false;
+
+  @property({type: Object})
+  _accountDetails: AccountDetailInfo | null = null;
+
+  @property({type: String})
+  _status = '';
+
+  _accountChanged(userId?: AccountId) {
     if (!userId) {
       this._accountDetails = null;
-      this._status = null;
+      this._status = '';
       return;
     }
 
     this.$.restAPI.getAccountDetails(userId).then(details => {
-      this._accountDetails = details;
-    });
-    this.$.restAPI.getAccountStatus(userId).then(status => {
-      this._status = status;
+      this._accountDetails = details ?? null;
+      this._status = details?.status ?? '';
     });
   }
 
-  _computeDisplayClass(status) {
-    return status ? ' ' : 'hide';
-  }
-
-  _computeDetail(accountDetails, name) {
+  _computeDetail(
+    accountDetails: AccountDetailInfo | null,
+    name: keyof AccountDetailInfo
+  ) {
     return accountDetails ? accountDetails[name] : '';
   }
 
-  _computeStatusClass(accountDetails) {
-    return this._computeDetail(accountDetails, 'status') ? '' : 'hide';
+  _computeStatusClass(status: string) {
+    return status ? '' : 'hide';
   }
 
-  _computeDashboardUrl(accountDetails) {
-    if (!accountDetails) { return null; }
+  _computeDashboardUrl(accountDetails: AccountDetailInfo | null) {
+    if (!accountDetails) {
+      return null;
+    }
     const id = accountDetails._account_id;
+    if (id) {
+      return GerritNav.getUrlForUserDashboard(String(id));
+    }
     const email = accountDetails.email;
-    if (!id && !email ) { return null; }
-    return GerritNav.getUrlForUserDashboard(id ? id : email);
+    if (email) {
+      return GerritNav.getUrlForUserDashboard(email);
+    }
+    return null;
   }
 
-  _computeDashboardLinkClass(showDashboardLink, loggedIn) {
-    return showDashboardLink && loggedIn ?
-      'dashboardLink' : 'dashboardLink hide';
+  _computeDashboardLinkClass(showDashboardLink: boolean, loggedIn: boolean) {
+    return showDashboardLink && loggedIn
+      ? 'dashboardLink'
+      : 'dashboardLink hide';
   }
 }
 
-customElements.define(GrUserHeader.is, GrUserHeader);
+declare global {
+  interface HTMLElementTagNameMap {
+    'gr-user-header': GrUserHeader;
+  }
+}
diff --git a/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header_html.ts b/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header_html.ts
index 72bdca6..136835d 100644
--- a/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header_html.ts
+++ b/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header_html.ts
@@ -37,7 +37,7 @@
       [[_computeDetail(_accountDetails, 'name')]]
     </h1>
     <hr />
-    <div class$="status [[_computeStatusClass(_accountDetails)]]">
+    <div class$="status [[_computeStatusClass(_status)]]">
       <span>Status:</span> [[_status]]
     </div>
     <div>
diff --git a/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header_test.js b/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header_test.js
index 6baacef..15fbf8b 100644
--- a/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header_test.js
+++ b/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header_test.js
@@ -32,10 +32,9 @@
         .returns(Promise.resolve({
           name: 'foo',
           email: 'bar',
+          status: 'OOO',
           registered_on: '2015-03-12 18:32:08.000000000',
         }));
-    sinon.stub(element.$.restAPI, 'getAccountStatus')
-        .returns(Promise.resolve('baz'));
 
     element.userId = 'foo.bar@baz';
     flush(() => {
@@ -46,7 +45,7 @@
       flush(() => {
         flushAsynchronousOperations();
         assert.isNull(element._accountDetails);
-        assert.isNull(element._status);
+        assert.equal(element._status, '');
 
         done();
       });
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.ts b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.ts
index a140f50..f4111e7 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.ts
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.ts
@@ -1125,7 +1125,7 @@
     return this._restApiHelper.fetchJSON({
       url: `/accounts/${encodeURIComponent(userId)}/status`,
       anonymizedUrl: '/accounts/*/status',
-    });
+    }) as Promise<string | undefined>;
   }
 
   // https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#list-groups
diff --git a/polygerrit-ui/app/services/services/gr-rest-api/gr-rest-api.ts b/polygerrit-ui/app/services/services/gr-rest-api/gr-rest-api.ts
index 18c24d2..90112b9 100644
--- a/polygerrit-ui/app/services/services/gr-rest-api/gr-rest-api.ts
+++ b/polygerrit-ui/app/services/services/gr-rest-api/gr-rest-api.ts
@@ -534,6 +534,10 @@
 
   getAccountGroups(): Promise<GroupInfo[] | undefined>;
 
+  getAccountDetails(userId: AccountId): Promise<AccountDetailInfo | undefined>;
+
+  getAccountStatus(userId: AccountId): Promise<string | undefined>;
+
   saveAccountAgreement(name: ContributorAgreementInput): Promise<Response>;
 
   generateAccountHttpPassword(): Promise<Password>;