+ Add bottom border on the header. + Fix issue with the first related change section having a top margin which would cause it to be misaligned with the other columns. + Clean up CSS a bit around the columns by adding a changeInfo-column class. Change-Id: I0fd76647c58b57126ca45c3404f3910e76918aa6
		
			
				
	
	
		
			364 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			364 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!--
 | 
						|
Copyright (C) 2016 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="../behaviors/rest-client-behavior.html">
 | 
						|
<link rel="import" href="gr-ajax.html">
 | 
						|
 | 
						|
<dom-module id="gr-related-changes-list">
 | 
						|
  <template>
 | 
						|
    <style>
 | 
						|
      :host {
 | 
						|
        display: block;
 | 
						|
      }
 | 
						|
      h3 {
 | 
						|
        margin: .5em 0 0;
 | 
						|
      }
 | 
						|
      section {
 | 
						|
        margin-bottom: 1em;
 | 
						|
      }
 | 
						|
      a {
 | 
						|
        display: block;
 | 
						|
      }
 | 
						|
      .relatedChanges a {
 | 
						|
        display: inline-block;
 | 
						|
      }
 | 
						|
      .strikethrough {
 | 
						|
        color: #666;
 | 
						|
        text-decoration: line-through;
 | 
						|
      }
 | 
						|
      .status {
 | 
						|
        color: #666;
 | 
						|
        font-weight: bold;
 | 
						|
      }
 | 
						|
      .notCurrent {
 | 
						|
        color: #e65100;
 | 
						|
      }
 | 
						|
      .indirectAncestor {
 | 
						|
        color: #33691e;
 | 
						|
      }
 | 
						|
      .submittable {
 | 
						|
        color: #1b5e20;
 | 
						|
      }
 | 
						|
      .hidden {
 | 
						|
        display: none;
 | 
						|
      }
 | 
						|
    </style>
 | 
						|
    <gr-ajax id="relatedXHR"
 | 
						|
        url="[[_computeRelatedURL(change._number, patchNum)]]"
 | 
						|
        last-response="{{_relatedResponse}}"></gr-ajax>
 | 
						|
    <gr-ajax id="submittedTogetherXHR"
 | 
						|
        url="[[_computeSubmittedTogetherURL(change._number)]]"
 | 
						|
        last-response="{{_submittedTogether}}"></gr-ajax>
 | 
						|
    <gr-ajax id="conflictsXHR"
 | 
						|
        url="/changes/"
 | 
						|
        params="[[_computeConflictsQueryParams(change._number)]]"
 | 
						|
        last-response="{{_conflicts}}"></gr-ajax>
 | 
						|
    <gr-ajax id="cherryPicksXHR"
 | 
						|
        url="/changes/"
 | 
						|
        params="[[_computeCherryPicksQueryParams(change.project, change.change_id, change._number)]]"
 | 
						|
        last-response="{{_cherryPicks}}"></gr-ajax>
 | 
						|
    <gr-ajax id="sameTopicXHR"
 | 
						|
        url="/changes/"
 | 
						|
        params="[[_computeSameTopicQueryParams(change.topic)]]"
 | 
						|
        last-response="{{_sameTopic}}"></gr-ajax>
 | 
						|
 | 
						|
    <div hidden$="[[!_loading]]">Loading...</div>
 | 
						|
    <section class="relatedChanges" hidden$="[[!_relatedResponse.changes.length]]" hidden>
 | 
						|
      <h4>Relation Chain</h4>
 | 
						|
      <template is="dom-repeat" items="[[_relatedResponse.changes]]" as="change">
 | 
						|
        <div>
 | 
						|
          <a href$="[[_computeChangeURL(change._change_number, change._revision_number)]]"
 | 
						|
              class$="[[_computeLinkClass(change)]]">
 | 
						|
            [[change.commit.subject]]
 | 
						|
          </a>
 | 
						|
          <span class$="[[_computeChangeStatusClass(change)]]">
 | 
						|
            ([[_computeChangeStatus(change)]])
 | 
						|
          </span>
 | 
						|
        </div>
 | 
						|
      </template>
 | 
						|
    </section>
 | 
						|
    <section hidden$="[[!_submittedTogether.length]]" hidden>
 | 
						|
      <h4>Submitted together</h4>
 | 
						|
      <template is="dom-repeat" items="[[_submittedTogether]]" as="change">
 | 
						|
        <a href$="[[_computeChangeURL(change._number)]]"
 | 
						|
            class$="[[_computeLinkClass(change)]]">
 | 
						|
          [[change.project]]: [[change.branch]]: [[change.subject]]
 | 
						|
        </a>
 | 
						|
      </template>
 | 
						|
    </section>
 | 
						|
    <section hidden$="[[!_sameTopic.length]]" hidden>
 | 
						|
      <h4>Same topic</h4>
 | 
						|
      <template is="dom-repeat" items="[[_sameTopic]]" as="change">
 | 
						|
        <a href$="[[_computeChangeURL(change._number)]]"
 | 
						|
            class$="[[_computeLinkClass(change)]]">
 | 
						|
          [[change.project]]: [[change.branch]]: [[change.subject]]
 | 
						|
        </a>
 | 
						|
      </template>
 | 
						|
    </section>
 | 
						|
    <section hidden$="[[!_conflicts.length]]" hidden>
 | 
						|
      <h4>Merge conflicts</h4>
 | 
						|
      <template is="dom-repeat" items="[[_conflicts]]" as="change">
 | 
						|
        <a href$="[[_computeChangeURL(change._number)]]"
 | 
						|
            class$="[[_computeLinkClass(change)]]">
 | 
						|
          [[change.subject]]
 | 
						|
        </a>
 | 
						|
      </template>
 | 
						|
    </section>
 | 
						|
    <section hidden$="[[!_cherryPicks.length]]" hidden>
 | 
						|
      <h4>Cherry picks</h4>
 | 
						|
      <template is="dom-repeat" items="[[_cherryPicks]]" as="change">
 | 
						|
        <a href$="[[_computeChangeURL(change._number)]]"
 | 
						|
            class$="[[_computeLinkClass(change)]]">
 | 
						|
          [[change.subject]]
 | 
						|
        </a>
 | 
						|
      </template>
 | 
						|
    </section>
 | 
						|
  </template>
 | 
						|
  <script>
 | 
						|
  (function() {
 | 
						|
    'use strict';
 | 
						|
 | 
						|
    Polymer({
 | 
						|
      is: 'gr-related-changes-list',
 | 
						|
 | 
						|
      properties: {
 | 
						|
        change: Object,
 | 
						|
        patchNum: String,
 | 
						|
        serverConfig: {
 | 
						|
          type: Object,
 | 
						|
          observer: '_serverConfigChanged',
 | 
						|
        },
 | 
						|
        hidden: {
 | 
						|
          type: Boolean,
 | 
						|
          value: false,
 | 
						|
          reflectToAttribute: true,
 | 
						|
        },
 | 
						|
 | 
						|
        _loading: Boolean,
 | 
						|
        _resolveServerConfigReady: Function,
 | 
						|
        _serverConfigReady: {
 | 
						|
          type: Object,
 | 
						|
          value: function() {
 | 
						|
            return new Promise(function(resolve) {
 | 
						|
              this._resolveServerConfigReady = resolve;
 | 
						|
            }.bind(this));
 | 
						|
          }
 | 
						|
        },
 | 
						|
        _connectedRevisions: {
 | 
						|
          type: Array,
 | 
						|
          computed: '_computeConnectedRevisions(change, patchNum, ' +
 | 
						|
              '_relatedResponse.changes)',
 | 
						|
        },
 | 
						|
        _relatedResponse: Object,
 | 
						|
        _submittedTogether: Array,
 | 
						|
        _conflicts: Array,
 | 
						|
        _cherryPicks: Array,
 | 
						|
        _sameTopic: Array,
 | 
						|
      },
 | 
						|
 | 
						|
      behaviors: [
 | 
						|
        Gerrit.RESTClientBehavior,
 | 
						|
      ],
 | 
						|
 | 
						|
      observers: [
 | 
						|
        '_resultsChanged(_relatedResponse.changes, _submittedTogether, ' +
 | 
						|
            '_conflicts, _cherryPicks, _sameTopic)',
 | 
						|
      ],
 | 
						|
 | 
						|
      reload: function() {
 | 
						|
        if (!this.change || !this.patchNum) {
 | 
						|
          return Promise.resolve();
 | 
						|
        }
 | 
						|
        this._loading = true;
 | 
						|
        var promises = [
 | 
						|
          this.$.relatedXHR.generateRequest().completes,
 | 
						|
          this.$.submittedTogetherXHR.generateRequest().completes,
 | 
						|
          this.$.conflictsXHR.generateRequest().completes,
 | 
						|
          this.$.cherryPicksXHR.generateRequest().completes,
 | 
						|
        ];
 | 
						|
 | 
						|
        return this._serverConfigReady.then(function() {
 | 
						|
          if (this.change.topic &&
 | 
						|
              !this.serverConfig.change.submit_whole_topic) {
 | 
						|
            return this.$.sameTopicXHR.generateRequest().completes;
 | 
						|
          } else {
 | 
						|
            this._sameTopic = [];
 | 
						|
          }
 | 
						|
          return Promise.resolve();
 | 
						|
        }.bind(this)).then(Promise.all(promises)).then(function() {
 | 
						|
          this._loading = false;
 | 
						|
        }.bind(this));
 | 
						|
      },
 | 
						|
 | 
						|
      _computeRelatedURL: function(changeNum, patchNum) {
 | 
						|
        return this.changeBaseURL(changeNum, patchNum) + '/related';
 | 
						|
      },
 | 
						|
 | 
						|
      _computeSubmittedTogetherURL: function(changeNum) {
 | 
						|
        return this.changeBaseURL(changeNum) + '/submitted_together';
 | 
						|
      },
 | 
						|
 | 
						|
      _computeConflictsQueryParams: function(changeNum) {
 | 
						|
        var options = this.listChangesOptionsToHex(
 | 
						|
            this.ListChangesOption.CURRENT_REVISION,
 | 
						|
            this.ListChangesOption.CURRENT_COMMIT
 | 
						|
        );
 | 
						|
        return {
 | 
						|
          O: options,
 | 
						|
          q: 'status:open is:mergeable conflicts:' + changeNum,
 | 
						|
        };
 | 
						|
      },
 | 
						|
 | 
						|
      _computeCherryPicksQueryParams: function(project, changeID, changeNum) {
 | 
						|
        var options = this.listChangesOptionsToHex(
 | 
						|
            this.ListChangesOption.CURRENT_REVISION,
 | 
						|
            this.ListChangesOption.CURRENT_COMMIT
 | 
						|
        );
 | 
						|
        var query = [
 | 
						|
          'project:' + project,
 | 
						|
          'change:' + changeID,
 | 
						|
          '-change:' + changeNum,
 | 
						|
          '-is:abandoned',
 | 
						|
        ].join(' ');
 | 
						|
        return {
 | 
						|
          O: options,
 | 
						|
          q: query
 | 
						|
        }
 | 
						|
      },
 | 
						|
 | 
						|
      _computeSameTopicQueryParams: function(topic) {
 | 
						|
        var options = this.listChangesOptionsToHex(
 | 
						|
            this.ListChangesOption.LABELS,
 | 
						|
            this.ListChangesOption.CURRENT_REVISION,
 | 
						|
            this.ListChangesOption.CURRENT_COMMIT,
 | 
						|
            this.ListChangesOption.DETAILED_LABELS
 | 
						|
        );
 | 
						|
        return {
 | 
						|
          O: options,
 | 
						|
          q: 'status:open topic:' + topic,
 | 
						|
        };
 | 
						|
      },
 | 
						|
 | 
						|
      _computeChangeURL: function(changeNum, patchNum) {
 | 
						|
        var urlStr = '/c/' + changeNum;
 | 
						|
        if (patchNum != null) {
 | 
						|
          urlStr += '/' + patchNum;
 | 
						|
        }
 | 
						|
        return urlStr;
 | 
						|
      },
 | 
						|
 | 
						|
      _computeLinkClass: function(change) {
 | 
						|
        if (change.status == this.ChangeStatus.ABANDONED) {
 | 
						|
          return 'strikethrough';
 | 
						|
        }
 | 
						|
      },
 | 
						|
 | 
						|
      _computeChangeStatusClass: function(change) {
 | 
						|
        var classes = ['status'];
 | 
						|
        if (change._revision_number != change._current_revision_number) {
 | 
						|
          classes.push('notCurrent');
 | 
						|
        } else if (this._isIndirectAncestor(change)) {
 | 
						|
          classes.push('indirectAncestor');
 | 
						|
        } else if (change.submittable) {
 | 
						|
          classes.push('submittable');
 | 
						|
        } else if (change.status == this.ChangeStatus.NEW) {
 | 
						|
          classes.push('hidden');
 | 
						|
        }
 | 
						|
        return classes.join(' ');
 | 
						|
      },
 | 
						|
 | 
						|
      _computeChangeStatus: function(change) {
 | 
						|
        switch (change.status) {
 | 
						|
          case this.ChangeStatus.MERGED:
 | 
						|
            return 'Merged';
 | 
						|
          case this.ChangeStatus.ABANDONED:
 | 
						|
            return 'Abandoned';
 | 
						|
          case this.ChangeStatus.DRAFT:
 | 
						|
            return 'Draft';
 | 
						|
        }
 | 
						|
        if (change._revision_number != change._current_revision_number) {
 | 
						|
          return 'Not current';
 | 
						|
        } else if (this._isIndirectAncestor(change)) {
 | 
						|
          return 'Indirect ancestor';
 | 
						|
        } else if (change.submittable) {
 | 
						|
          return 'Submittable';
 | 
						|
        }
 | 
						|
        return ''
 | 
						|
      },
 | 
						|
 | 
						|
      _serverConfigChanged: function(config) {
 | 
						|
        this._resolveServerConfigReady(config);
 | 
						|
      },
 | 
						|
 | 
						|
      _resultsChanged: function(related, submittedTogether, conflicts,
 | 
						|
          cherryPicks, sameTopic) {
 | 
						|
        var results = [
 | 
						|
          related,
 | 
						|
          submittedTogether,
 | 
						|
          conflicts,
 | 
						|
          cherryPicks,
 | 
						|
          sameTopic
 | 
						|
        ];
 | 
						|
        for (var i = 0; i < results.length; i++) {
 | 
						|
          if (results[i].length > 0) {
 | 
						|
            this.hidden = false;
 | 
						|
            return;
 | 
						|
          }
 | 
						|
        }
 | 
						|
        this.hidden = true;
 | 
						|
      },
 | 
						|
 | 
						|
      _isIndirectAncestor: function(change) {
 | 
						|
        return this._connectedRevisions.indexOf(change.commit.commit) == -1;
 | 
						|
      },
 | 
						|
 | 
						|
      _computeConnectedRevisions: function(change, patchNum, relatedChanges) {
 | 
						|
        var connected = [];
 | 
						|
        var changeRevision;
 | 
						|
        for (var rev in change.revisions) {
 | 
						|
          if (change.revisions[rev]._number == patchNum) {
 | 
						|
            changeRevision = rev;
 | 
						|
          }
 | 
						|
        }
 | 
						|
        var commits = relatedChanges.map(function(c) { return c.commit; });
 | 
						|
        var pos = commits.length - 1;
 | 
						|
 | 
						|
        while (pos >= 0) {
 | 
						|
          var commit = commits[pos].commit;
 | 
						|
          connected.push(commit);
 | 
						|
          if (commit == changeRevision) {
 | 
						|
            break;
 | 
						|
          }
 | 
						|
          pos--;
 | 
						|
        }
 | 
						|
        while (pos >= 0) {
 | 
						|
          for (var i = 0; i < commits[pos].parents.length; i++) {
 | 
						|
            if (connected.indexOf(commits[pos].parents[i].commit) != -1) {
 | 
						|
              connected.push(commits[pos].commit);
 | 
						|
              break;
 | 
						|
            }
 | 
						|
          }
 | 
						|
          --pos;
 | 
						|
        }
 | 
						|
        return connected;
 | 
						|
      },
 | 
						|
 | 
						|
    });
 | 
						|
  })();
 | 
						|
  </script>
 | 
						|
</dom-module>
 |