Merge "Cache rest api for getAccountDetails"
diff --git a/polygerrit-ui/app/models/accounts-model/accounts-model.ts b/polygerrit-ui/app/models/accounts-model/accounts-model.ts
index 2bf6068..1c67857 100644
--- a/polygerrit-ui/app/models/accounts-model/accounts-model.ts
+++ b/polygerrit-ui/app/models/accounts-model/accounts-model.ts
@@ -8,11 +8,14 @@
 import {RestApiService} from '../../services/gr-rest-api/gr-rest-api';
 import {UserId} from '../../types/common';
 import {getUserId, isDetailedAccount} from '../../utils/account-util';
+import {hasOwnProperty} from '../../utils/common-util';
 import {define} from '../dependency';
 import {Model} from '../model';
 
 export interface AccountsState {
-  accounts: {[id: UserId]: AccountDetailInfo};
+  accounts: {
+    [id: UserId]: AccountDetailInfo | AccountInfo;
+  };
 }
 
 export const accountsModelToken = define<AccountsModel>('accounts-model');
@@ -24,33 +27,36 @@
     });
   }
 
-  private updateStateAccount(id: UserId, account?: AccountDetailInfo) {
+  private updateStateAccount(
+    id: UserId,
+    account: AccountDetailInfo | AccountInfo
+  ) {
     if (!account) return;
     const current = {...this.getState()};
     current.accounts = {...current.accounts, [id]: account};
     this.setState(current);
   }
 
-  async getAccount(partialAccount: AccountInfo) {
+  async getAccount(
+    partialAccount: AccountInfo
+  ): Promise<AccountDetailInfo | AccountInfo> {
     const current = this.getState();
     const id = getUserId(partialAccount);
-    if (current.accounts[id]) return current.accounts[id];
+    if (hasOwnProperty(current.accounts, id)) return current.accounts[id];
     // It is possible to add emails to CC when they don't have a Gerrit
-    // account. In this case getAccountDetails will return a 404 error hence
-    // pass an empty error function to handle that.
+    // account. In this case getAccountDetails will return a 404 error then
+    // we at least use what is in partialAccount.
     const account = await this.restApiService.getAccountDetails(id, () => {
-      this.updateStateAccount(id, partialAccount as AccountDetailInfo);
+      this.updateStateAccount(id, partialAccount);
       return;
     });
     if (account) this.updateStateAccount(id, account);
-    return account;
+    return account ?? partialAccount;
   }
 
   async fillDetails(account: AccountInfo) {
     if (!isDetailedAccount(account)) {
-      if (account.email) return await this.getAccount({email: account.email});
-      else if (account._account_id)
-        return await this.getAccount({_account_id: account._account_id});
+      return await this.getAccount(account);
     }
     return account;
   }
diff --git a/polygerrit-ui/app/services/gr-rest-api/gr-rest-api-impl.ts b/polygerrit-ui/app/services/gr-rest-api/gr-rest-api-impl.ts
index 0d0c88f..610d8f3 100644
--- a/polygerrit-ui/app/services/gr-rest-api/gr-rest-api-impl.ts
+++ b/polygerrit-ui/app/services/gr-rest-api/gr-rest-api-impl.ts
@@ -769,7 +769,7 @@
     userId: AccountId | EmailAddress,
     errFn?: ErrorCallback
   ): Promise<AccountDetailInfo | undefined> {
-    return this._restApiHelper.fetchJSON({
+    return this._fetchSharedCacheURL({
       url: `/accounts/${encodeURIComponent(userId)}/detail`,
       anonymizedUrl: '/accounts/*/detail',
       errFn,