Implement star action
Star action is available on change-list and change-view.
Change-Id: I5c146349515277a02b3e73d1bfe597b43a379c61
diff --git a/polygerrit-ui/app/elements/gr-app.html b/polygerrit-ui/app/elements/gr-app.html
index 585141a..e53b1a5 100644
--- a/polygerrit-ui/app/elements/gr-app.html
+++ b/polygerrit-ui/app/elements/gr-app.html
@@ -105,7 +105,8 @@
</header>
<main>
<template is="dom-if" if="{{_showChangeListView}}" restamp="true">
- <gr-change-list-view params="[[params]]"></gr-change-list-view>
+ <gr-change-list-view params="[[params]]"
+ logged-in="[[_computeLoggedIn(account)]]"></gr-change-list-view>
</template>
<template is="dom-if" if="{{_showDashboardView}}" restamp="true">
<gr-dashboard-view params="[[params]]"></gr-dashboard-view>
@@ -224,6 +225,10 @@
window.location.pathname + window.location.hash));
},
+ _computeLoggedIn: function(account) { // argument used for binding update only
+ return this.loggedIn;
+ },
+
});
})();
</script>
diff --git a/polygerrit-ui/app/elements/gr-change-list-item.html b/polygerrit-ui/app/elements/gr-change-list-item.html
index 46c0513..9c77a06 100644
--- a/polygerrit-ui/app/elements/gr-change-list-item.html
+++ b/polygerrit-ui/app/elements/gr-change-list-item.html
@@ -17,6 +17,7 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../styles/gr-change-list-styles.html">
<link rel="import" href="gr-account-link.html">
+<link rel="import" href="gr-change-star.html">
<link rel="import" href="gr-date-formatter.html">
<dom-module id="gr-change-list-item">
@@ -60,6 +61,9 @@
<span class="cell keyboard">
<span class="positionIndicator">▶</span>
</span>
+ <span class="cell star" hidden$="[[!showStar]]">
+ <gr-change-star change="{{change}}"></gr-change-star>
+ </span>
<a class="cell subject" href$="[[changeURL]]">[[change.subject]]</a>
<span class="cell status">[[_computeChangeStatusString(change)]]</span>
<span class="cell owner">
@@ -94,6 +98,10 @@
type: String,
computed: '_computeChangeURL(change._number)',
},
+ showStar: {
+ type: Boolean,
+ value: false,
+ },
},
_computeChangeURL: function(changeNum) {
diff --git a/polygerrit-ui/app/elements/gr-change-list-view.html b/polygerrit-ui/app/elements/gr-change-list-view.html
index 403d87c..aef69c5 100644
--- a/polygerrit-ui/app/elements/gr-change-list-view.html
+++ b/polygerrit-ui/app/elements/gr-change-list-view.html
@@ -57,8 +57,9 @@
last-response="{{_changes}}"
loading="{{_loading}}"></gr-ajax>
<div class="loading" hidden$="[[!_loading]]">Loading...</div>
- <div hidden$="[[_loading]]" hidden>
- <gr-change-list changes="{{_changes}}"></gr-change-list>
+ <div hidden$="[[_loading]]">
+ <gr-change-list changes="{{_changes}}"
+ show-star="[[loggedIn]]"></gr-change-list>
<nav>
<a href$="[[_computeNavLink(query, offset, -1)]]"
hidden$="[[_hidePrevArrow(offset)]]">← Prev</a>
@@ -86,6 +87,14 @@
},
/**
+ * True when user is logged in.
+ */
+ loggedIn: {
+ type: Boolean,
+ value: false,
+ },
+
+ /**
* Change objects loaded from the server.
*/
_changes: Array,
diff --git a/polygerrit-ui/app/elements/gr-change-list.html b/polygerrit-ui/app/elements/gr-change-list.html
index 1c25d91..fd2b520 100644
--- a/polygerrit-ui/app/elements/gr-change-list.html
+++ b/polygerrit-ui/app/elements/gr-change-list.html
@@ -42,6 +42,7 @@
<style include="gr-change-list-styles"></style>
<div class="headerRow">
<span class="topHeader keyboard"></span> <!-- keyboard position indicator -->
+ <span class="topHeader star" hidden$="[[!showStar]]"></span>
<span class="topHeader subject">Subject</span>
<span class="topHeader status">Status</span>
<span class="topHeader owner">Owner</span>
@@ -57,7 +58,7 @@
<div class="groupHeader">[[_groupTitle(groupIndex)]]</div>
</template>
<template is="dom-repeat" items="[[changeGroup]]" as="change">
- <gr-change-list-item change="[[change]]"></gr-change-list-item>
+ <gr-change-list-item change="[[change]]" show-star="[[showStar]]"></gr-change-list-item>
</template>
</template>
</template>
@@ -100,6 +101,10 @@
value: 0,
observer: '_selectedIndexChanged',
},
+ showStar: {
+ type: Boolean,
+ value: false,
+ },
_boundKeyHandler: {
type: Function,
value: function() { return this._handleKey.bind(this); },
diff --git a/polygerrit-ui/app/elements/gr-change-star.html b/polygerrit-ui/app/elements/gr-change-star.html
new file mode 100644
index 0000000..9311aff
--- /dev/null
+++ b/polygerrit-ui/app/elements/gr-change-star.html
@@ -0,0 +1,88 @@
+<!--
+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-request.html">
+
+<dom-module id="gr-change-star">
+ <template>
+ <style>
+ :host {
+ display: inline;
+ }
+ .starButton {
+ font-size: .95em;
+ margin-right: .25em;
+ cursor: pointer;
+ background-color: transparent;
+ border-color: transparent;
+ }
+ .star {
+ color: #fbc02d;
+ }
+ .unstar {
+ color: #666;
+ }
+ </style>
+ <button class="starButton" on-tap="_handleStarTap">
+ <span class="star" hidden$="[[!change.starred]]">★</span>
+ <span class="unstar" hidden$="[[change.starred]]">☆</span>
+ </button>
+ </template>
+ <script>
+ (function() {
+ 'use strict';
+
+ Polymer({
+ is: 'gr-change-star',
+
+ properties: {
+ change: {
+ type: Object,
+ notify: true,
+ },
+
+ _xhrPromise: Object, // Used for testing.
+ },
+
+ _handleStarTap: function() {
+ var method = this.change.starred ? 'DELETE' : 'PUT';
+ this.set('change.starred', !this.change.starred);
+ this._send(method, this._restEndpoint()).catch(function(err) {
+ this.set('change.starred', !this.change.starred);
+ alert('Change couldn’t be starred. Check the console and contact ' +
+ 'the PolyGerrit team for assistance.');
+ throw err;
+ }.bind(this));
+ },
+
+ _send: function(method, url) {
+ var xhr = document.createElement('gr-request');
+ this._xhrPromise = xhr.send({
+ method: method,
+ url: url,
+ });
+ return this._xhrPromise;
+ },
+
+ _restEndpoint: function() {
+ return '/accounts/self/starred.changes/' + this.change._number;
+ },
+
+ });
+ })();
+ </script>
+</dom-module>
diff --git a/polygerrit-ui/app/elements/gr-change-view.html b/polygerrit-ui/app/elements/gr-change-view.html
index be63e59..1388d8a 100644
--- a/polygerrit-ui/app/elements/gr-change-view.html
+++ b/polygerrit-ui/app/elements/gr-change-view.html
@@ -18,6 +18,7 @@
<link rel="import" href="gr-account-link.html">
<link rel="import" href="gr-ajax.html">
<link rel="import" href="gr-change-actions.html">
+<link rel="import" href="gr-change-star.html">
<link rel="import" href="gr-date-formatter.html">
<link rel="import" href="gr-file-list.html">
<link rel="import" href="gr-linked-text.html">
@@ -149,6 +150,7 @@
<div class="headerContainer">
<div class="header">
<span class="header-title">
+ <gr-change-star change="{{_change}}" hidden$="[[!_loggedIn]]"></gr-change-star>
<a href$="[[_computeChangePath(_change._number)]]">[[_change._number]]</a><span>:</span>
<span>[[_change.subject]]</span>
<span class="changeStatus">[[_computeChangeStatus(_change.status)]]</span>
diff --git a/polygerrit-ui/app/elements/gr-dashboard-view.html b/polygerrit-ui/app/elements/gr-dashboard-view.html
index 88997f6..d04b9f6 100644
--- a/polygerrit-ui/app/elements/gr-dashboard-view.html
+++ b/polygerrit-ui/app/elements/gr-dashboard-view.html
@@ -34,7 +34,7 @@
url="/changes/"
params="[[_computeQueryParams()]]"
last-response="{{_results}}"></gr-ajax>
- <gr-change-list groups="{{_results}}"
+ <gr-change-list groups="{{_results}}" show-star
group-titles="[[_groupTitles]]"></gr-change-list>
</template>
<script>
diff --git a/polygerrit-ui/app/styles/gr-change-list-styles.html b/polygerrit-ui/app/styles/gr-change-list-styles.html
index 0ead9ac..5a96b6c 100644
--- a/polygerrit-ui/app/styles/gr-change-list-styles.html
+++ b/polygerrit-ui/app/styles/gr-change-list-styles.html
@@ -16,7 +16,8 @@
<dom-module id="gr-change-list-styles">
<template>
<style>
- .keyboard {
+ .keyboard,
+ .star {
width: 2em;
}
.subject {
diff --git a/polygerrit-ui/app/test/gr-change-star-test.html b/polygerrit-ui/app/test/gr-change-star-test.html
new file mode 100644
index 0000000..25eacf4
--- /dev/null
+++ b/polygerrit-ui/app/test/gr-change-star-test.html
@@ -0,0 +1,117 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+
+<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+<title>gr-change-star</title>
+
+<script src="../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
+<script src="../../bower_components/web-component-tester/browser.js"></script>
+<script src="../../bower_components/page/page.js"></script>
+<script src="../scripts/fake-app.js"></script>
+<script src="../scripts/util.js"></script>
+
+<link rel="import" href="../../bower_components/iron-test-helpers/iron-test-helpers.html">
+<link rel="import" href="../elements/gr-change-star.html">
+
+<test-fixture id="basic">
+ <template>
+ <gr-change-star></gr-change-star>
+ </template>
+</test-fixture>
+
+<script>
+ suite('gr-change-star tests', function() {
+ var element;
+ var server;
+
+ setup(function() {
+ element = fixture('basic');
+ element.change = {
+ _number: 2,
+ starred: true,
+ };
+
+ server = sinon.fakeServer.create();
+ server.respondWith(
+ 'PUT',
+ '/accounts/self/starred.changes/2',
+ [
+ 204,
+ { 'Content-Type': 'application/json' },
+ ''
+ ]
+ );
+
+ server.respondWith(
+ 'DELETE',
+ '/accounts/self/starred.changes/2',
+ [
+ 204,
+ { 'Content-Type': 'application/json' },
+ ''
+ ]
+ );
+ });
+
+ teardown(function() {
+ server.restore();
+ });
+
+ function isVisible(el) {
+ assert.ok(el);
+ return getComputedStyle(el).getPropertyValue('display') != 'none';
+ }
+
+ test('star visibility states', function() {
+ element.set('change.starred', true);
+ assert.isTrue(isVisible(element.$$('.star')), 'star is visible');
+ assert.isFalse(isVisible(element.$$('.unstar')), 'unstar is not visible');
+
+ element.set('change.starred', false);
+ assert.isTrue(isVisible(element.$$('.unstar')), 'unstar is visible');
+ assert.isFalse(isVisible(element.$$('.star')), 'star is not visible');
+ });
+
+ test('starring', function(done) {
+ element.set('change.starred', false);
+ MockInteractions.tap(element.$$('button'));
+
+ server.respond();
+
+ element._xhrPromise.then(function(req) {
+ assert.equal(req.status, 204);
+ assert.equal(req.url, '/accounts/self/starred.changes/2');
+ assert.equal(element.change.starred, true);
+ done();
+ });
+ });
+
+ test('unstarring', function(done) {
+ element.set('change.starred', true);
+ MockInteractions.tap(element.$$('button'));
+
+ server.respond();
+
+ element._xhrPromise.then(function(req) {
+ assert.equal(req.status, 204);
+ assert.equal(req.url, '/accounts/self/starred.changes/2');
+ assert.equal(element.change.starred, false);
+ done();
+ });
+ });
+ });
+</script>
diff --git a/polygerrit-ui/app/test/index.html b/polygerrit-ui/app/test/index.html
index e415b2e..eff75db 100644
--- a/polygerrit-ui/app/test/index.html
+++ b/polygerrit-ui/app/test/index.html
@@ -29,6 +29,7 @@
'gr-change-actions-test.html',
'gr-change-list-item-test.html',
'gr-change-list-test.html',
+ 'gr-change-star-test.html',
'gr-change-view-test.html',
'gr-date-formatter-test.html',
'gr-diff-comment-test.html',