|  | /** | 
|  | * @license | 
|  | * Copyright (C) 2018 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | * http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  | import '../../../styles/shared-styles'; | 
|  | import '../../shared/gr-button/gr-button'; | 
|  | import '../../shared/gr-icons/gr-icons'; | 
|  | import '../../shared/gr-label/gr-label'; | 
|  | import '../../shared/gr-label-info/gr-label-info'; | 
|  | import '../../shared/gr-limited-text/gr-limited-text'; | 
|  | import {PolymerElement} from '@polymer/polymer/polymer-element'; | 
|  | import {htmlTemplate} from './gr-change-requirements_html'; | 
|  | import {customElement, property, observe} from '@polymer/decorators'; | 
|  | import { | 
|  | ChangeInfo, | 
|  | AccountInfo, | 
|  | QuickLabelInfo, | 
|  | Requirement, | 
|  | RequirementType, | 
|  | LabelNameToInfoMap, | 
|  | LabelInfo, | 
|  | } from '../../../types/common'; | 
|  | import {PolymerDeepPropertyChange} from '@polymer/polymer/interfaces'; | 
|  | import {appContext} from '../../../services/app-context'; | 
|  | import {labelCompare} from '../../../utils/label-util'; | 
|  |  | 
|  | interface ChangeRequirement extends Requirement { | 
|  | satisfied: boolean; | 
|  | style: string; | 
|  | } | 
|  |  | 
|  | interface ChangeWIP { | 
|  | type: RequirementType; | 
|  | fallback_text: string; | 
|  | tooltip: string; | 
|  | } | 
|  |  | 
|  | interface Label { | 
|  | labelName: string; | 
|  | labelInfo: LabelInfo; | 
|  | icon: string; | 
|  | style: string; | 
|  | } | 
|  |  | 
|  | @customElement('gr-change-requirements') | 
|  | class GrChangeRequirements extends PolymerElement { | 
|  | static get template() { | 
|  | return htmlTemplate; | 
|  | } | 
|  |  | 
|  | @property({type: Object}) | 
|  | change?: ChangeInfo; | 
|  |  | 
|  | @property({type: Object}) | 
|  | account?: AccountInfo; | 
|  |  | 
|  | @property({type: Boolean}) | 
|  | mutable?: boolean; | 
|  |  | 
|  | @property({type: Array, computed: '_computeRequirements(change)'}) | 
|  | _requirements?: Array<ChangeRequirement | ChangeWIP>; | 
|  |  | 
|  | @property({type: Array}) | 
|  | _requiredLabels: Label[] = []; | 
|  |  | 
|  | @property({type: Array}) | 
|  | _optionalLabels: Label[] = []; | 
|  |  | 
|  | @property({type: Boolean, computed: '_computeShowWip(change)'}) | 
|  | _showWip?: boolean; | 
|  |  | 
|  | @property({type: Boolean}) | 
|  | _showOptionalLabels = true; | 
|  |  | 
|  | private readonly reporting = appContext.reportingService; | 
|  |  | 
|  | _computeShowWip(change: ChangeInfo) { | 
|  | return change.work_in_progress; | 
|  | } | 
|  |  | 
|  | _computeRequirements(change: ChangeInfo) { | 
|  | const _requirements: Array<ChangeRequirement | ChangeWIP> = []; | 
|  |  | 
|  | if (change.requirements) { | 
|  | for (const requirement of change.requirements) { | 
|  | const satisfied = requirement.status === 'OK'; | 
|  | const style = this._computeRequirementClass(satisfied); | 
|  | _requirements.push({...requirement, satisfied, style}); | 
|  | } | 
|  | } | 
|  | if (change.work_in_progress) { | 
|  | _requirements.push({ | 
|  | type: 'wip' as RequirementType, | 
|  | fallback_text: 'Work-in-progress', | 
|  | tooltip: "Change must not be in 'Work in Progress' state.", | 
|  | }); | 
|  | } | 
|  |  | 
|  | return _requirements; | 
|  | } | 
|  |  | 
|  | _computeRequirementClass(requirementStatus: boolean) { | 
|  | return requirementStatus ? 'approved' : ''; | 
|  | } | 
|  |  | 
|  | _computeRequirementIcon(requirementStatus: boolean) { | 
|  | return requirementStatus ? 'gr-icons:check' : 'gr-icons:schedule'; | 
|  | } | 
|  |  | 
|  | @observe('change.labels.*') | 
|  | _computeLabels( | 
|  | labelsRecord: PolymerDeepPropertyChange< | 
|  | LabelNameToInfoMap, | 
|  | LabelNameToInfoMap | 
|  | > | 
|  | ) { | 
|  | const labels = labelsRecord.base || {}; | 
|  | const allLabels: Label[] = []; | 
|  |  | 
|  | for (const label of Object.keys(labels).sort(labelCompare)) { | 
|  | allLabels.push({ | 
|  | labelName: label, | 
|  | icon: this._computeLabelIcon(labels[label]), | 
|  | style: this._computeLabelClass(labels[label]), | 
|  | labelInfo: labels[label], | 
|  | }); | 
|  | } | 
|  | this._optionalLabels = allLabels.filter(label => label.labelInfo.optional); | 
|  | this._requiredLabels = allLabels.filter(label => !label.labelInfo.optional); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @return The icon name, or undefined if no icon should | 
|  | * be used. | 
|  | */ | 
|  | _computeLabelIcon(labelInfo: QuickLabelInfo) { | 
|  | if (labelInfo.approved) { | 
|  | return 'gr-icons:check'; | 
|  | } | 
|  | if (labelInfo.rejected) { | 
|  | return 'gr-icons:close'; | 
|  | } | 
|  | return 'gr-icons:schedule'; | 
|  | } | 
|  |  | 
|  | _computeLabelClass(labelInfo: QuickLabelInfo) { | 
|  | if (labelInfo.approved) { | 
|  | return 'approved'; | 
|  | } | 
|  | if (labelInfo.rejected) { | 
|  | return 'rejected'; | 
|  | } | 
|  | return ''; | 
|  | } | 
|  |  | 
|  | _computeShowOptional( | 
|  | optionalFieldsRecord: PolymerDeepPropertyChange<Label[], Label[]> | 
|  | ) { | 
|  | return optionalFieldsRecord.base.length ? '' : 'hidden'; | 
|  | } | 
|  |  | 
|  | _computeLabelValue(value: number) { | 
|  | return `${value > 0 ? '+' : ''}${value}`; | 
|  | } | 
|  |  | 
|  | _computeSectionClass(show: boolean) { | 
|  | return show ? '' : 'hidden'; | 
|  | } | 
|  |  | 
|  | _handleShowHide() { | 
|  | this._showOptionalLabels = !this._showOptionalLabels; | 
|  | this.reporting.reportInteraction('toggle show all button', { | 
|  | sectionName: 'optional labels', | 
|  | toState: this._showOptionalLabels ? 'Show all' : 'Show less', | 
|  | }); | 
|  | } | 
|  |  | 
|  | _computeSubmitRequirementEndpoint(item: ChangeRequirement | ChangeWIP) { | 
|  | return `submit-requirement-item-${item.type}`; | 
|  | } | 
|  |  | 
|  | _computeShowAllLabelText(_showOptionalLabels: boolean) { | 
|  | if (_showOptionalLabels) { | 
|  | return 'Show less'; | 
|  | } else { | 
|  | return 'Show all'; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | declare global { | 
|  | interface HTMLElementTagNameMap { | 
|  | 'gr-change-requirements': GrChangeRequirements; | 
|  | } | 
|  | } |