| <!-- |
| Copyright (C) 2015 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. |
| --> |
| |
| <link rel="import" href="../bower_components/polymer/polymer.html"> |
| <link rel="import" href="gr-date-formatter.html"> |
| |
| <dom-module id="gr-change-list-item"> |
| <template> |
| <style> |
| :host { |
| display: table-row; |
| } |
| :host([selected]) { |
| background-color: #d8EdF9; |
| } |
| th, td { |
| border-bottom: 1px solid #eee; |
| padding: .3em .5em; |
| vertical-align: top; |
| } |
| th { |
| background: #ddd; |
| text-align: left; |
| } |
| a { |
| color: var(--default-text-color); |
| text-decoration: none; |
| } |
| a:hover { |
| text-decoration: underline; |
| } |
| .positionIndicator { |
| visibility: hidden; |
| } |
| :host([selected]) .positionIndicator { |
| visibility: visible; |
| } |
| .avatarImage { |
| border-radius: 50%; |
| height: 1.3em; |
| vertical-align: -.3em; |
| width: 1.3em; |
| } |
| .u-monospace { |
| font-family: 'Source Code Pro'; |
| } |
| .u-green { |
| color: #388E3C; |
| } |
| .u-red { |
| color: #D32F2F; |
| } |
| </style> |
| <template is="dom-if" if="[[header]]"> |
| <th></th> <!-- keyboard position indicator --> |
| <th>Subject</th> |
| <th>Status</th> |
| <th>Owner</th> |
| <th>Project</th> |
| <th>Branch</th> |
| <th>Updated</th> |
| <th>Size</th> |
| <th title="Code-Review">CR</th> |
| <th title="Verified">V</th> |
| </template> |
| <template is="dom-if" if="[[!header]]"> |
| <td> |
| <span class="positionIndicator">▶</span> |
| </td> |
| <td> |
| <a href$="[[changeURL]]">[[change.subject]]</a> |
| </td> |
| <td>[[_computeChangeStatusString(change)]]</td> |
| <td> |
| <img class="avatarImage" src$="[[_computeAvatarURL(change.owner)]]"> |
| <a href$="[[_computeOwnerLink(change.owner.email)]]" |
| title$="[[_computeOwnerTitle(change.owner)]]">[[change.owner.name]]</a> |
| </td> |
| <td> |
| <a href$="[[_computeProjectURL(change.project)]]">[[change.project]]</a> |
| </td> |
| <td> |
| <a href$="[[_computeProjectBranchURL(change.project, change.branch)]]">[[change.branch]]</a> |
| </td> |
| <td><gr-date-formatter date-str="[[change.updated]]"></gr-date-formatter></td> |
| <td class="u-monospace"> |
| <span class="u-green"><span>+</span>[[change.insertions]]</span>, |
| <span class="u-red"><span>-</span>[[change.deletions]]</span> |
| </td> |
| <td title="Code-Review" |
| class$="[[_computeCodeReviewClass(change.labels.Code-Review)]]">[[_computeCodeReviewLabel(change.labels.Code-Review)]]</td> |
| <td title="Verified" class="u-green">[[_computeVerifiedLabel(change.labels.Verified)]]</td> |
| </template> |
| </template> |
| <script> |
| (function() { |
| 'use strict'; |
| |
| Polymer({ |
| is: 'gr-change-list-item', |
| |
| properties: { |
| header: { |
| type: Boolean, |
| reflectToAttribute: true, |
| value: false, |
| }, |
| selected: { |
| type: Boolean, |
| reflectToAttribute: true, |
| }, |
| change: Object, |
| changeURL: { |
| type: String, |
| computed: '_computeChangeURL(change._number)', |
| } |
| }, |
| |
| _computeChangeURL: function(changeNum) { |
| if (!changeNum) { return ''; } |
| return '/c/' + changeNum + '/'; |
| }, |
| |
| _computeChangeStatusString: function(change) { |
| if (!change.mergeable) { |
| return 'Merge Conflict'; |
| } |
| return ''; |
| }, |
| |
| _computeCodeReviewClass: function(codeReview) { |
| if (!codeReview) { return ''; } |
| if (codeReview.approved) { |
| return 'u-green'; |
| } |
| if (codeReview.value == 1) { |
| return 'u-monospace u-green'; |
| } |
| if (codeReview.value == -1) { |
| return 'u-monospace u-red'; |
| } |
| return ''; |
| }, |
| |
| _computeCodeReviewLabel: function(codeReview) { |
| if (!codeReview) { return ''; } |
| if (codeReview.approved) { |
| return '✓'; |
| } |
| if (codeReview.value == 1) { |
| return '+1'; |
| } |
| if (codeReview.value == -1) { |
| return '-1'; |
| } |
| return ''; |
| }, |
| |
| _computeVerifiedLabel: function(verified) { |
| if (verified && verified.approved) { |
| return '✓'; |
| } |
| return '' |
| }, |
| |
| _computeAvatarURL: function(owner) { |
| if (!owner) { return ''; } |
| return '/accounts/' + owner.email + '/avatar?s=32' |
| }, |
| |
| _computeOwnerLink: function(email) { |
| if (!email) { return ''; } |
| return '/q/owner:' + encodeURIComponent(email) + '+status:open'; |
| }, |
| |
| _computeOwnerTitle: function(owner) { |
| if (!owner) { return ''; } |
| // TODO: Is this safe from XSS attacks? |
| return owner.name + ' <' + owner.email + '>'; |
| }, |
| |
| _computeProjectURL: function(project) { |
| return '/projects/' + project + ',dashboards/default'; |
| }, |
| |
| _computeProjectBranchURL: function(project, branch) { |
| return '/q/status:open+project:' + project + '+branch:' + branch; |
| }, |
| |
| }); |
| })(); |
| </script> |
| </dom-module> |