Sort Code-Review label always to the top

Change-Id: Iaa768ffd6f331e064cdede141726ea2f387d6bee
diff --git a/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.ts b/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.ts
index c0e87f3..adc7fd3 100644
--- a/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.ts
@@ -37,6 +37,7 @@
 import {PolymerDeepPropertyChange} from '@polymer/polymer/interfaces';
 import {appContext} from '../../../services/app-context';
 import {KnownExperimentId} from '../../../services/flags/flags';
+import {labelCompare} from '../../../utils/label-util';
 
 interface ChangeRequirement extends Requirement {
   satisfied: boolean;
@@ -136,7 +137,7 @@
     const labels = labelsRecord.base || {};
     const allLabels: Label[] = [];
 
-    for (const label of Object.keys(labels).sort()) {
+    for (const label of Object.keys(labels).sort(labelCompare)) {
       allLabels.push({
         labelName: label,
         icon: this._computeLabelIcon(labels[label]),
diff --git a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.ts b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.ts
index a966186..661cd1a 100644
--- a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.ts
+++ b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.ts
@@ -37,6 +37,7 @@
 } from '../gr-label-score-row/gr-label-score-row';
 import {PolymerDeepPropertyChange} from '@polymer/polymer/interfaces';
 import {appContext} from '../../../services/app-context';
+import {labelCompare} from '../../../utils/label-util';
 
 @customElement('gr-label-scores')
 export class GrLabelScores extends GestureEventListeners(
@@ -147,7 +148,7 @@
     if (!labelRecord?.base) return [];
     const labelsObj = labelRecord.base;
     return Object.keys(labelsObj)
-      .sort()
+      .sort(labelCompare)
       .map(key => {
         return {
           name: key,
diff --git a/polygerrit-ui/app/utils/label-util.ts b/polygerrit-ui/app/utils/label-util.ts
index 60ac4d8..4eed0a0 100644
--- a/polygerrit-ui/app/utils/label-util.ts
+++ b/polygerrit-ui/app/utils/label-util.ts
@@ -51,3 +51,11 @@
 ): ApprovalInfo | undefined {
   return label.all?.filter(x => x._account_id === account._account_id)[0];
 }
+
+export function labelCompare(labelName1: string, labelName2: string) {
+  if (labelName1 === CODE_REVIEW && labelName2 === CODE_REVIEW) return 0;
+  if (labelName1 === CODE_REVIEW) return -1;
+  if (labelName2 === CODE_REVIEW) return 1;
+
+  return labelName1.localeCompare(labelName2);
+}
diff --git a/polygerrit-ui/app/utils/label-util_test.js b/polygerrit-ui/app/utils/label-util_test.js
index 6a2f768..f9a30df 100644
--- a/polygerrit-ui/app/utils/label-util_test.js
+++ b/polygerrit-ui/app/utils/label-util_test.js
@@ -21,6 +21,7 @@
   getVotingRangeOrDefault,
   getMaxAccounts,
   getApprovalInfo,
+  labelCompare,
 } from './label-util.js';
 
 const VALUES_1 = {
@@ -113,4 +114,11 @@
     };
     assert.isUndefined(getApprovalInfo(label, myAccountInfo));
   });
+
+  test('labelCompare', () => {
+    let sorted = ['c', 'b', 'a'].sort(labelCompare);
+    assert.sameOrderedMembers(sorted, ['a', 'b', 'c']);
+    sorted = ['b', 'a', 'Code-Review'].sort(labelCompare);
+    assert.sameOrderedMembers(sorted, ['Code-Review', 'a', 'b']);
+  });
 });