| /** | 
 |  * @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 {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners'; | 
 | import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin'; | 
 | 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 {hasOwnProperty} from '../../../utils/common-util'; | 
 | import {PolymerDeepPropertyChange} from '@polymer/polymer/interfaces'; | 
 |  | 
 | interface ChangeRequirement extends Requirement { | 
 |   satisfied: boolean; | 
 |   style: string; | 
 | } | 
 |  | 
 | interface ChangeWIP { | 
 |   type: RequirementType; | 
 |   fallback_text: string; | 
 |   tooltip: string; | 
 | } | 
 |  | 
 | interface Label { | 
 |   labelInfo: LabelInfo; | 
 |   icon: string; | 
 |   style: string; | 
 | } | 
 |  | 
 | @customElement('gr-change-requirements') | 
 | class GrChangeRequirements extends GestureEventListeners( | 
 |   LegacyElementMixin(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; | 
 |  | 
 |   _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; | 
 |     this._optionalLabels = []; | 
 |     this._requiredLabels = []; | 
 |  | 
 |     for (const label of Object.keys(labels || {}).sort()) { | 
 |       if (!hasOwnProperty(labels, label)) { | 
 |         continue; | 
 |       } | 
 |  | 
 |       const labelInfo = labels[label]; | 
 |       const icon = this._computeLabelIcon(labelInfo); | 
 |       const style = this._computeLabelClass(labelInfo); | 
 |       const path = labelInfo.optional ? '_optionalLabels' : '_requiredLabels'; | 
 |  | 
 |       this.push(path, {label, icon, style, labelInfo}); | 
 |     } | 
 |   } | 
 |  | 
 |   /** | 
 |    * @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}`; | 
 |   } | 
 |  | 
 |   _computeShowHideIcon(showOptionalLabels: boolean) { | 
 |     return showOptionalLabels ? 'gr-icons:expand-less' : 'gr-icons:expand-more'; | 
 |   } | 
 |  | 
 |   _computeSectionClass(show: boolean) { | 
 |     return show ? '' : 'hidden'; | 
 |   } | 
 |  | 
 |   _handleShowHide() { | 
 |     this._showOptionalLabels = !this._showOptionalLabels; | 
 |   } | 
 |  | 
 |   _computeSubmitRequirementEndpoint(item: ChangeRequirement | ChangeWIP) { | 
 |     return `submit-requirement-item-${item.type}`; | 
 |   } | 
 | } | 
 |  | 
 | declare global { | 
 |   interface HTMLElementTagNameMap { | 
 |     'gr-change-requirements': GrChangeRequirements; | 
 |   } | 
 | } |