| /** |
| * @license |
| * Copyright 2021 Google LLC |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| import '../../shared/gr-label-info/gr-label-info'; |
| import '../../shared/gr-vote-chip/gr-vote-chip'; |
| import '../gr-trigger-vote-hovercard/gr-trigger-vote-hovercard'; |
| import {LitElement, css, html} from 'lit'; |
| import {customElement, property} from 'lit/decorators.js'; |
| import {ParsedChangeInfo} from '../../../types/types'; |
| import { |
| AccountInfo, |
| isDetailedLabelInfo, |
| isQuickLabelInfo, |
| LabelInfo, |
| } from '../../../api/rest-api'; |
| import { |
| getAllUniqueApprovals, |
| hasNeutralStatus, |
| } from '../../../utils/label-util'; |
| |
| @customElement('gr-trigger-vote') |
| export class GrTriggerVote extends LitElement { |
| @property() |
| label?: string; |
| |
| @property({type: Object}) |
| labelInfo?: LabelInfo; |
| |
| @property({type: Object}) |
| change?: ParsedChangeInfo; |
| |
| @property({type: Object}) |
| account?: AccountInfo; |
| |
| /** |
| * If defined, trigger-vote is shown with this value instead of the latest |
| * vote. This is useful for change log. |
| */ |
| @property() |
| displayValue?: string; |
| |
| @property({type: Boolean}) |
| mutable?: boolean; |
| |
| @property({type: Boolean, attribute: 'disable-hovercards'}) |
| disableHovercards = false; |
| |
| 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; |
| margin-left: var(--spacing-xs); |
| } |
| gr-vote-chip:first-of-type { |
| margin-left: 0px; |
| } |
| `; |
| } |
| |
| override render() { |
| if (!this.labelInfo) return; |
| return html` |
| <div class="container"> |
| ${this.renderHovercard()} |
| <span class="label">${this.label}</span> |
| ${this.renderVotes()} |
| </div> |
| `; |
| } |
| |
| private renderHovercard() { |
| if (this.disableHovercards) return; |
| return html`<gr-trigger-vote-hovercard |
| .labelName=${this.label} |
| .labelInfo=${this.labelInfo} |
| > |
| <gr-label-info |
| slot="label-info" |
| .change=${this.change} |
| .account=${this.account} |
| .mutable=${this.mutable} |
| .label=${this.label} |
| .labelInfo=${this.labelInfo} |
| .showAllReviewers=${false} |
| ></gr-label-info> |
| </gr-trigger-vote-hovercard>`; |
| } |
| |
| private renderVotes() { |
| const {labelInfo} = this; |
| if (!labelInfo) return; |
| if (this.displayValue) |
| return html`<gr-vote-chip |
| .displayValue=${this.displayValue} |
| .label=${labelInfo} |
| ></gr-vote-chip>`; |
| if (isDetailedLabelInfo(labelInfo)) { |
| const approvals = getAllUniqueApprovals(labelInfo).filter( |
| approval => !hasNeutralStatus(labelInfo, approval) |
| ); |
| return approvals.map( |
| approvalInfo => html`<gr-vote-chip |
| .vote=${approvalInfo} |
| .label=${labelInfo} |
| ></gr-vote-chip>` |
| ); |
| } else if (isQuickLabelInfo(labelInfo)) { |
| return [html`<gr-vote-chip .label=${this.labelInfo}></gr-vote-chip>`]; |
| } else { |
| return html``; |
| } |
| } |
| } |
| |
| declare global { |
| interface HTMLElementTagNameMap { |
| 'gr-trigger-vote': GrTriggerVote; |
| } |
| } |