Merge "Improve design of keyboard shortcuts dialog"
diff --git a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
index ad240d4..28ffef7 100644
--- a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
+++ b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
@@ -60,6 +60,7 @@
 import com.google.gerrit.server.account.AccountResolver;
 import com.google.gerrit.server.account.AccountResolver.UnresolvableAccountException;
 import com.google.gerrit.server.account.AccountState;
+import com.google.gerrit.server.account.DestinationList;
 import com.google.gerrit.server.account.GroupBackend;
 import com.google.gerrit.server.account.GroupBackends;
 import com.google.gerrit.server.account.GroupMembers;
@@ -96,6 +97,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -479,6 +481,7 @@
 
   private final Arguments args;
   protected Map<String, String> hasOperandAliases = Collections.emptyMap();
+  private Map<Account.Id, DestinationList> destinationListByAccount = new HashMap<>();
 
   private static final Splitter RULE_SPLITTER = Splitter.on("=");
   private static final Splitter PLUGIN_SPLITTER = Splitter.on("_");
@@ -1497,9 +1500,7 @@
         account = self();
       }
 
-      VersionedAccountDestinations d = VersionedAccountDestinations.forUser(account);
-      d.load(args.allUsersName, git);
-      Set<BranchNameKey> destinations = d.getDestinationList().getDestinations(name);
+      Set<BranchNameKey> destinations = getDestinationList(git, account).getDestinations(name);
       if (destinations != null && !destinations.isEmpty()) {
         return new DestinationPredicate(destinations, value);
       }
@@ -1512,6 +1513,23 @@
     throw new QueryParseException("Unknown named destination: " + name);
   }
 
+  protected DestinationList getDestinationList(Repository git, Account.Id account)
+      throws ConfigInvalidException, RepositoryNotFoundException, IOException {
+    DestinationList dl = destinationListByAccount.get(account);
+    if (dl == null) {
+      dl = loadDestinationList(git, account);
+      destinationListByAccount.put(account, dl);
+    }
+    return dl;
+  }
+
+  protected DestinationList loadDestinationList(Repository git, Account.Id account)
+      throws ConfigInvalidException, RepositoryNotFoundException, IOException {
+    VersionedAccountDestinations d = VersionedAccountDestinations.forUser(account);
+    d.load(args.allUsersName, git);
+    return d.getDestinationList();
+  }
+
   @Operator
   public Predicate<ChangeData> author(String who) throws QueryParseException {
     return getAuthorOrCommitterPredicate(
diff --git a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.ts b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.ts
index 30ff45f..4056688 100644
--- a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.ts
+++ b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.ts
@@ -17,7 +17,7 @@
 import '@polymer/iron-selector/iron-selector';
 import '../../shared/gr-button/gr-button';
 import {sharedStyles} from '../../../styles/shared-styles';
-import {css, html, nothing, LitElement} from 'lit';
+import {css, html, LitElement} from 'lit';
 import {customElement, property, query, state} from 'lit/decorators';
 import {ifDefined} from 'lit/directives/if-defined';
 import {IronSelectorElement} from '@polymer/iron-selector/iron-selector';
@@ -193,11 +193,6 @@
       <div class="buttonsCell">
         ${this.renderBlankItems('start')} ${this.renderLabelSelector()}
         ${this.renderBlankItems('end')}
-        ${!this._computeAnyPermittedLabelValues()
-          ? html` <span class="labelMessage">
-              You don't have permission to edit this label.
-            </span>`
-          : nothing}
       </div>
     `;
   }
@@ -220,7 +215,6 @@
       <iron-selector
         id="labelSelector"
         .attrForSelected=${'data-value'}
-        ?hidden="${!this._computeAnyPermittedLabelValues()}"
         selected="${ifDefined(this._computeLabelValue())}"
         @selected-item-changed=${this.setSelectedValueText}
         role="radiogroup"
@@ -266,7 +260,6 @@
       <div
         class="${classMap({
           selectedValueCell: true,
-          hidden: !this._computeAnyPermittedLabelValues(),
           newSubmitRequirements: this.isSubmitRequirementsUiEnabled,
         })}"
       >
@@ -418,15 +411,6 @@
     );
   };
 
-  _computeAnyPermittedLabelValues() {
-    return (
-      this.permittedLabels &&
-      this.label &&
-      hasOwnProperty(this.permittedLabels, this.label.name) &&
-      this.permittedLabels[this.label.name].length
-    );
-  }
-
   private computePermittedLabelValues() {
     if (!this.permittedLabels || !this.label) {
       return [];
diff --git a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.ts b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.ts
index 7e63010..24d4f9b 100644
--- a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.ts
@@ -238,25 +238,6 @@
     checkAriaCheckedValid();
   });
 
-  test('without permitted labels', async () => {
-    element.permittedLabels = {
-      Verified: ['-1', ' 0', '+1'],
-    };
-    await element.updateComplete;
-    assert.isOk(element.labelSelector);
-    assert.isFalse(element.labelSelector!.hidden);
-
-    element.permittedLabels = {};
-    await element.updateComplete;
-    assert.isOk(element.labelSelector);
-    assert.isTrue(element.labelSelector!.hidden);
-
-    element.permittedLabels = {Verified: []};
-    await element.updateComplete;
-    assert.isOk(element.labelSelector);
-    assert.isTrue(element.labelSelector!.hidden);
-  });
-
   test('asymmetrical labels', async () => {
     element.permittedLabels = {
       'Code-Review': ['-2', '-1', ' 0', '+1', '+2'],