Merge lp:~cprov/uci-engine/webui-ticket-edit into lp:uci-engine
- webui-ticket-edit
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Celso Providelo |
Approved revision: | 870 |
Merged at revision: | 879 |
Proposed branch: | lp:~cprov/uci-engine/webui-ticket-edit |
Merge into: | lp:uci-engine |
Prerequisite: | lp:~cprov/uci-engine/ts-workflow |
Diff against target: |
526 lines (+273/-92) 9 files modified
ticket_system/ticket/api.py (+28/-0) ticket_system/ticket/tests/test_write_api.py (+28/-0) webui/common/static/common/webui.css (+16/-0) webui/tickets/static/tickets/webui.js (+5/-2) webui/tickets/static/tickets/webui_ticket_edit.js (+4/-33) webui/tickets/static/tickets/webuiforms.js (+182/-42) webui/tickets/templates/tickets/edit.html (+6/-7) webui/tickets/urls.py (+2/-2) webui/tickets/views.py (+2/-6) |
To merge this branch: | bzr merge lp:~cprov/uci-engine/webui-ticket-edit |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Francis Ginther | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email: mp+240075@code.launchpad.net |
Commit message
Implementing a all-in-one ticket edit form.
Description of the change
Implementing a all-in-one ticket edit form.
This is a plan-B for the delay on implementing inline-edit for the ticket-details datatable:
https:/
While it is clearly not *outstanding* from the usability PoV, it fulfils the requirements of the citrain transition allowing users to update ticket details during the ticket lifecycle.
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:870
http://
Executed test runs:
Click here to trigger a rebuild:
http://
Francis Ginther (fginther) wrote : | # |
Editing works. It's very basic as you mentioned, but it works. I don't have much input for the js portion. The refactoring is nice and I don't see anything obvious enough to comment on.
Ubuntu CI Bot (uci-bot) wrote : | # |
The attempt to merge lp:~cprov/uci-engine/webui-ticket-edit into lp:uci-engine failed. Below is the output from the failed tests.
Running cm...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
uploading webui-content.tgz to swift
Updating source dependencies...
Checking juju status
Private PPAs: disabled
Preparing local branch upload...
Uploading local branch, fingerprint ee7d6e8516d4378
Building charm: lander
Building charm: wsgi-app
Building charm: rabbitmq-worker
Building charm: chroot-builder
Building charm: key-secret-
Building charm: webui
Building charm: system-image-server
Installing keys from bzr+ssh:
Running juju-deployer -v -c /tmp/tmpJram7Y/
Tests running...
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
Ubuntu CI Bot (uci-bot) wrote : | # |
The attempt to merge lp:~cprov/uci-engine/webui-ticket-edit into lp:uci-engine failed. Below is the output from the failed tests.
Running cm...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
uploading webui-content.tgz to swift
Updating source dependencies...
Checking juju status
Private PPAs: disabled
Preparing local branch upload...
Uploading local branch, fingerprint 878254b38f6d8c0
Building charm: lander
Building charm: wsgi-app
Building charm: rabbitmq-worker
Building charm: chroot-builder
Building charm: key-secret-
Building charm: webui
Building charm: system-image-server
Installing keys from bzr+ssh:
Running juju-deployer -v -c /tmp/tmpRH1ObA/
Tests running...
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
Ubuntu CI Bot (uci-bot) wrote : | # |
The attempt to merge lp:~cprov/uci-engine/webui-ticket-edit into lp:uci-engine failed. Below is the output from the failed tests.
Running cm...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
uploading webui-content.tgz to swift
Updating source dependencies...
Checking juju status
Private PPAs: disabled
Preparing local branch upload...
Uploading local branch, fingerprint 6376fa629f4280a
Building charm: lander
Building charm: wsgi-app
Building charm: rabbitmq-worker
Building charm: chroot-builder
Building charm: key-secret-
Building charm: webui
Building charm: system-image-server
Installing keys from bzr+ssh:
Running juju-deployer -v -c /tmp/tmpmG2Ksj/
Tests running...
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
Ubuntu CI Bot (uci-bot) wrote : | # |
The attempt to merge lp:~cprov/uci-engine/webui-ticket-edit into lp:uci-engine failed. Below is the output from the failed tests.
Running cm...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
uploading webui-content.tgz to swift
Updating source dependencies...
Checking juju status
Private PPAs: disabled
Preparing local branch upload...
Uploading local branch, fingerprint be873127c37b943
Building charm: lander
Building charm: wsgi-app
Building charm: rabbitmq-worker
Building charm: chroot-builder
Building charm: key-secret-
Building charm: webui
Building charm: system-image-server
Installing keys from bzr+ssh:
Running juju-deployer -v -c /tmp/tmplKtrKh/
Tests running...
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
Ubuntu CI Bot (uci-bot) wrote : | # |
The attempt to merge lp:~cprov/uci-engine/webui-ticket-edit into lp:uci-engine failed. Below is the output from the failed tests.
Running cm...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
uploading webui-content.tgz to swift
Updating source dependencies...
Checking juju status
Private PPAs: disabled
Preparing local branch upload...
Uploading local branch, fingerprint dcb93501c07911d
Building charm: lander
Building charm: wsgi-app
Building charm: rabbitmq-worker
Building charm: chroot-builder
Building charm: key-secret-
Building charm: webui
Building charm: system-image-server
Installing keys from bzr+ssh:
Running juju-deployer -v -c /tmp/tmpOVrtL8/
Tests running...
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
Ubuntu CI Bot (uci-bot) wrote : | # |
The attempt to merge lp:~cprov/uci-engine/webui-ticket-edit into lp:uci-engine failed. Below is the output from the failed tests.
Running cm...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
Updating source dependencies...
uploading webui-content.tgz to swift
Updating source dependencies...
Checking juju status
Private PPAs: disabled
Preparing local branch upload...
Uploading local branch, fingerprint 8ac73e1c6b94a85
Building charm: lander
Building charm: wsgi-app
Building charm: rabbitmq-worker
Building charm: chroot-builder
Building charm: key-secret-
Building charm: webui
Building charm: system-image-server
Installing keys from bzr+ssh:
Running juju-deployer -v -c /tmp/tmpQf_
Tests running...
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
ci-utils.
Preview Diff
1 | === modified file 'ticket_system/ticket/api.py' |
2 | --- ticket_system/ticket/api.py 2014-10-30 04:58:12 +0000 |
3 | +++ ticket_system/ticket/api.py 2014-10-30 04:58:12 +0000 |
4 | @@ -129,6 +129,34 @@ |
5 | bundle.data['status'] = value |
6 | return bundle |
7 | |
8 | + def hydrate_subtickets(self, bundle): |
9 | + """Prevent creation of conflicting (duplicated) `Subticket`s.""" |
10 | + subtickets = bundle.data.get('subtickets') |
11 | + if subtickets is None: |
12 | + return bundle |
13 | + |
14 | + for subticket in subtickets: |
15 | + if not isinstance(subticket, dict): |
16 | + sp = subticket.data['sourcepackage'] |
17 | + else: |
18 | + sp = subticket['sourcepackage'] |
19 | + |
20 | + # Already a resource URI. |
21 | + if not isinstance(sp, dict): |
22 | + continue |
23 | + |
24 | + # Set the 'id' attribute if the subticket already exists, |
25 | + # it will prevent tastypie to create a conflict one. |
26 | + cls = SubTicketResource._meta.object_class |
27 | + try: |
28 | + obj = cls.objects.get( |
29 | + ticket=bundle.obj, sourcepackage__name=sp['name']) |
30 | + except cls.DoesNotExist: |
31 | + continue |
32 | + subticket['id'] = obj.id |
33 | + |
34 | + return bundle |
35 | + |
36 | def hydrate_workflow(self, bundle): |
37 | """Re-use existing `Workflow` when creating or updating tickets. |
38 | |
39 | |
40 | === modified file 'ticket_system/ticket/tests/test_write_api.py' |
41 | --- ticket_system/ticket/tests/test_write_api.py 2014-10-30 04:58:12 +0000 |
42 | +++ ticket_system/ticket/tests/test_write_api.py 2014-10-30 04:58:12 +0000 |
43 | @@ -229,6 +229,34 @@ |
44 | [sub_foo] = list(ticket.subticket_set.all()) |
45 | self.assertEqual(existing_sp, sub_foo.sourcepackage) |
46 | |
47 | + def test_patch_ticket_subtickets(self): |
48 | + # `Ticket` patch can create new or update existing `Subticket`s. |
49 | + params = self.post_ticket_data.copy() |
50 | + params.update({ |
51 | + 'title': 'Atomic Patched Ticket', |
52 | + 'subtickets': [{ |
53 | + 'sourcepackage': {'name': 'foo'}, |
54 | + 'assignee': 'foo@bar.com', |
55 | + }, { |
56 | + 'sourcepackage': {'name': 'bar'}, |
57 | + 'assignee': 'foo@bar.com', |
58 | + }], |
59 | + }) |
60 | + # Create a matching `SourcePackage` and `SubTicket`. |
61 | + sp = SourcePackage.objects.create(name='foo') |
62 | + subticket = self.ticket.subticket_set.create( |
63 | + sourcepackage=sp, assignee='boing@boing.com') |
64 | + |
65 | + self.patch(resource=self.detail_url, params=params) |
66 | + |
67 | + # The existing `Subticket` was updated and a new one was created. |
68 | + [ticket] = list(Ticket.objects.all()) |
69 | + self.assertEqual('Atomic Patched Ticket', unicode(ticket)) |
70 | + [old, new] = list(ticket.subticket_set.all()) |
71 | + self.assertEqual(old, subticket) |
72 | + self.assertEqual('foo@bar.com', old.assignee) |
73 | + self.assertEqual('Atomic Patched Ticket bar', unicode(new)) |
74 | + |
75 | def test_post_ticket_citrain_overlay(self): |
76 | # `Ticket` creation supports adding CI-Train extra fields (via |
77 | # 'citrain_overlay' FK). |
78 | |
79 | === added file 'webui/common/static/common/edit.png' |
80 | Binary files webui/common/static/common/edit.png 1970-01-01 00:00:00 +0000 and webui/common/static/common/edit.png 2014-10-30 04:58:12 +0000 differ |
81 | === modified file 'webui/common/static/common/webui.css' |
82 | --- webui/common/static/common/webui.css 2014-10-30 04:58:12 +0000 |
83 | +++ webui/common/static/common/webui.css 2014-10-30 04:58:12 +0000 |
84 | @@ -231,6 +231,11 @@ |
85 | width: auto; |
86 | } |
87 | |
88 | +.yui3-submit-button-content a { |
89 | + padding-left: 2em; |
90 | + font-weight: bold; |
91 | +} |
92 | + |
93 | /* Login menu. */ |
94 | div.yui3-login { |
95 | float: right; |
96 | @@ -252,9 +257,11 @@ |
97 | /* Ticket details datatable. */ |
98 | td.dt-details-key { |
99 | font-weight: bold; |
100 | + line-height: 1.5; |
101 | } |
102 | |
103 | td.dt-details-value { |
104 | + line-height: 1.5; |
105 | } |
106 | |
107 | th.dt-details-key, th.dt-details-value { |
108 | @@ -307,3 +314,12 @@ |
109 | background-size: contain; |
110 | padding-left: 1.2em; |
111 | } |
112 | + |
113 | +a.edit-link { |
114 | + background-image: url('/static/common/edit.png'); |
115 | + background-repeat: no-repeat; |
116 | + background-size: contain; |
117 | + padding-left: 1.2em; |
118 | + margin-left: 5px; |
119 | + font-size: 10px; |
120 | +} |
121 | |
122 | === modified file 'webui/tickets/static/tickets/webui.js' |
123 | --- webui/tickets/static/tickets/webui.js 2014-10-30 04:58:12 +0000 |
124 | +++ webui/tickets/static/tickets/webui.js 2014-10-30 04:58:12 +0000 |
125 | @@ -376,7 +376,10 @@ |
126 | dt_status.render(workflow_inner_div); |
127 | |
128 | // Create a section for presenting ticket details. |
129 | - ticket_wrapper.appendChild('<h3>Ticket Details</h3>'); |
130 | + var status_title = Y.Node.create('<h3>Ticket Details</h3>'); |
131 | + status_title.appendChild( |
132 | + '<a class="edit-link" title="Edit details" href="edit"></a>'); |
133 | + ticket_wrapper.appendChild(status_title); |
134 | ticket_div = ticket_wrapper.appendChild( |
135 | Y.Node.create("<div class='ticket'></div>")); |
136 | |
137 | @@ -650,7 +653,7 @@ |
138 | |
139 | return new Y.DataTable({ |
140 | columns: [ |
141 | - {key: 'key', label: 'Key', 'width': '150%', |
142 | + {key: 'key', label: 'Key', 'width': '100%', |
143 | allowHTML: true, formatter: format_key, |
144 | className: 'dt-details-key'}, |
145 | {key: 'value', label: 'Value', |
146 | |
147 | === renamed file 'webui/tickets/static/tickets/webui_review.js' => 'webui/tickets/static/tickets/webui_ticket_edit.js' |
148 | --- webui/tickets/static/tickets/webui_review.js 2014-06-17 18:09:59 +0000 |
149 | +++ webui/tickets/static/tickets/webui_ticket_edit.js 2014-10-30 04:58:12 +0000 |
150 | @@ -1,34 +1,5 @@ |
151 | -YUI().use('io', 'webui', 'datatable-mutable', function (Y) { |
152 | - |
153 | - var columns = [ |
154 | - {key: 'review_type', label: 'Review Type'}, |
155 | - {key: 'completed', label: 'Completed'} |
156 | - ] |
157 | - var table = new Y.DataTable({columnset: columns, recordset: []}); |
158 | - table.render('#review-table'); |
159 | - |
160 | - function show_reviews(ticket_id) { |
161 | - var url = '/api/v1/review/?ticket=' + ticket_id; |
162 | - Y.io(url, { |
163 | - on: { |
164 | - success: function(tx, r) { |
165 | - data = Y.JSON.parse(r.responseText); |
166 | - if(data.objects.length > 0) { |
167 | - for(var i=0; i<data.objects.length; i++) { |
168 | - table.addRow(data.objects[i]); |
169 | - } |
170 | - } else { |
171 | - Y.one('#review-retry')._node.style.display = 'block'; |
172 | - Y.one('#review-table')._node.style.display = 'None'; |
173 | - } |
174 | - }, |
175 | - failure: function(tx, r, e) { |
176 | - console.log("failure: ", tx, r, e); |
177 | - } |
178 | - } |
179 | - }); |
180 | - } |
181 | - |
182 | - show_reviews(ticket_id); |
183 | +YUI().use('webuiforms', function (Y) { |
184 | + |
185 | + Y.webuiforms.setupEditForm('#form-content'); |
186 | + |
187 | }); |
188 | - |
189 | |
190 | === modified file 'webui/tickets/static/tickets/webuiforms.js' |
191 | --- webui/tickets/static/tickets/webuiforms.js 2014-10-30 04:58:12 +0000 |
192 | +++ webui/tickets/static/tickets/webuiforms.js 2014-10-30 04:58:12 +0000 |
193 | @@ -27,12 +27,71 @@ |
194 | * the supported options in Ticket-System. |
195 | */ |
196 | seriesChoices: [ |
197 | + {label : 'Vivid - 15.04', value : 'vivid'}, |
198 | {label : 'Utopic - 14.10', value : 'utopic'}, |
199 | {label : 'Trusty - 14.04', value : 'trusty'}, |
200 | {label : 'Precise - 12.04', value : 'precise'} |
201 | ], |
202 | |
203 | /** |
204 | + * Convert form 'sources' to 'subtickets'. |
205 | + * |
206 | + * @method _mangleFormSources |
207 | + */ |
208 | + _mangleFormSources: function (form_data) { |
209 | + var sources_list = form_data['sources'].split('\n'); |
210 | + delete form_data['sources']; |
211 | + form_data['subtickets'] = []; |
212 | + sources_list.forEach( function(name) { |
213 | + if (!Y.Lang.trim(name)) { return; } |
214 | + form_data['subtickets'].push({ |
215 | + 'sourcepackage': {'name': name}, |
216 | + 'assignee': form_data['owner'] |
217 | + }); |
218 | + }); |
219 | + return form_data; |
220 | + }, |
221 | + |
222 | + /** |
223 | + * Convert form 'citrain' attributes to 'citrain_overlay'. |
224 | + * |
225 | + * @method _mangleFormCitrain |
226 | + */ |
227 | + _mangleFormCitrain: function (form_data) { |
228 | + var citrain_overlay_fields = [ |
229 | + 'comments', 'test_notes', 'landers', 'sync_request', |
230 | + 'job_url' |
231 | + ] |
232 | + var citrain_overlay_obj = {} |
233 | + citrain_overlay_fields.forEach( function(name) { |
234 | + citrain_overlay_obj[name] = form_data[name]; |
235 | + delete form_data[name]; |
236 | + }); |
237 | + form_data['citrain_overlay'] = citrain_overlay_obj; |
238 | + return form_data; |
239 | + }, |
240 | + |
241 | + /** |
242 | + * Add appropiate reviews to the form. |
243 | + * |
244 | + * @method _mangleFormReviews |
245 | + */ |
246 | + _mangleFormReviews: function (form_data) { |
247 | + form_data['reviews'] = [ |
248 | + {'review_type': 'Developer', |
249 | + 'workflow_step': 'Silo testing'} |
250 | + ]; |
251 | + if (form_data['qa_review']) { |
252 | + form_data['reviews'].push({ |
253 | + 'review_type': 'QA', |
254 | + 'workflow_step': 'Silo testing' |
255 | + }); |
256 | + }; |
257 | + delete form_data['qa_review']; |
258 | + return form_data; |
259 | + }, |
260 | + |
261 | + /** |
262 | * Setup a form for creating a new ticket. |
263 | * |
264 | * Uses Y.Form() to build and render the form dynamically and |
265 | @@ -56,24 +115,30 @@ |
266 | type: 'TextareaField'}, |
267 | {name: 'owner', required: true, label: 'Owner:', |
268 | validator: Y.FormField.VALIDATE_EMAIL_ADDRESS}, |
269 | + {name: 'landers', label: 'Landers:'}, |
270 | + {name: 'qa_review', label: 'QA sign-off required?', |
271 | + type: 'CheckboxField'}, |
272 | + {name: 'sync_request', label: 'Sync request:'}, |
273 | {name: 'series', required: true, label: 'Series:', |
274 | type: 'WebUISelectField', useDefaultOption: false, |
275 | choices: this.seriesChoices}, |
276 | - {name: 'sync_request', label: 'Sync request:'}, |
277 | {name: 'sources', label: 'Source Packages:', |
278 | type: 'TextareaField'}, |
279 | - {name: 'landers', label: 'Landers:'}, |
280 | {name: 'test_notes', label: 'Test notes:', |
281 | type: 'TextareaField'}, |
282 | {name: 'comments', label: 'Comments:', |
283 | type: 'TextareaField'}, |
284 | - {name: 'qa_review', label: 'QA sign-off required?', |
285 | - type: 'CheckboxField'}, |
286 | {name: 'create-button', type: 'SubmitButton', |
287 | value: 'Create!'} |
288 | ] |
289 | }); |
290 | + |
291 | f.render(); |
292 | + Y.one('.yui3-submit-button-content').appendChild( |
293 | + Y.Node.create('<a>') |
294 | + .set('text', 'Cancel') |
295 | + .set('href', '.') |
296 | + ); |
297 | |
298 | // Hijack the default (www-urlencoded) form submission and |
299 | // submit its content as JSON. |
300 | @@ -83,45 +148,10 @@ |
301 | return 1; |
302 | } |
303 | |
304 | - // XXX cprov 20140922: extend the form data with appropriate |
305 | - // 'status' and 'current_workflow_step'. |
306 | var form_data = f.toJSON(); |
307 | - |
308 | - // Convert form 'sources' to 'subtickets'. |
309 | - var sources_list = form_data['sources'].split('\n'); |
310 | - delete form_data['sources']; |
311 | - form_data['subtickets'] = []; |
312 | - sources_list.forEach( function(name) { |
313 | - form_data['subtickets'].push({ |
314 | - 'sourcepackage': {'name': name}, |
315 | - 'assignee': form_data['owner'] |
316 | - }); |
317 | - }); |
318 | - |
319 | - form_data['reviews'] = [ |
320 | - {'review_type': 'Developer', |
321 | - 'workflow_step': 'Silo testing'} |
322 | - ]; |
323 | - // Create QA review, if necessary. |
324 | - if (form_data['qa_review']) { |
325 | - form_data['reviews'].push({ |
326 | - 'review_type': 'QA', |
327 | - 'workflow_step': 'Silo testing' |
328 | - }); |
329 | - }; |
330 | - delete form_data['qa_review']; |
331 | - |
332 | - // Convert several form fields to 'citrain_overlay'. |
333 | - var citrain_overlay_fields = [ |
334 | - 'comments', 'test_notes', 'landers', 'sync_request', |
335 | - 'job_url' |
336 | - ] |
337 | - var citrain_overlay_obj = {} |
338 | - citrain_overlay_fields.forEach( function(name) { |
339 | - citrain_overlay_obj[name] = form_data[name]; |
340 | - delete form_data[name]; |
341 | - }); |
342 | - form_data['citrain_overlay'] = citrain_overlay_obj; |
343 | + form_data = Y.webuiforms._mangleFormSources(form_data); |
344 | + form_data = Y.webuiforms._mangleFormCitrain(form_data); |
345 | + form_data = Y.webuiforms._mangleFormReviews(form_data); |
346 | form_data['workflow'] = {'name': 'citrain'}; |
347 | |
348 | Y.io(f.get('action'), { |
349 | @@ -146,6 +176,116 @@ |
350 | } |
351 | }); |
352 | }); |
353 | + }, |
354 | + /** |
355 | + * Setup a form for editing a ticket. |
356 | + * |
357 | + * @method setupEditForm |
358 | + */ |
359 | + setupEditForm: function (container) { |
360 | + var form_message = Y.Node.create('<div>'); |
361 | + Y.one(container).appendChild(form_message); |
362 | + |
363 | + // Build and render a form for editing Ticket. |
364 | + var f = new Y.Form({ |
365 | + boundingBox: container, |
366 | + action : '/api/v1/ticket/' + ticket_id + '/', |
367 | + method : 'post', |
368 | + children : [ |
369 | + {name: 'title', required: true, label: 'Title:'}, |
370 | + {name: 'owner', required: true, label: 'Owner:', |
371 | + validator: Y.FormField.VALIDATE_EMAIL_ADDRESS}, |
372 | + {name: 'landers', label: 'Landers:'}, |
373 | + {name: 'bug_id', label: 'Bug id:'}, |
374 | + {name: 'sync_request', label: 'Sync request:'}, |
375 | + {name: 'sources', label: 'Source Packages:', |
376 | + type: 'TextareaField'}, |
377 | + {name: 'description', label: 'Description:', |
378 | + type: 'TextareaField'}, |
379 | + {name: 'test_notes', label: 'Test notes:', |
380 | + type: 'TextareaField'}, |
381 | + {name: 'comments', label: 'Comments:', |
382 | + type: 'TextareaField'}, |
383 | + {name: 'edit-button', type: 'SubmitButton', |
384 | + value: 'Update!'} |
385 | + ] |
386 | + }); |
387 | + |
388 | + // Load ticket information from TS and pre-fill the form. |
389 | + Y.io('/api/v1/fullticket/' + ticket_id + '/', { |
390 | + sync: true, |
391 | + on: { |
392 | + success: function (tx, r) { |
393 | + var ticket = Y.JSON.parse(r.responseText); |
394 | + if (ticket.citrain_overlay) { |
395 | + ticket = Y.merge(ticket, ticket.citrain_overlay); |
396 | + } |
397 | + f.each( function(field) { |
398 | + var name = field.get('name'); |
399 | + switch (name) { |
400 | + case 'edit-button': |
401 | + return; |
402 | + case 'bug_id': |
403 | + field.set( |
404 | + 'value', (ticket[name] || '').toString()); |
405 | + break; |
406 | + case 'sources': |
407 | + var sources = []; |
408 | + ticket.subticket.forEach( function(s) { |
409 | + sources.push(s.sourcepackage.name); |
410 | + }); |
411 | + field.set('value', sources.join('\n')); |
412 | + break; |
413 | + default: |
414 | + field.set('value', ticket[name] || ''); |
415 | + } |
416 | + }); |
417 | + }, |
418 | + failure: function (tx, r, e) { |
419 | + console.log("failure loading fullticket (" + |
420 | + ticket_id + "): ", tx, r, e); |
421 | + } |
422 | + } |
423 | + }); |
424 | + |
425 | + // Render the form and a 'Cancel' link. |
426 | + f.render(); |
427 | + Y.one('.yui3-submit-button-content').appendChild( |
428 | + Y.Node.create('<a>') |
429 | + .set('text', 'Cancel') |
430 | + .set('href', '.') |
431 | + ); |
432 | + |
433 | + f.getField('edit-button').on('click', function(e) { |
434 | + e.halt(); |
435 | + if (!f._runValidation()) { |
436 | + return 1; |
437 | + } |
438 | + var form_data = f.toJSON(); |
439 | + form_data = Y.webuiforms._mangleFormSources(form_data); |
440 | + form_data = Y.webuiforms._mangleFormCitrain(form_data); |
441 | + |
442 | + Y.io(f.get('action'), { |
443 | + method: 'patch', |
444 | + sync: true, |
445 | + data: Y.JSON.stringify(form_data), |
446 | + headers: { |
447 | + 'Content-Type': 'application/json;', |
448 | + }, |
449 | + on: { |
450 | + success: function(tx, r) { |
451 | + Y.config.win.location.href = f.get( |
452 | + 'action').replace('/api/v1', ''); |
453 | + }, |
454 | + failure: function (tx, r) { |
455 | + Y.log('FAILURE: ' + r.responseText); |
456 | + form_message.addClass('form-error') |
457 | + form_message.set( |
458 | + 'text', 'Ticket update failed!') |
459 | + } |
460 | + } |
461 | + }); |
462 | + }); |
463 | } |
464 | }; |
465 | }, '0.0.1', {requires: ['io', 'node', 'json-parse', 'json-stringify', |
466 | |
467 | === renamed file 'webui/tickets/templates/tickets/review.html' => 'webui/tickets/templates/tickets/edit.html' |
468 | --- webui/tickets/templates/tickets/review.html 2014-06-17 18:09:59 +0000 |
469 | +++ webui/tickets/templates/tickets/edit.html 2014-10-30 04:58:12 +0000 |
470 | @@ -3,15 +3,14 @@ |
471 | |
472 | {% block extra_headers %} |
473 | <script type="text/javascript"> |
474 | - ticket_id = {{ ticket_id }}; |
475 | + ticket_id = '{{ ticket_id }}'; |
476 | </script> |
477 | - <script type="text/javascript" src="{% static 'tickets/webui_review.js' %}"></script> |
478 | + <script type="text/javascript" |
479 | + src="{% static 'tickets/webuiforms.js' %}"></script> |
480 | + <script type="text/javascript" |
481 | + src="{% static 'tickets/webui_ticket_edit.js' %}"></script> |
482 | {% endblock extra_headers %} |
483 | |
484 | {% block content %} |
485 | -<div id="review-table" class="yui3-skin-sam"></div> |
486 | - |
487 | -<div id="review-retry" style="display: None"> |
488 | -TODO - add some sort of "retry ticket" button |
489 | -</div> |
490 | +<div id="form-content" class="yui3-skin-sam"></div> |
491 | {% endblock content %} |
492 | |
493 | === modified file 'webui/tickets/urls.py' |
494 | --- webui/tickets/urls.py 2014-10-07 10:04:01 +0000 |
495 | +++ webui/tickets/urls.py 2014-10-30 04:58:12 +0000 |
496 | @@ -10,8 +10,8 @@ |
497 | 'tickets.views.detail', name='ticket_detail'), |
498 | url(r'^ticket/(?P<ticket_id>{})/livelog$'.format(ticket_id_regexp), |
499 | 'tickets.views.livelog', name='ticket_livelog'), |
500 | - url(r'^ticket/(?P<ticket_id>{})/review$'.format(ticket_id_regexp), |
501 | - 'tickets.views.review', name='ticket_review'), |
502 | + url(r'^ticket/(?P<ticket_id>{})/edit$'.format(ticket_id_regexp), |
503 | + 'tickets.views.edit', name='ticket_edit'), |
504 | url(r'^complete/$', 'tickets.views.complete', name='ticket_complete'), |
505 | url(r'^failed/$', 'tickets.views.failed', name='ticket_failed'), |
506 | url(r'^create$', 'tickets.views.create', name='create'), |
507 | |
508 | === modified file 'webui/tickets/views.py' |
509 | --- webui/tickets/views.py 2014-10-07 10:04:01 +0000 |
510 | +++ webui/tickets/views.py 2014-10-30 04:58:12 +0000 |
511 | @@ -27,13 +27,9 @@ |
512 | return render_to_response('tickets/logview.html', base_data) |
513 | |
514 | |
515 | -def review(request, ticket_id): |
516 | +def edit(request, ticket_id): |
517 | base_data['ticket_id'] = ticket_id |
518 | - return render_to_response('tickets/review.html', base_data) |
519 | - |
520 | - |
521 | -def status(request): |
522 | - return render_to_response('tickets/status.html', base_data) |
523 | + return render_to_response('tickets/edit.html', base_data) |
524 | |
525 | |
526 | def create(request): |
FAILED: Continuous integration, rev:870 s-jenkins. ubuntu- ci:8080/ job/uci- engine- ci/1643/
http://
Executed test runs:
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/uci- engine- ci/1643/ rebuild
http://