Merge lp:~dylanmccall/harvest/opportunity-edit into lp:harvest
- opportunity-edit
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 235 |
Proposed branch: | lp:~dylanmccall/harvest/opportunity-edit |
Merge into: | lp:harvest |
Diff against target: |
1060 lines (+437/-183) 26 files modified
EXTERNALS (+4/-0) harvest/common/templatetags/humanize_timediff.py (+51/-0) harvest/common/templatetags/list_to_columns.py (+0/-30) harvest/media/css/style.css (+113/-30) harvest/media/js/harvest.js (+10/-8) harvest/opportunities/admin.py (+8/-2) harvest/opportunities/forms.py (+6/-2) harvest/opportunities/models.py (+19/-6) harvest/opportunities/urls.py (+24/-8) harvest/opportunities/views.py (+91/-60) harvest/templates/base.html (+2/-2) harvest/templates/one_column.html (+9/-0) harvest/templates/opportunities/filter.html (+1/-1) harvest/templates/opportunities/include/filter_results.html (+1/-1) harvest/templates/opportunities/include/opportunity.html (+2/-4) harvest/templates/opportunities/include/opportunity_details.html (+7/-0) harvest/templates/opportunities/include/opportunity_details_edit.html (+48/-0) harvest/templates/opportunities/include/opportunity_li.html (+3/-0) harvest/templates/opportunities/include/opportunity_notes_list.html (+9/-0) harvest/templates/opportunities/include/opportunity_outer_li.html (+3/-0) harvest/templates/opportunities/include/package_details.html (+1/-3) harvest/templates/opportunities/opportunity_edit.html (+11/-14) harvest/templates/opportunities/single_package.html (+5/-12) harvest/templates/opportunities/xhr/opportunity_edit.html (+3/-0) harvest/templates/opportunities/xhr/opportunity_li.html (+3/-0) harvest/templates/opportunities/xhr/opportunity_outer_li.html (+3/-0) |
To merge this branch: | bzr merge lp:~dylanmccall/harvest/opportunity-edit |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel Holbach | Approve | ||
Review via email: mp+32544@code.launchpad.net |
Commit message
Description of the change
Improved the opportunity edit form and the style for some surrounding elements. Implemented the new Notes system (which is like comments, but shorter and simpler with a 250 character limit).
Screenshot: http://
This branch does not address how the form is opened or where it goes after submitting, which is still a problem when running with Javascript.
- 243. By Dylan McCall
-
Improved formatting for form errors and #messages.
Fixed some inconsistency with padding and margins around elements.
- 244. By Dylan McCall
-
Fixed wrapping for .opportunity-
details. edit > form > ul.opportunity- switches
Dylan McCall (dylanmccall) wrote : | # |
Daniel Holbach (dholbach) wrote : | # |
Good work. I like your code changes, but there's a few small glitches which we can address through follow-up bugs.
Daniel Holbach (dholbach) wrote : | # |
Nevermind, can't reproduce the issue I had with duplicated opportunity entries.
Preview Diff
1 | === modified file 'EXTERNALS' |
2 | --- EXTERNALS 2010-07-14 15:34:17 +0000 |
3 | +++ EXTERNALS 2010-08-13 02:04:41 +0000 |
4 | @@ -10,6 +10,10 @@ |
5 | By "metajack" |
6 | <http://djangosnippets.org/snippets/797/> |
7 | |
8 | +./harvest/common/templatetags/humanize_timediff.py |
9 | + By "supsupmo" |
10 | + <http://djangosnippets.org/snippets/412/> |
11 | + |
12 | ./harvest/media/css/reset.css |
13 | By Eric Meyer |
14 | <http://meyerweb.com/eric/tools/css/reset/> |
15 | |
16 | === added file 'harvest/common/templatetags/humanize_timediff.py' |
17 | --- harvest/common/templatetags/humanize_timediff.py 1970-01-01 00:00:00 +0000 |
18 | +++ harvest/common/templatetags/humanize_timediff.py 2010-08-13 02:04:41 +0000 |
19 | @@ -0,0 +1,51 @@ |
20 | +#Template filter to provide a string similar to the built in timesince |
21 | +#filter, but slightly fuzzier. |
22 | +#From <http://djangosnippets.org/snippets/412/> with localization added |
23 | + |
24 | +from django.utils.translation import ungettext |
25 | +from django import template |
26 | + |
27 | +register = template.Library() |
28 | + |
29 | +@register.filter |
30 | +def humanize_timediff(timestamp = None): |
31 | + """ |
32 | + Returns a humanized string representing time difference |
33 | + between now() and the input timestamp. |
34 | + |
35 | + The output rounds up to days, hours, minutes, or seconds. |
36 | + 4 days 5 hours returns '4 days' |
37 | + 0 days 4 hours 3 minutes returns '4 hours', etc... |
38 | + """ |
39 | + import datetime |
40 | + |
41 | + timeDiff = datetime.datetime.now() - timestamp |
42 | + days = timeDiff.days |
43 | + hours = timeDiff.seconds/3600 |
44 | + minutes = timeDiff.seconds%3600/60 |
45 | + seconds = timeDiff.seconds%3600%60 |
46 | + |
47 | + str = "" |
48 | + tStr = "" |
49 | + if days > 0: |
50 | + str = ungettext('%(days)d day', '%(days)d days', days) % { |
51 | + 'days' : days |
52 | + } |
53 | + return str |
54 | + elif hours > 0: |
55 | + str = ungettext('%(hours)d hour', '%(hours)d hours', hours) % { |
56 | + 'hours' : hours |
57 | + } |
58 | + return str |
59 | + elif minutes > 0: |
60 | + str = ungettext('%(minutes)d minute', '%(minutes)d minutes', minutes) % { |
61 | + 'minutes' : minutes |
62 | + } |
63 | + return str |
64 | + elif seconds > 0: |
65 | + str = ungettext('%(seconds)d second', '%(seconds)d seconds', seconds) % { |
66 | + 'seconds' : seconds |
67 | + } |
68 | + return str |
69 | + else: |
70 | + return None |
71 | |
72 | === removed file 'harvest/common/templatetags/list_to_columns.py' |
73 | --- harvest/common/templatetags/list_to_columns.py 2009-07-08 11:31:32 +0000 |
74 | +++ harvest/common/templatetags/list_to_columns.py 1970-01-01 00:00:00 +0000 |
75 | @@ -1,30 +0,0 @@ |
76 | -from django import template |
77 | - |
78 | -register = template.Library() |
79 | - |
80 | -class SplitListNode(template.Node): |
81 | - def __init__(self, list, cols, new_list): |
82 | - self.list = list |
83 | - self.cols = cols |
84 | - self.new_list = new_list |
85 | - |
86 | - def split_seq(self, list, cols=2): |
87 | - start = 0 |
88 | - for i in xrange(cols): |
89 | - stop = start + len(list[i::cols]) |
90 | - yield list[start:stop] |
91 | - start = stop |
92 | - |
93 | - def render(self, context): |
94 | - context[self.new_list] = self.split_seq(context[self.list], |
95 | - int(self.cols)) |
96 | - return '' |
97 | - |
98 | -def list_to_columns(parser, token): |
99 | - bits = token.contents.split() |
100 | - if len(bits) != 5: |
101 | - raise template.TemplateSyntaxError, "list_to_columns list as new_list 2" |
102 | - if bits[2] != 'as': |
103 | - raise template.TemplateSyntaxError, "second argument to the list_to_columns tag must be 'as'" |
104 | - return SplitListNode(bits[1], bits[4], bits[3]) |
105 | -list_to_columns = register.tag(list_to_columns) |
106 | |
107 | === modified file 'harvest/media/css/style.css' |
108 | --- harvest/media/css/style.css 2010-08-05 17:20:01 +0000 |
109 | +++ harvest/media/css/style.css 2010-08-13 02:04:41 +0000 |
110 | @@ -43,6 +43,17 @@ |
111 | color:rgb(180,180,180); |
112 | } |
113 | |
114 | +form label { |
115 | + font-weight:bold; |
116 | +} |
117 | +form .error input, form .error textarea, form .error input#new_note { |
118 | + border:solid 2px rgb(140,0,0); |
119 | +} |
120 | +form ul.errorlist { |
121 | + font-size:smaller; |
122 | + color:rgb(140,0,0); |
123 | +} |
124 | + |
125 | |
126 | |
127 | #container { |
128 | @@ -59,34 +70,33 @@ |
129 | display:block; |
130 | width:100%; |
131 | min-height:80px; |
132 | - |
133 | padding-top:12px; |
134 | - padding-bottom:12px; |
135 | } |
136 | #header a { |
137 | color:rgb(0,0,0); |
138 | } |
139 | -#header #pagetitle { |
140 | +#header #sitetitle { |
141 | display:inline; |
142 | position:static; |
143 | - margin-left:80px; |
144 | + margin-left:40px; |
145 | margin-right:40px; |
146 | + margin-bottom:10px; |
147 | |
148 | text-transform:lowercase; |
149 | color:rgb(0,0,0); |
150 | font-family:'Molengo', 'Bitstream Vera Sans', 'DejaVu Sans', sans-serif; |
151 | } |
152 | -#header #pagetitle #sitelogo { |
153 | +#header #sitetitle #sitelogo { |
154 | width:auto; /* line up with #sitename font-size */ |
155 | height:36px; |
156 | } |
157 | -#header #pagetitle #sitename { |
158 | +#header #sitetitle #sitename { |
159 | display:inline; |
160 | position:static; |
161 | |
162 | font-size:36px; |
163 | } |
164 | -#header #pagetitle #releasename { |
165 | +#header #sitetitle #releasename { |
166 | display:inline; |
167 | position:static; |
168 | |
169 | @@ -112,6 +122,30 @@ |
170 | padding-bottom:140px; |
171 | } |
172 | |
173 | +#content > #messages { |
174 | + display:block; |
175 | + margin:10px 0px; |
176 | + padding:5px 10px; |
177 | + font-size:larger; |
178 | + background-color:rgb(242,151,93); |
179 | + color:rgb(255,255,255); |
180 | +} |
181 | + |
182 | +#content > .pagetitle { |
183 | + margin:10px 0px; |
184 | + max-width:30em; |
185 | + padding:0px 10px; |
186 | + letter-spacing:-1px; |
187 | + font-size:18px; |
188 | + line-height:1em; |
189 | +} |
190 | + |
191 | +#content > .main { |
192 | + margin:10px 0px; |
193 | + padding:0px 20px; |
194 | + max-width:60em; |
195 | +} |
196 | + |
197 | |
198 | |
199 | #filters { |
200 | @@ -120,7 +154,7 @@ |
201 | float:left; |
202 | min-width:160px; |
203 | |
204 | - padding:0px 20px 20px 20px; |
205 | + padding:0px 20px; |
206 | font-size:12px; |
207 | line-height:1.4em; |
208 | color:rgb(51,51,51); |
209 | @@ -207,9 +241,9 @@ |
210 | #filters .editfilter input { |
211 | width:8em; |
212 | border:none; |
213 | + border-bottom:1px solid rgb(180,180,180); |
214 | + |
215 | padding:0px 2px 0px 2px; |
216 | - border-bottom:1px solid rgb(180,180,180); |
217 | - |
218 | background-color:inherit; |
219 | color:inherit; |
220 | font:inherit; |
221 | @@ -265,48 +299,43 @@ |
222 | -moz-border-radius:3px 3px 0px 0px; |
223 | border-radius:3px 3px 0px 0px; /* lines up with li.sourcepackage's border */ |
224 | } |
225 | -.sourcepackage > a.sourcepackage-header { |
226 | +a.sourcepackage-header { |
227 | color:inherit; |
228 | text-decoration:none; |
229 | } |
230 | -.sourcepackage > .sourcepackage-header > .sourcepackage-name { |
231 | +.sourcepackage-header > .sourcepackage-name { |
232 | display:inline; |
233 | margin-right:10px; |
234 | color:rgb(0,0,0); |
235 | font-size:16px; |
236 | } |
237 | -.sourcepackage > .sourcepackage-header > .status { |
238 | +.sourcepackage-header > .status { |
239 | display:none; /* harvest.js will override this where necessary */ |
240 | } |
241 | -.sourcepackage > .sourcepackage-header > .status img { |
242 | +.sourcepackage-header > .status img { |
243 | width:16px; |
244 | height:16px; |
245 | } |
246 | -.sourcepackage > .sourcepackage-header > .sourcepackage-summary { |
247 | +.sourcepackage-header > .sourcepackage-summary { |
248 | display:inline; |
249 | float:right; |
250 | text-align:right; |
251 | font-size:10px; |
252 | } |
253 | /* prelights */ |
254 | -.sourcepackage > a.sourcepackage-header:hover, |
255 | -.sourcepackage > a.sourcepackage-header:focus { |
256 | - /* use the opportunity count or experience measure here */ |
257 | +a.sourcepackage-header:hover, |
258 | +a.sourcepackage-header:focus { |
259 | background-color:rgb(240,255,243); |
260 | } |
261 | -.sourcepackage > a.sourcepackage-header:hover .sourcepackage-name, |
262 | -.sourcepackage > a.sourcepackage-header:focus .sourcepackage-name { |
263 | +a.sourcepackage-header:hover .sourcepackage-name, |
264 | +a.sourcepackage-header:focus .sourcepackage-name { |
265 | text-decoration:underline; |
266 | } |
267 | |
268 | -.sourcepackage > .sourcepackage-details { |
269 | +.sourcepackage-details { |
270 | display:block; |
271 | - padding-top:20px; |
272 | /* inner padding should be left:20px, right:20px and bottom:5px */ |
273 | } |
274 | -li.sourcepackage > .sourcepackage-details { |
275 | - padding-top:0px; |
276 | -} |
277 | |
278 | /* collapsed state. (expanded is the default) */ |
279 | li.sourcepackage.collapsed { |
280 | @@ -334,7 +363,7 @@ |
281 | } |
282 | |
283 | |
284 | -.sourcepackage-details > .opportunity-list { |
285 | +li.sourcepackage > .sourcepackage-details > .opportunity-list { |
286 | padding-left:20px; |
287 | margin-bottom:5px; |
288 | } |
289 | @@ -394,17 +423,71 @@ |
290 | font-size:smaller; |
291 | } |
292 | |
293 | -.opportunity > .opportunity-details { |
294 | +li.opportunity > .opportunity-details { |
295 | display:block; |
296 | margin-left:10px; |
297 | } |
298 | -.opportunity-details > .opportunity-status { |
299 | +li.opportunity > .opportunity-details.edit { |
300 | + background-color:rgb(255,255,240); |
301 | +} |
302 | + |
303 | +.opportunity-notes { |
304 | display:block; |
305 | - max-width:30em; |
306 | + width:100%; |
307 | + max-width:35em; |
308 | border-left:dashed 1px rgb(180,180,180); |
309 | - padding-left:5px; |
310 | + padding:0px 5px 0px 5px; |
311 | font-size:12px; |
312 | } |
313 | +.opportunity-notes input#new_note { |
314 | + width:100%; |
315 | + border:none; |
316 | + border-bottom:1px solid rgb(180,180,180); |
317 | + |
318 | + padding:2px 5px 2px 5px; |
319 | + background-color:inherit; |
320 | + color:inherit; |
321 | + font:inherit; |
322 | +} |
323 | +.opportunity-notes > ul { |
324 | + margin:0.5em 0; |
325 | + max-height:10em; |
326 | +} |
327 | +.opportunity-notes > ul > li { |
328 | + line-height:1.2em; |
329 | + margin-bottom:0.5em; |
330 | +} |
331 | +.opportunity-notes > ul > li > .signature { |
332 | + margin-left:1em; |
333 | + vertical-align:sub; |
334 | + color:rgb(180,180,180); |
335 | + font-style:italic; |
336 | + font-size:smaller; |
337 | +} |
338 | + |
339 | + |
340 | + |
341 | +.opportunity-details.edit > form > div.opportunity-notes { |
342 | + float:left; |
343 | + margin-right:4em; |
344 | + margin-bottom:2em; |
345 | +} |
346 | + |
347 | +.opportunity-details.edit > form > ul.opportunity-switches { |
348 | + float:left; |
349 | +} |
350 | +.opportunity-details.edit > form > ul.opportunity-switches > li { |
351 | + white-space:nowrap; |
352 | + margin-bottom:0.5em; |
353 | +} |
354 | +.opportunity-details.edit > form > ul.opportunity-switches > li.separate-top { |
355 | + margin-bottom:2em; |
356 | +} |
357 | + |
358 | +.opportunity-details.edit > form > .actions { |
359 | + clear:both; |
360 | + padding-top:1em; |
361 | +} |
362 | |
363 | |
364 | |
365 | |
366 | === modified file 'harvest/media/js/harvest.js' |
367 | --- harvest/media/js/harvest.js 2010-07-21 20:59:34 +0000 |
368 | +++ harvest/media/js/harvest.js 2010-08-13 02:04:41 +0000 |
369 | @@ -52,6 +52,10 @@ |
370 | var harvest = new function () { |
371 | |
372 | /* Globals and constants */ |
373 | +var XHR_ROOT = '/opportunities/xhr/'; /* TODO: would be nice to get this from Django */ |
374 | +var RESULTS_URL = XHR_ROOT + 'results/' |
375 | +var OPPORTUNITIES_URL = XHR_ROOT + 'opportunity/'; |
376 | + |
377 | var MEDIA_PATH = '/media/' /* we should get this from Django somehow */ |
378 | var MEDIA = { 'pkg' : { 'loading' : MEDIA_PATH+'img/pkg-status-loading.gif' }, |
379 | 'results' : { 'waiting' : MEDIA_PATH+'img/results-status-waiting.gif', |
380 | @@ -312,13 +316,13 @@ |
381 | } |
382 | |
383 | |
384 | -function Package (dom_node, details_url, opps_query, expanded_cb, collapsed_cb) { |
385 | +function Package (dom_node, opps_query, expanded_cb, collapsed_cb) { |
386 | /* Created for each package inside the #results element */ |
387 | |
388 | - /* gtksourceview gives an error box around "package", so we'll have to forego the convention */ |
389 | + /* gtksourceview highlights "package" as an error, so we'll have to forego the convention */ |
390 | var pkg = this; |
391 | |
392 | - this.id = $(dom_node).attr('data-results-packageid'); |
393 | + this.id = $(dom_node).attr('data-package-id'); |
394 | this.details = $(dom_node).children('.sourcepackage-details'); |
395 | |
396 | this.loading_xhr = null; |
397 | @@ -370,7 +374,7 @@ |
398 | |
399 | this.loading_xhr = $.ajax({ |
400 | type: "GET", |
401 | - url: details_url + this.id, dataType: 'html', |
402 | + url: RESULTS_URL + this.id, dataType: 'html', |
403 | data: opps_query, |
404 | complete: function (xhr, status) { |
405 | pkg.hide_status('loading'); |
406 | @@ -452,7 +456,6 @@ |
407 | this.future_query = {}; |
408 | |
409 | this.container = $(dom_node); |
410 | - this.query_url = $(dom_node).attr('data-results-url'); |
411 | this.output = $(dom_node).children('#results'); |
412 | this.status_bubble = $(dom_node).children('#results-status'); |
413 | |
414 | @@ -488,10 +491,9 @@ |
415 | |
416 | results_packages.each(function () { |
417 | var dom_node = $(this); |
418 | - var details_url = results.query_url + '/'; |
419 | var opps_query = results.current_query; /* would be nice to only send properties starting with opp: */ |
420 | |
421 | - var pkg = new Package(dom_node, details_url, opps_query, |
422 | + var pkg = new Package(dom_node, opps_query, |
423 | pkg_expanded_cb, pkg_collapsed_cb); |
424 | results.packages[pkg.id] = pkg; |
425 | |
426 | @@ -545,7 +547,7 @@ |
427 | |
428 | this.loading_xhr = $.ajax({ |
429 | type: "GET", |
430 | - url: this.query_url, dataType: 'html', |
431 | + url: RESULTS_URL, dataType: 'html', |
432 | data: load_query, |
433 | complete: function (xhr, status) { |
434 | results.hide_status('loading'); |
435 | |
436 | === modified file 'harvest/opportunities/admin.py' |
437 | --- harvest/opportunities/admin.py 2009-08-30 14:53:53 +0000 |
438 | +++ harvest/opportunities/admin.py 2010-08-13 02:04:41 +0000 |
439 | @@ -1,9 +1,15 @@ |
440 | from django.contrib import admin |
441 | -from opportunities.models import Opportunity, OpportunityList, SourcePackage |
442 | +from opportunities.models import Opportunity, Note, OpportunityList, SourcePackage |
443 | + |
444 | +class NoteInline(admin.TabularInline): |
445 | + model = Note |
446 | + extra = 1 |
447 | + raw_id_fields = ('author', ) |
448 | |
449 | class OpportunityAdmin(admin.ModelAdmin): |
450 | - list_display = ('description', 'sourcepackage', 'opportunitylist', 'last_updated') |
451 | + list_display = ('description', 'sourcepackage', 'opportunitylist', 'last_updated', 'note_set') |
452 | list_filter = ('opportunitylist', 'last_updated') |
453 | + inlines = [NoteInline] |
454 | |
455 | class OpportunityListAdmin(admin.ModelAdmin): |
456 | list_display = ('name', 'description', 'last_updated', 'active') |
457 | |
458 | === modified file 'harvest/opportunities/forms.py' |
459 | --- harvest/opportunities/forms.py 2010-03-08 16:53:44 +0000 |
460 | +++ harvest/opportunities/forms.py 2010-08-13 02:04:41 +0000 |
461 | @@ -1,9 +1,13 @@ |
462 | from django import forms |
463 | - |
464 | from models import Opportunity |
465 | +from django.utils.translation import ugettext as _ |
466 | |
467 | class OpportunityForm(forms.ModelForm): |
468 | + new_note = forms.CharField(label=_("Enter a new note here"), |
469 | + required=False, |
470 | + max_length=250) #from models.Note.text |
471 | + |
472 | class Meta: |
473 | model = Opportunity |
474 | - exclude = ('description', 'url', 'last_updated', 'since', 'sourcepackage', 'opportunitylist', 'valid') |
475 | + fields = ('experience', 'applied', 'reviewed') |
476 | |
477 | |
478 | === modified file 'harvest/opportunities/models.py' |
479 | --- harvest/opportunities/models.py 2010-08-05 17:20:01 +0000 |
480 | +++ harvest/opportunities/models.py 2010-08-13 02:04:41 +0000 |
481 | @@ -8,10 +8,10 @@ |
482 | PACKAGE_RED_THRESHOLD = 20 |
483 | |
484 | EXPERIENCE_CHOICES = ( |
485 | - (0, '---'), |
486 | - (1, 'Easy'), |
487 | - (2, 'Medium'), |
488 | - (3, 'Hard'), |
489 | + (0, ""), |
490 | + (1, _("Easy")), |
491 | + (2, _("Medium")), |
492 | + (3, _("Hard")), |
493 | ) |
494 | |
495 | class PackageSet(models.Model): |
496 | @@ -83,9 +83,8 @@ |
497 | applied = models.BooleanField(_("Applied"), default=False, blank=True) |
498 | sourcepackage = models.ForeignKey(SourcePackage) |
499 | opportunitylist = models.ForeignKey(OpportunityList) |
500 | - comment = models.TextField(_("Comment"), blank=True) |
501 | valid = models.BooleanField(_("Valid"), default=True) |
502 | - experience = models.IntegerField(_("Required Experience"), choices=EXPERIENCE_CHOICES, default=0, |
503 | + experience = models.IntegerField(_("Difficulty"), choices=EXPERIENCE_CHOICES, default=0, |
504 | help_text=_("Level of experience required for this specific opportunity.")) |
505 | |
506 | class Meta: |
507 | @@ -108,6 +107,20 @@ |
508 | summary_list.append(_("Invalid")) |
509 | return summary_list |
510 | |
511 | + |
512 | +class Note(models.Model): |
513 | + opportunity = models.ForeignKey(Opportunity) |
514 | + date = models.DateTimeField(auto_now_add=True) |
515 | + author = models.ForeignKey(User) |
516 | + text = models.CharField(max_length=250) |
517 | + |
518 | + def __unicode__(self): |
519 | + text = self.text |
520 | + if len(text) > 40: |
521 | + text = text[:40]+u"\u2026" |
522 | + return '%s: %s' % (self.author, text) |
523 | + |
524 | + |
525 | class ActionLogEntry(models.Model): |
526 | timestamp = models.DateTimeField(_("Timestamp")) |
527 | who = models.ForeignKey(User) |
528 | |
529 | === modified file 'harvest/opportunities/urls.py' |
530 | --- harvest/opportunities/urls.py 2010-07-30 21:45:23 +0000 |
531 | +++ harvest/opportunities/urls.py 2010-08-13 02:04:41 +0000 |
532 | @@ -1,12 +1,28 @@ |
533 | from django.conf.urls.defaults import * |
534 | |
535 | urlpatterns = patterns('', |
536 | - url(r'^opportunity/(?P<opportunity_id>[\d]+)/edit$', 'opportunities.views.opportunity_edit', name='opportunity_edit'), |
537 | - |
538 | - url(r'^filter$', 'opportunities.views.opportunities_filter', name='opportunities_filter'), |
539 | - |
540 | - url(r'^package/(?P<package_name>.+)', 'opportunities.views.single_package', name='single_package'), |
541 | - |
542 | - url(r'^xhr/results$', 'opportunities.views.opportunities_xhr_filter_results', name='opportunities_xhr_filter_results'), |
543 | - url(r'^xhr/results/(?P<package_id>[\d]+)$', 'opportunities.views.opportunities_xhr_package_details', name='opportunities_xhr_package_details'), |
544 | + url(r'^$', |
545 | + 'opportunities.views.filter', |
546 | + name='filter'), |
547 | + |
548 | + url(r'^package/(?P<package_name>.+)/$', |
549 | + 'opportunities.views.single_package', |
550 | + name='single_package'), |
551 | + |
552 | + url(r'^opportunity/(?P<opportunity_id>[\d]+)/edit/$', |
553 | + 'opportunities.views.opportunity_edit', |
554 | + name='opportunity_edit'), |
555 | + |
556 | + |
557 | + url(r'^xhr/results/$', |
558 | + 'opportunities.views.xhr_filter_results'), |
559 | + |
560 | + url(r'^xhr/results/(?P<package_id>[\d]+)/$', |
561 | + 'opportunities.views.xhr_package_details'), |
562 | + |
563 | + url(r'xhr/opportunity/(?P<opportunity_id>[\d]+)/$', |
564 | + 'opportunities.views.xhr_opportunity_li'), |
565 | + |
566 | + url(r'^xhr/opportunity/(?P<opportunity_id>[\d]+)/edit/$', |
567 | + 'opportunities.views.xhr_opportunity_edit'), |
568 | ) |
569 | |
570 | === modified file 'harvest/opportunities/views.py' |
571 | --- harvest/opportunities/views.py 2010-07-30 21:45:23 +0000 |
572 | +++ harvest/opportunities/views.py 2010-08-13 02:04:41 +0000 |
573 | @@ -13,11 +13,67 @@ |
574 | import models |
575 | import forms |
576 | |
577 | +from models import Opportunity, Note # for form processing |
578 | + |
579 | from filters import HarvestFilters |
580 | from wrappers import PackageWrapper, PackageListWrapper |
581 | |
582 | +def _create_packages_list(request, filters_pkg, filters_opp): |
583 | + # XXX: rockstar: Eep! We shouldn't be storing the None as a string. We |
584 | + # should re-think this model relationship. |
585 | + #sourcepackages_list = models.SourcePackage.objects.exclude(name='None') |
586 | + |
587 | + sourcepackages_list = models.SourcePackage.objects.distinct() |
588 | + sourcepackages_list = filters_pkg.process_queryset(sourcepackages_list) |
589 | + |
590 | + #opportunities_list is filtered right away to only check opportunities belonging to selected packages |
591 | + opportunities_list = models.Opportunity.objects.distinct().filter(sourcepackage__in=sourcepackages_list) |
592 | + opportunities_list = filters_opp.process_queryset(opportunities_list) |
593 | + |
594 | + #TODO: need to filter out opportunities with valid=False again |
595 | + #TODO: would it be more efficient to group opportunities by their sourcepackages first, then run filters_opp.process_queryset() for each of those groups? |
596 | + |
597 | + pkg_list_wrapper = PackageListWrapper(request, sourcepackages_list, opportunities_list) |
598 | + |
599 | + return pkg_list_wrapper |
600 | + |
601 | + |
602 | + |
603 | +def filter(request): |
604 | + filters = HarvestFilters() |
605 | + filters.update_from_http(request) |
606 | + filters_pkg = filters.find('pkg') |
607 | + filters_opp = filters.find('opp') |
608 | + |
609 | + pkg_list_wrapper = _create_packages_list(request, filters_pkg, filters_opp) |
610 | + |
611 | + context = { |
612 | + 'packages_list': pkg_list_wrapper, |
613 | + 'filters_pkg' : filters_pkg, |
614 | + 'filters_opp' : filters_opp |
615 | + } |
616 | + |
617 | + return render( |
618 | + 'opportunities/filter.html', |
619 | + context, |
620 | + context_instance=RequestContext(request)) |
621 | + |
622 | +def single_package(request, package_name): |
623 | + package = get_object_or_404(models.SourcePackage, name=package_name) |
624 | + |
625 | + package_wrapper = PackageWrapper(request, package, visible_opportunities = package.opportunity_set) |
626 | + |
627 | + context = { |
628 | + 'package': package_wrapper |
629 | + } |
630 | + |
631 | + return render( |
632 | + 'opportunities/single_package.html', |
633 | + context, |
634 | + context_instance=RequestContext(request)) |
635 | + |
636 | @login_required |
637 | -def opportunity_edit(request, opportunity_id): |
638 | +def opportunity_edit(request, opportunity_id, template='opportunities/opportunity_edit.html'): |
639 | opportunity = get_object_or_404(models.Opportunity, id=opportunity_id) |
640 | if request.method == "POST": |
641 | form = forms.OpportunityForm(data=request.POST, instance=opportunity) |
642 | @@ -32,68 +88,41 @@ |
643 | models.log_action(request.user, |
644 | action="changed experience to: %s" % form.cleaned_data["experience"], |
645 | opportunity=opportunity) |
646 | - if form.cleaned_data["comment"] != opportunity.comment: |
647 | - if len(form.cleaned_data["comment"]) > 178: |
648 | - action = "changed comment to: '%s'" % (form.cleaned_data["comment"][:177]+u"…") |
649 | - else: |
650 | - action = "changed comment to: '%s'" % form.cleaned_data["comment"] |
651 | - models.log_action(request.user, action=action, |
652 | - opportunity=opportunity) |
653 | form.save() |
654 | + |
655 | + #add a new note if input by the user |
656 | + if form.cleaned_data["new_note"].strip() != '': |
657 | + note_text = form.cleaned_data["new_note"] |
658 | + |
659 | + note_log_text = note_text |
660 | + if len(note_log_text) > 160: |
661 | + note_log_text = note_log_text[:160]+u"\u2026" |
662 | + models.log_action(request.user, |
663 | + action="added note: '%s'" % note_log_text, |
664 | + opportunity=opportunity) |
665 | + |
666 | + note = Note(opportunity=opportunity, author=request.user, text=note_text) |
667 | + note.save() |
668 | + |
669 | return HttpResponseRedirect(request.POST["next"]) |
670 | else: |
671 | request.user.message_set.create(message=_('Opportunity details could not be saved.')) |
672 | else: |
673 | form = forms.OpportunityForm(instance=opportunity) |
674 | - return render('opportunities/opportunity_edit.html', |
675 | + |
676 | + next = '/' |
677 | + if 'next' in request.GET: next = request.GET['next'] |
678 | + |
679 | + return render(template, |
680 | {'form': form, |
681 | 'opportunity':opportunity, |
682 | 'user':request.user, |
683 | - 'next': request.GET['next'], |
684 | + 'next': next, |
685 | }, RequestContext(request)) |
686 | |
687 | |
688 | -def _create_packages_list(request, filters_pkg, filters_opp): |
689 | - # XXX: rockstar: Eep! We shouldn't be storing the None as a string. We |
690 | - # should re-think this model relationship. |
691 | - #sourcepackages_list = models.SourcePackage.objects.exclude(name='None') |
692 | - |
693 | - sourcepackages_list = models.SourcePackage.objects.distinct() |
694 | - sourcepackages_list = filters_pkg.process_queryset(sourcepackages_list) |
695 | - |
696 | - #opportunities_list is filtered right away to only check opportunities belonging to selected packages |
697 | - opportunities_list = models.Opportunity.objects.distinct().filter(sourcepackage__in=sourcepackages_list) |
698 | - opportunities_list = filters_opp.process_queryset(opportunities_list) |
699 | - |
700 | - #TODO: need to filter out opportunities with valid=False again |
701 | - #TODO: would it be more efficient to group opportunities by their sourcepackages first, then run filters_opp.process_queryset() for each of those groups? |
702 | - |
703 | - pkg_list_wrapper = PackageListWrapper(request, sourcepackages_list, opportunities_list) |
704 | - |
705 | - return pkg_list_wrapper |
706 | - |
707 | - |
708 | -def opportunities_filter(request): |
709 | - filters = HarvestFilters() |
710 | - filters.update_from_http(request) |
711 | - filters_pkg = filters.find('pkg') |
712 | - filters_opp = filters.find('opp') |
713 | - |
714 | - pkg_list_wrapper = _create_packages_list(request, filters_pkg, filters_opp) |
715 | - |
716 | - context = { |
717 | - 'packages_list': pkg_list_wrapper, |
718 | - 'filters_pkg' : filters_pkg, |
719 | - 'filters_opp' : filters_opp |
720 | - } |
721 | - |
722 | - return render( |
723 | - 'opportunities/filter.html', |
724 | - context, |
725 | - context_instance=RequestContext(request)) |
726 | - |
727 | - |
728 | -def opportunities_xhr_filter_results(request): |
729 | + |
730 | +def xhr_filter_results(request): |
731 | filters = HarvestFilters() |
732 | filters.update_from_http(request) |
733 | |
734 | @@ -108,12 +137,11 @@ |
735 | context, |
736 | context_instance=RequestContext(request)) |
737 | |
738 | - |
739 | -def opportunities_xhr_package_details(request, package_id): |
740 | +def xhr_package_details(request, package_id): |
741 | filters = HarvestFilters() |
742 | filters.update_from_http(request) |
743 | |
744 | - package = models.SourcePackage.objects.get(id=package_id) |
745 | + package = get_object_or_404(models.SourcePackage, id=package_id) |
746 | |
747 | opportunities_list = filters.find('opp').process_queryset(package.opportunity_set).all() |
748 | |
749 | @@ -128,18 +156,21 @@ |
750 | context, |
751 | context_instance=RequestContext(request)) |
752 | |
753 | -def single_package(request, package_name): |
754 | - package = models.SourcePackage.objects.get(name=package_name) |
755 | - |
756 | - package_wrapper = PackageWrapper(request, package, visible_opportunities = package.opportunity_set) |
757 | +def xhr_opportunity_li(request, opportunity_id): |
758 | + opportunity = get_object_or_404(models.Opportunity, id=opportunity_id) |
759 | |
760 | context = { |
761 | - 'package': package_wrapper |
762 | + 'opportunity': opportunity |
763 | } |
764 | |
765 | return render( |
766 | - 'opportunities/single_package.html', |
767 | + 'opportunities/xhr/opportunity_outer_li.html', |
768 | context, |
769 | context_instance=RequestContext(request)) |
770 | |
771 | +def xhr_opportunity_edit(request, opportunity_id): |
772 | + return opportunity_edit( |
773 | + request, |
774 | + opportunity_id, |
775 | + template='opportunities/xhr/opportunity_edit.html') |
776 | |
777 | |
778 | === modified file 'harvest/templates/base.html' |
779 | --- harvest/templates/base.html 2010-07-21 20:21:14 +0000 |
780 | +++ harvest/templates/base.html 2010-08-13 02:04:41 +0000 |
781 | @@ -26,7 +26,7 @@ |
782 | <div id="container"> |
783 | |
784 | <div id="header"> |
785 | - <span id="pagetitle"> |
786 | + <span id="sitetitle"> |
787 | <img id="sitelogo" src="{{ MEDIA_URL }}img/logo_humanity-search-icon.png" /> |
788 | <h1 id="sitename">{% trans "Harvest" %}</h1> |
789 | {% if harvest_version_name %}<span id="releasename">{{harvest_version_name}}</span>{% endif %} |
790 | @@ -59,7 +59,7 @@ |
791 | |
792 | <div id="footer"> |
793 | <div id="footnav"><nav> |
794 | - <a class="title" href="{% url home %}" tabindex="2">{% trans "Harvest" %}</a> <a href="http://answers.launchpad.net/harvest" tabindex="2">{% trans "Help" %}</a> <a href="http://bugs.launchpad.net/harvest" tabindex="2">{% trans "Bugs" %}</a> <a href="http://launchpad.net/harvest" tabindex="2">{% trans "Code" %}</a> |
795 | + <a class="title" href="{% url home %}" tabindex="2">{% trans "Harvest" %}</a> <a href="http://answers.launchpad.net/harvest" target="_blank" tabindex="2">{% trans "Help" %}</a> <a href="http://bugs.launchpad.net/harvest" target="_blank" tabindex="2">{% trans "Bugs" %}</a> <a href="http://launchpad.net/harvest" target="_blank" tabindex="2">{% trans "Code" %}</a> |
796 | </nav></div> |
797 | |
798 | <div id="smallprint" tabindex="3"> |
799 | |
800 | === added file 'harvest/templates/one_column.html' |
801 | --- harvest/templates/one_column.html 1970-01-01 00:00:00 +0000 |
802 | +++ harvest/templates/one_column.html 2010-08-13 02:04:41 +0000 |
803 | @@ -0,0 +1,9 @@ |
804 | +{% extends "base.html" %} |
805 | +{% load i18n %} |
806 | + |
807 | +{% block content %} |
808 | +<h2 class="pagetitle">{% block pagetitle %}{% endblock %}</h2> |
809 | +<div class="main"> |
810 | + {% block content_main %}{% endblock %} |
811 | +</div> |
812 | +{% endblock %} |
813 | \ No newline at end of file |
814 | |
815 | === modified file 'harvest/templates/opportunities/filter.html' |
816 | --- harvest/templates/opportunities/filter.html 2010-07-30 21:45:23 +0000 |
817 | +++ harvest/templates/opportunities/filter.html 2010-08-13 02:04:41 +0000 |
818 | @@ -10,7 +10,7 @@ |
819 | {{filters_opp.render}} |
820 | </div> |
821 | |
822 | -<div id="results-pane" data-results-url="{% url opportunities_xhr_filter_results %}"> |
823 | +<div id="results-pane"> |
824 | <div id="results-status"></div> |
825 | <div id="results"> |
826 | {% include "opportunities/include/filter_results.html" %} |
827 | |
828 | === modified file 'harvest/templates/opportunities/include/filter_results.html' |
829 | --- harvest/templates/opportunities/include/filter_results.html 2010-07-30 08:23:24 +0000 |
830 | +++ harvest/templates/opportunities/include/filter_results.html 2010-08-13 02:04:41 +0000 |
831 | @@ -3,7 +3,7 @@ |
832 | {% if packages_list %} |
833 | <ul> |
834 | {% for package in packages_list.get_visible_packages %} |
835 | - <li data-results-packageid="{{ package.real.id }}" class="sourcepackage {% if package.expanded %}expanded{% else %}collapsed{% endif %}"> |
836 | + <li data-package-id="{{ package.real.id }}" class="sourcepackage {% if package.expanded %}expanded{% else %}collapsed{% endif %}"> |
837 | <a class="sourcepackage-header" href="{{ package.get_expand_toggle_url }}"> |
838 | <h2 class="sourcepackage-name">{{ package.real.name }}</h2> |
839 | <span class="status"></span> |
840 | |
841 | === modified file 'harvest/templates/opportunities/include/opportunity.html' |
842 | --- harvest/templates/opportunities/include/opportunity.html 2010-07-30 21:45:23 +0000 |
843 | +++ harvest/templates/opportunities/include/opportunity.html 2010-08-13 02:04:41 +0000 |
844 | @@ -3,16 +3,14 @@ |
845 | <div class="opportunity-header"> |
846 | <a href="{{opportunity.url}}" class="opportunity-description" target="_blank">{{ opportunity.description }}</a> |
847 | {% if user.is_authenticated %} |
848 | - <a href="{% url opportunity_edit opportunity.id %}?next={{request.get_full_path}}" class="opportunity-edit-button">edit</a> |
849 | + <a href="{% url opportunity_edit opportunity.id %}?next={{request.get_full_path}}" target="_blank" class="opportunity-edit-button">edit</a> |
850 | {% endif %} |
851 | <span class="opportunity-summary"> |
852 | {{ opportunity.summary|join:', ' }} |
853 | </span> |
854 | </div> |
855 | <div class="opportunity-details"> |
856 | - {% if opportunity.comment %} |
857 | - <span class="opportunity-status">{{ opportunity.comment }}</span> |
858 | - {% endif %} |
859 | + {% include "opportunities/include/opportunity_details.html" %} |
860 | </div> |
861 | <div class="bottom"></div> |
862 | |
863 | |
864 | === added file 'harvest/templates/opportunities/include/opportunity_details.html' |
865 | --- harvest/templates/opportunities/include/opportunity_details.html 1970-01-01 00:00:00 +0000 |
866 | +++ harvest/templates/opportunities/include/opportunity_details.html 2010-08-13 02:04:41 +0000 |
867 | @@ -0,0 +1,7 @@ |
868 | +{% ifnotequal opportunity.note_set.count 0 %} |
869 | +<div class="opportunity-notes"> |
870 | + <ul> |
871 | + {% include "opportunities/include/opportunity_notes_list.html" %} |
872 | + </ul> |
873 | +</div> |
874 | +{% endifnotequal %} |
875 | \ No newline at end of file |
876 | |
877 | === added file 'harvest/templates/opportunities/include/opportunity_details_edit.html' |
878 | --- harvest/templates/opportunities/include/opportunity_details_edit.html 1970-01-01 00:00:00 +0000 |
879 | +++ harvest/templates/opportunities/include/opportunity_details_edit.html 2010-08-13 02:04:41 +0000 |
880 | @@ -0,0 +1,48 @@ |
881 | +{% load i18n %} |
882 | + |
883 | +<form action="{{ request.path_info }}" method="POST"> |
884 | + <div class="opportunity-notes"> |
885 | + {% with form.new_note as field %} |
886 | + <span class="separate-top {% if field.required %}required{% endif %} {% if field.errors %}error{% endif %}"> |
887 | + {{field.errors}} |
888 | + <input type="text" name="new_note" id="new_note" placeholder="{{field.label}}" {% if form.new_note.data %}value="{{form.new_note.data}}"{% endif %} /> |
889 | + {% endwith %} |
890 | + </span> |
891 | + <ul> |
892 | + {% include "opportunities/include/opportunity_notes_list.html" %} |
893 | + </ul> |
894 | + <div class="bottom"></div> |
895 | + </div> |
896 | + |
897 | + <ul class="opportunity-switches"> |
898 | + {% with form.experience as field %} |
899 | + <li class="separate-top {% if field.required %}required{% endif %} {% if field.errors %}error{% endif %}"> |
900 | + {{field.errors}} |
901 | + {{field}} |
902 | + {{field.label_tag}} |
903 | + </li> |
904 | + {% endwith %} |
905 | + |
906 | + {% with form.applied as field %} |
907 | + <li class="{% if field.required %}required{% endif %} {% if field.errors %}error{% endif %}"> |
908 | + {{field.errors}} |
909 | + {{field}} |
910 | + {{field.label_tag}} |
911 | + </li> |
912 | + {% endwith %} |
913 | + |
914 | + {% with form.reviewed as field %} |
915 | + <li class="{% if field.required %}required{% endif %} {% if field.errors %}error{% endif %}"> |
916 | + {{field.errors}} |
917 | + {{field}} |
918 | + {{field.label_tag}} |
919 | + </li> |
920 | + {% endwith %} |
921 | + </ul> |
922 | + |
923 | + <div class="actions"> |
924 | + <input type="hidden" name="next" value="{{ next }}" /> |
925 | + <input type="submit" value="{% trans 'Apply changes' %}" /> |
926 | + <a href="{{next}}" rel="deactivate"><button>Cancel</button></a> |
927 | + </div> |
928 | +</form> |
929 | |
930 | === added file 'harvest/templates/opportunities/include/opportunity_li.html' |
931 | --- harvest/templates/opportunities/include/opportunity_li.html 1970-01-01 00:00:00 +0000 |
932 | +++ harvest/templates/opportunities/include/opportunity_li.html 2010-08-13 02:04:41 +0000 |
933 | @@ -0,0 +1,3 @@ |
934 | +<li class="opportunity" data-opportunity-experience="{{opportunity.experience}}" {% if opportunity.reviewed %}data-opportunity-irrelevant{% endif %} {% if opportunity.applied %}data-opportunity-applied{% endif %}> |
935 | + {% include "opportunities/include/opportunity.html" %} |
936 | +</li> |
937 | |
938 | === added file 'harvest/templates/opportunities/include/opportunity_notes_list.html' |
939 | --- harvest/templates/opportunities/include/opportunity_notes_list.html 1970-01-01 00:00:00 +0000 |
940 | +++ harvest/templates/opportunities/include/opportunity_notes_list.html 2010-08-13 02:04:41 +0000 |
941 | @@ -0,0 +1,9 @@ |
942 | +{% load i18n %} |
943 | +{% load humanize_timediff %} |
944 | + |
945 | +{% for note in opportunity.note_set.all|dictsortreversed:"date" %} |
946 | +<li> |
947 | + {{ note.text }} |
948 | + <span class="signature">{% blocktrans with note.date|humanize_timediff as timesince and note.author as author %}{{author}}, {{timesince}} ago{% endblocktrans %}</span> |
949 | +</li> |
950 | +{% endfor %} |
951 | |
952 | === added file 'harvest/templates/opportunities/include/opportunity_outer_li.html' |
953 | --- harvest/templates/opportunities/include/opportunity_outer_li.html 1970-01-01 00:00:00 +0000 |
954 | +++ harvest/templates/opportunities/include/opportunity_outer_li.html 2010-08-13 02:04:41 +0000 |
955 | @@ -0,0 +1,3 @@ |
956 | +<li class="opportunity" data-opportunity-id="{{opportunity.id}}" data-opportunity-experience="{{opportunity.experience}}" {% if opportunity.reviewed %}data-opportunity-irrelevant{% endif %} {% if opportunity.applied %}data-opportunity-applied{% endif %}> |
957 | + {% include "opportunities/include/opportunity.html" %} |
958 | +</li> |
959 | |
960 | === modified file 'harvest/templates/opportunities/include/package_details.html' |
961 | --- harvest/templates/opportunities/include/package_details.html 2010-07-31 20:22:58 +0000 |
962 | +++ harvest/templates/opportunities/include/package_details.html 2010-08-13 02:04:41 +0000 |
963 | @@ -11,9 +11,7 @@ |
964 | <ul> |
965 | {# FIXME: use |dictsort:'experience'|dictsort:'description' here (see comment in wrappers.py) #} |
966 | {% for opportunity in opplist.list %} |
967 | - <li class="opportunity" data-opportunity-experience="{{opportunity.experience}}" {% if opportunity.reviewed %}data-opportunity-irrelevant{% endif %} {% if opportunity.applied %}data-opportunity-applied{% endif %}> |
968 | - {% include "opportunities/include/opportunity.html" %} |
969 | - </li> |
970 | + {% include "opportunities/include/opportunity_outer_li.html" %} |
971 | {% endfor %} |
972 | </ul> |
973 | </div> |
974 | |
975 | === modified file 'harvest/templates/opportunities/opportunity_edit.html' |
976 | --- harvest/templates/opportunities/opportunity_edit.html 2010-07-30 08:23:24 +0000 |
977 | +++ harvest/templates/opportunities/opportunity_edit.html 2010-08-13 02:04:41 +0000 |
978 | @@ -1,17 +1,14 @@ |
979 | -{% extends "base.html" %} |
980 | +{% extends "one_column.html" %} |
981 | {% load i18n %} |
982 | |
983 | -{% block content %} |
984 | - <div class="opportunity"> |
985 | - {% include "opportunities/include/opportunity.html" %} |
986 | - </div> |
987 | - <div id="form"><form action="{{ request.path_info }}" method="POST"> |
988 | - {% if form.errors %} |
989 | - <p style="color: red;">{% trans "Please correct the error" %} {{ form.errors|pluralize }} below.</p> |
990 | - {% endif %} |
991 | - <table>{{ form.as_table }}</table> |
992 | - <td><input type="hidden" name="next" value="{{ next }}" /> </td> |
993 | - <td><input type="submit" value='{% trans "Update Information Now!" %}' /></td> |
994 | - <td><a href="{{next}}" rel="deactivate"><button>Cancel</button></a></td> |
995 | - </form></div> |
996 | +{% block title %}{{ block.super }}: {{ opportunity.description }}{% endblock %} |
997 | + |
998 | +{% block pagetitle %} |
999 | +Opportunity <a href="{{opportunity.url}}" class="opportunity-description" target="_blank">{{ opportunity.description }}</a> in {% with opportunity.sourcepackage.name as pkgname %}<a href="{% url single_package pkgname %}">{{ pkgname }}</a>{% endwith %} |
1000 | +{% endblock %} |
1001 | + |
1002 | +{% block content_main %} |
1003 | +<div class="opportunity-details edit"> |
1004 | + {% include "opportunities/include/opportunity_details_edit.html" %} |
1005 | +</div> |
1006 | {% endblock %} |
1007 | |
1008 | === modified file 'harvest/templates/opportunities/single_package.html' |
1009 | --- harvest/templates/opportunities/single_package.html 2010-07-30 21:45:23 +0000 |
1010 | +++ harvest/templates/opportunities/single_package.html 2010-08-13 02:04:41 +0000 |
1011 | @@ -1,20 +1,13 @@ |
1012 | -{% extends "base.html" %} |
1013 | +{% extends "one_column.html" %} |
1014 | {% load i18n %} |
1015 | |
1016 | {% block title %}{{ block.super }}: {{ package.real.name }}{% endblock %} |
1017 | |
1018 | -{% block content %} |
1019 | +{% block pagetitle %}{{ package.real.name }}{% endblock %} |
1020 | |
1021 | -<div class="sourcepackage"> |
1022 | - <div class="sourcepackage-header"> |
1023 | - <h2 class="sourcepackage-name">{{ package.real.name }}</h2> |
1024 | - {% comment %}<span class="sourcepackage-summary"></span>{% endcomment %} |
1025 | - <div class="bottom"></div> |
1026 | - </div> |
1027 | - <div class="sourcepackage-details"> |
1028 | - {% include "opportunities/include/package_details.html" %} |
1029 | - </div> |
1030 | +{% block content_main %} |
1031 | +<div class="sourcepackage-details"> |
1032 | + {% include "opportunities/include/package_details.html" %} |
1033 | </div> |
1034 | - |
1035 | {% endblock %} |
1036 | |
1037 | |
1038 | === added file 'harvest/templates/opportunities/xhr/opportunity_edit.html' |
1039 | --- harvest/templates/opportunities/xhr/opportunity_edit.html 1970-01-01 00:00:00 +0000 |
1040 | +++ harvest/templates/opportunities/xhr/opportunity_edit.html 2010-08-13 02:04:41 +0000 |
1041 | @@ -0,0 +1,3 @@ |
1042 | +{% load i18n %} |
1043 | +{% include "opportunities/include/opportunity_details_edit.html" %} |
1044 | + |
1045 | |
1046 | === added file 'harvest/templates/opportunities/xhr/opportunity_li.html' |
1047 | --- harvest/templates/opportunities/xhr/opportunity_li.html 1970-01-01 00:00:00 +0000 |
1048 | +++ harvest/templates/opportunities/xhr/opportunity_li.html 2010-08-13 02:04:41 +0000 |
1049 | @@ -0,0 +1,3 @@ |
1050 | +{% load i18n %} |
1051 | +{% include "opportunities/include/opportunity_li.html" %} |
1052 | + |
1053 | |
1054 | === added file 'harvest/templates/opportunities/xhr/opportunity_outer_li.html' |
1055 | --- harvest/templates/opportunities/xhr/opportunity_outer_li.html 1970-01-01 00:00:00 +0000 |
1056 | +++ harvest/templates/opportunities/xhr/opportunity_outer_li.html 2010-08-13 02:04:41 +0000 |
1057 | @@ -0,0 +1,3 @@ |
1058 | +{% load i18n %} |
1059 | +{% include "opportunities/include/opportunity_outer_li.html" %} |
1060 | + |
Oh, I should mention: Note adds a new table to the database, and the Comment field in Opportunity is removed (replaced with note_set via the OneToMany relationship).
You'll need to run ./manage.py syncdb to get that all working right. It shouldn't cause any problems given that the comment field hasn't been used for anything so far.