diff --git a/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.js b/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.js deleted file mode 100644 index 8dfee819e3..0000000000 --- a/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.js +++ /dev/null @@ -1,170 +0,0 @@ -/** - * @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.js'; -import '../../shared/gr-button/gr-button.js'; -import '../../shared/gr-icons/gr-icons.js'; -import '../../shared/gr-label/gr-label.js'; -import '../../shared/gr-label-info/gr-label-info.js'; -import '../../shared/gr-limited-text/gr-limited-text.js'; -import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js'; -import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js'; -import {PolymerElement} from '@polymer/polymer/polymer-element.js'; -import {htmlTemplate} from './gr-change-requirements_html.js'; - -/** - * @extends PolymerElement - */ -class GrChangeRequirements extends GestureEventListeners( - LegacyElementMixin(PolymerElement)) { - static get template() { return htmlTemplate; } - - static get is() { return 'gr-change-requirements'; } - - static get properties() { - return { - /** @type {?} */ - change: Object, - account: Object, - mutable: Boolean, - _requirements: { - type: Array, - computed: '_computeRequirements(change)', - }, - _requiredLabels: { - type: Array, - value: () => [], - }, - _optionalLabels: { - type: Array, - value: () => [], - }, - _showWip: { - type: Boolean, - computed: '_computeShowWip(change)', - }, - _showOptionalLabels: { - type: Boolean, - value: true, - }, - }; - } - - static get observers() { - return [ - '_computeLabels(change.labels.*)', - ]; - } - - _computeShowWip(change) { - return change.work_in_progress; - } - - _computeRequirements(change) { - const _requirements = []; - - if (change.requirements) { - for (const requirement of change.requirements) { - requirement.satisfied = requirement.status === 'OK'; - requirement.style = - this._computeRequirementClass(requirement.satisfied); - _requirements.push(requirement); - } - } - if (change.work_in_progress) { - _requirements.push({ - type: 'wip', - fallback_text: 'Work-in-progress', - tooltip: 'Change must not be in \'Work in Progress\' state.', - }); - } - - return _requirements; - } - - _computeRequirementClass(requirementStatus) { - return requirementStatus ? 'approved' : ''; - } - - _computeRequirementIcon(requirementStatus) { - return requirementStatus ? 'gr-icons:check' : 'gr-icons:schedule'; - } - - _computeLabels(labelsRecord) { - const labels = labelsRecord.base; - this._optionalLabels = []; - this._requiredLabels = []; - - for (const label in labels) { - if (!labels.hasOwnProperty(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}); - } - } - - /** - * @param {Object} labelInfo - * @return {string} The icon name, or undefined if no icon should - * be used. - */ - _computeLabelIcon(labelInfo) { - if (labelInfo.approved) { return 'gr-icons:check'; } - if (labelInfo.rejected) { return 'gr-icons:close'; } - return 'gr-icons:schedule'; - } - - /** - * @param {Object} labelInfo - */ - _computeLabelClass(labelInfo) { - if (labelInfo.approved) { return 'approved'; } - if (labelInfo.rejected) { return 'rejected'; } - return ''; - } - - _computeShowOptional(optionalFieldsRecord) { - return optionalFieldsRecord.base.length ? '' : 'hidden'; - } - - _computeLabelValue(value) { - return (value > 0 ? '+' : '') + value; - } - - _computeShowHideIcon(showOptionalLabels) { - return showOptionalLabels ? - 'gr-icons:expand-less' : - 'gr-icons:expand-more'; - } - - _computeSectionClass(show) { - return show ? '' : 'hidden'; - } - - _handleShowHide(e) { - this._showOptionalLabels = !this._showOptionalLabels; - } - - _computeSubmitRequirementEndpoint(item) { - return `submit-requirement-item-${item.type}`; - } -} - -customElements.define(GrChangeRequirements.is, GrChangeRequirements); 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 new file mode 100644 index 0000000000..7a9908631e --- /dev/null +++ b/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.ts @@ -0,0 +1,202 @@ +/** + * @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; + + @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 = []; + + 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 in labels) { + 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 + ) { + 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; + } +}