Submit requirements - Trigger votes

Trigger votes are votes that are not associated
with submit requirements.This change is creating a chip
with label name and vote.

Screenshot: https://imgur.com/a/oA1QoNd
Google-Bug-Id: b/202289702
Change-Id: Ia8d73049e630c196b55762ce226504cf6db184b3
diff --git a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_html.ts b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_html.ts
index d115899..dec65e2 100644
--- a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_html.ts
+++ b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_html.ts
@@ -58,6 +58,7 @@
     gr-vote-chip {
       --gr-vote-chip-width: 14px;
       --gr-vote-chip-height: 14px;
+      margin-right: var(--spacing-s);
     }
   </style>
   <div class="container">
diff --git a/polygerrit-ui/app/elements/change/gr-submit-requirements/gr-submit-requirements.ts b/polygerrit-ui/app/elements/change/gr-submit-requirements/gr-submit-requirements.ts
index 19bc388..21e8093 100644
--- a/polygerrit-ui/app/elements/change/gr-submit-requirements/gr-submit-requirements.ts
+++ b/polygerrit-ui/app/elements/change/gr-submit-requirements/gr-submit-requirements.ts
@@ -21,6 +21,7 @@
 import {
   AccountInfo,
   isDetailedLabelInfo,
+  LabelInfo,
   LabelNameToInfoMap,
   SubmitRequirementResultInfo,
   SubmitRequirementStatus,
@@ -28,6 +29,7 @@
 import {unique} from '../../../utils/common-util';
 import {
   extractAssociatedLabels,
+  getAllUniqueApprovals,
   hasVotes,
   iconForStatus,
 } from '../../../utils/label-util';
@@ -92,9 +94,19 @@
           visibility: visible;
         }
         .requirements,
-        section.votes {
+        section.trigger-votes {
           margin-left: var(--spacing-l);
         }
+        .trigger-votes {
+          padding-top: var(--spacing-s);
+          display: flex;
+          flex-wrap: wrap;
+          gap: var(--spacing-s);
+          /* Setting max-width as defined in Submit Requirements design,
+           *  to wrap overflowed items to next row.
+           */
+          max-width: 390px;
+        }
         gr-limited-text.name {
           font-weight: var(--font-weight-bold);
         }
@@ -115,6 +127,9 @@
           color: var(--error-foreground);
           vertical-align: top;
         }
+        gr-vote-chip {
+          margin-right: var(--spacing-s);
+        }
       `,
     ];
   }
@@ -211,12 +226,7 @@
   renderLabelVote(label: string, labels: LabelNameToInfoMap) {
     const labelInfo = labels[label];
     if (!isDetailedLabelInfo(labelInfo)) return;
-    const uniqueApprovals = (labelInfo.all ?? [])
-      .filter(
-        (approvalInfo, index, array) =>
-          index === array.findIndex(other => other.value === approvalInfo.value)
-      )
-      .sort((a, b) => -(a.value ?? 0) + (b.value ?? 0));
+    const uniqueApprovals = getAllUniqueApprovals(labelInfo);
     return uniqueApprovals.map(
       approvalInfo =>
         html`<gr-vote-chip
@@ -262,16 +272,13 @@
       .filter(label => hasVotes(labels[label]));
     if (!triggerVotes.length) return;
     return html`<h3 class="metadata-title heading-3">Trigger Votes</h3>
-      <section class="votes">
+      <section class="trigger-votes">
         ${triggerVotes.map(
-          label => html`${label}:
-            <gr-label-info
-              .change="${this.change}"
-              .account="${this.account}"
-              .mutable="${this.mutable ?? false}"
-              label="${label}"
+          label =>
+            html`<gr-trigger-vote
+              .label="${label}"
               .labelInfo="${labels[label]}"
-            ></gr-label-info>`
+            ></gr-trigger-vote>`
         )}
       </section>`;
   }
@@ -320,8 +327,61 @@
   }
 }
 
+@customElement('gr-trigger-vote')
+export class GrTriggerVote extends LitElement {
+  @property()
+  label?: string;
+
+  @property({type: Object})
+  labelInfo?: LabelInfo;
+
+  static override get styles() {
+    return css`
+      :host {
+        display: block;
+      }
+      .container {
+        box-sizing: border-box;
+        border: 1px solid var(--border-color);
+        border-radius: calc(var(--border-radius) + 2px);
+        background-color: var(--background-color-primary);
+        display: flex;
+        padding: 0;
+        padding-left: var(--spacing-s);
+        padding-right: var(--spacing-xxs);
+        align-items: center;
+      }
+      .label {
+        padding-right: var(--spacing-s);
+        font-weight: var(--font-weight-bold);
+      }
+      gr-vote-chip {
+        --gr-vote-chip-width: 14px;
+        --gr-vote-chip-height: 14px;
+        margin-right: 0px;
+      }
+    `;
+  }
+
+  override render() {
+    const uniqueApprovals = getAllUniqueApprovals(this.labelInfo);
+    return html`
+      <div class="container">
+        <span class="label">${this.label}</span>
+        ${uniqueApprovals.map(
+          approvalInfo => html`<gr-vote-chip
+            .vote="${approvalInfo}"
+            .label="${this.labelInfo}"
+          ></gr-vote-chip>`
+        )}
+      </div>
+    `;
+  }
+}
+
 declare global {
   interface HTMLElementTagNameMap {
     'gr-submit-requirements': GrSubmitRequirements;
+    'gr-trigger-vote': GrTriggerVote;
   }
 }
diff --git a/polygerrit-ui/app/elements/shared/gr-vote-chip/gr-vote-chip.ts b/polygerrit-ui/app/elements/shared/gr-vote-chip/gr-vote-chip.ts
index 2fd3fb9..3762d8d 100644
--- a/polygerrit-ui/app/elements/shared/gr-vote-chip/gr-vote-chip.ts
+++ b/polygerrit-ui/app/elements/shared/gr-vote-chip/gr-vote-chip.ts
@@ -83,8 +83,8 @@
           display: flex;
           width: var(--gr-vote-chip-width, 16px);
           height: var(--gr-vote-chip-height, 16px);
+          font-size: var(--font-size-small);
           justify-content: center;
-          margin-right: var(--spacing-s);
           padding: 1px;
           border-radius: var(--border-radius);
           line-height: var(--gr-vote-chip-width, 16px);
diff --git a/polygerrit-ui/app/utils/label-util.ts b/polygerrit-ui/app/utils/label-util.ts
index cde9a45..884afd7 100644
--- a/polygerrit-ui/app/utils/label-util.ts
+++ b/polygerrit-ui/app/utils/label-util.ts
@@ -122,6 +122,17 @@
   return label.all?.filter(x => x._account_id === account._account_id)[0];
 }
 
+export function getAllUniqueApprovals(labelInfo?: LabelInfo) {
+  if (!labelInfo || !isDetailedLabelInfo(labelInfo)) return [];
+  const uniqueApprovals = (labelInfo.all ?? [])
+    .filter(
+      (approvalInfo, index, array) =>
+        index === array.findIndex(other => other.value === approvalInfo.value)
+    )
+    .sort((a, b) => -(a.value ?? 0) + (b.value ?? 0));
+  return uniqueApprovals;
+}
+
 export function hasVotes(labelInfo: LabelInfo): boolean {
   if (isDetailedLabelInfo(labelInfo)) {
     return (labelInfo.all ?? []).some(