Merge lp:~cprov/uci-engine/webui-reviews-signoff into lp:uci-engine

Proposed by Celso Providelo
Status: Superseded
Proposed branch: lp:~cprov/uci-engine/webui-reviews-signoff
Merge into: lp:uci-engine
Diff against target: 246 lines (+113/-31)
3 files modified
webui/common/static/common/webui.css (+33/-5)
webui/tickets/static/tickets/webui.js (+78/-24)
webui/tickets/static/tickets/webuiforms.js (+2/-2)
To merge this branch: bzr merge lp:~cprov/uci-engine/webui-reviews-signoff
Reviewer Review Type Date Requested Status
Canonical CI Engineering Pending
Review via email: mp+240918@code.launchpad.net
To post a comment you must log in.
888. By Celso Providelo

Adding 'Review Status' column to the ticket list.

889. By Celso Providelo

typo

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'webui/common/static/common/webui.css'
2--- webui/common/static/common/webui.css 2014-11-06 02:50:14 +0000
3+++ webui/common/static/common/webui.css 2014-11-06 17:15:07 +0000
4@@ -308,26 +308,54 @@
5 font-size: small;
6 font-weight: bold;
7 display: inline-block;
8- width: 6em;
9 }
10
11 .yui3-inlinereview-content label.pending {
12 background-image: url('/static/common/pencil-black.png');
13 }
14
15-.yui3-inlinereview-content label.complete {
16+.yui3-inlinereview-content label.approved {
17 background-image: url('/static/common/check.svg');
18 }
19
20+.yui3-inlinereview-content label.disapproved {
21+ background-image: url('/static/common/cross.svg');
22+}
23+
24+.yui3-inlinereview-content a.pending {
25+ color: black;
26+}
27+
28+.yui3-inlinereview-content a.approved {
29+ color: green;
30+}
31+
32+.yui3-inlinereview-content a.disapproved {
33+ color: red;
34+}
35+
36 .yui3-inlinereview-content button {
37 font-size: small;
38 font-weight: normal;
39+ margin-top: 10px;
40 }
41
42 .yui3-inlinereview-content .error {
43- color: red;
44- font-weight: bold;
45- padding-left: 1em;
46+ color: red;
47+ font-weight: bold;
48+ padding-left: 1em;
49+}
50+
51+.yui3-inlinereview-content div.yui3-overlay-content {
52+ background-color: #FBFBFB;
53+ border: 1px solid #DEDEDE;
54+ -moz-border-radius: 4px;
55+ -webkit-border-radius: 4px;
56+ border-radius: 4px;
57+ -webkit-box-shadow: 0 2px 2px 0 #C2C2C2;
58+ box-shadow: 0 2px 2px 0 #C2C2C2;
59+ padding: 10px;
60+ text-align: left;
61 }
62
63 /* General links decorators. */
64
65=== modified file 'webui/tickets/static/tickets/webui.js'
66--- webui/tickets/static/tickets/webui.js 2014-11-06 02:31:24 +0000
67+++ webui/tickets/static/tickets/webui.js 2014-11-06 17:15:07 +0000
68@@ -8,7 +8,7 @@
69 /**
70 * InlineReview widget.
71 *
72- * Allows reviews to be 'completed' inline via TS JSON-XHR.
73+ * Allows reviews to be edited inline via TS JSON-XHR.
74 *
75 */
76 var InlineReview = function () {
77@@ -23,6 +23,10 @@
78
79 review: {
80 value: {}
81+ },
82+
83+ readonly: {
84+ value: false
85 }
86
87 }
88@@ -32,33 +36,80 @@
89 Y.extend(InlineReview, Y.Widget, {
90
91 renderUI: function() {
92+ var review = this.get('review');
93+
94+ // Empty previous content.
95 this.get('srcNode').empty();
96
97+ // Review label.
98 var label = Y.Node.create('<label>')
99- .set('text', this.get('review').review_type);
100+ .set('text', review.review_type)
101+ .addClass(this.get('review').status.toLowerCase());
102 this.get('srcNode').appendChild(label);
103- if (this.get('review').completed) {
104- label.addClass('complete');
105- return;
106- } else {
107- label.addClass('pending');
108- }
109-
110- var button = Y.Node.create('<button>')
111- .set('text', 'Review');
112- this.get('srcNode').appendChild(button);
113+
114+ // Only render the review label if the widget is readonly.
115+ if (this.get('readonly')) { return; }
116+
117+ // Link that will render the review overlay options.
118+ var overlay_link = Y.Node.create('<a>')
119+ .set('id', 'review-link-' + review.id)
120+ .set('href', '#')
121+ .addClass('edit-link')
122+ .set('title', 'Review');
123+ this.get('srcNode').appendChild(overlay_link);
124+
125+ // Overlay content with review options as links.
126+ var overlay_content = Y.Node.create('<div>')
127+ .set('id', 'review-options-' + review.id)
128+ .addClass('hidden');
129+ var statuses = ['Approved', 'Disapproved', 'Pending'];
130+ statuses.forEach(function (s) {
131+ var choice = Y.Node.create('<a>')
132+ .set('text', s)
133+ .set('href', '#')
134+ .addClass(s.toLowerCase())
135+ .addClass('review-choice')
136+ if (s === review.status) {
137+ choice.addClass('current');
138+ }
139+ overlay_content.appendChild(choice);
140+ overlay_content.appendChild('<hr>');
141+ });
142+ this.get('srcNode').appendChild(overlay_content);
143+
144+ // Overlay widget.
145+ Y.Base.mix(Y.Overlay, [Y.WidgetAutohide]);
146+ var overlay = new Y.Overlay({
147+ srcNode: '#review-options-' + review.id,
148+ align: {
149+ node:'#review-link-' + review.id,
150+ points: [
151+ Y.WidgetPositionAlign.TL,
152+ Y.WidgetPositionAlign.BR
153+ ]
154+ },
155+ hideOn: [{eventName: 'clickoutside'}],
156+ visible: false,
157+ render: true
158+ });
159+
160+ // Hook the overlay link.
161+ overlay_link.on('click', function (e) {
162+ e.preventDefault();
163+ overlay.show();
164+ });
165+
166 },
167
168 bindUI: function() {
169+ var review = this.get('review');
170+ var trigger = this.get('srcNode').all('a.review-choice');
171 var self = this;
172- this.get('srcNode').all('button').on('click', function(e) {
173- var review = self.get('review');
174+ trigger.on('click', function(e) {
175+ e.halt();
176+ review.status = e.currentTarget.get('text');
177 var data = {
178- reviews: [{
179- 'id': review.id,
180- 'workflow_step': review.workflow_step,
181- 'completed': true
182- }]
183+ reviews: [review]
184 };
185 // Issue a PATCH TS-request to update the review and
186 // update the widget accordingly.
187@@ -73,7 +124,6 @@
188 self.get('srcNode').all('.error').remove(true);
189 },
190 success: function(tx, r) {
191- review.completed = true;
192 self.renderUI();
193 self.bindUI();
194 },
195@@ -657,7 +707,7 @@
196 }
197 } else {
198 // Steps yet to come are empty.
199- return;
200+ value = '';
201 }
202
203 // Render a placeholder for related reviews recording
204@@ -703,8 +753,12 @@
205 node.getAttribute('row-id'));
206 var record = e.currentTarget.getRecord(row_id);
207 Y.Array.each(record.get('reviews'), function (r) {
208- var w = new InlineReview(
209- {boundingBox: node, review: r});
210+ var w = new InlineReview({
211+ boundingBox: node,
212+ review: r,
213+ readonly: (ticket.current_workflow_step !==
214+ r.workflow_step)
215+ });
216 w.render();
217 });
218 });
219@@ -1020,4 +1074,4 @@
220 Y.webui.get_workflow_steps();
221 Y.webui.get_workflow_statuses();
222 }, '0.0.1', {requires: ['datatable', 'datatype-number', 'io', 'json-parse',
223- 'json-stringify']});
224+ 'json-stringify', 'overlay', 'widget-autohide']});
225
226=== modified file 'webui/tickets/static/tickets/webuiforms.js'
227--- webui/tickets/static/tickets/webuiforms.js 2014-10-30 04:57:56 +0000
228+++ webui/tickets/static/tickets/webuiforms.js 2014-11-06 17:15:07 +0000
229@@ -142,7 +142,7 @@
230
231 // Hijack the default (www-urlencoded) form submission and
232 // submit its content as JSON.
233- f.getField('create-button').on('click', function(e) {
234+ Y.one('input[name="create-button"]').on('click', function(e) {
235 e.halt();
236 if (!f._runValidation()) {
237 return 1;
238@@ -256,7 +256,7 @@
239 .set('href', '.')
240 );
241
242- f.getField('edit-button').on('click', function(e) {
243+ Y.one('input[name="edit-button"]').on('click', function(e) {
244 e.halt();
245 if (!f._runValidation()) {
246 return 1;

Subscribers

People subscribed via source and target branches