Merge lp:~aelkner/schooltool.gradebook/flourish into lp:schooltool.gradebook/flourish
- flourish
- Merge into flourish
Proposed by
Gediminas Paulauskas
Status: | Rejected |
---|---|
Rejected by: | Alan Elkner |
Proposed branch: | lp:~aelkner/schooltool.gradebook/flourish |
Merge into: | lp:schooltool.gradebook/flourish |
Diff against target: |
1514 lines (+1162/-21) (has conflicts) 22 files modified
CHANGES.txt (+4/-0) src/schooltool/gradebook/README.txt (+19/-0) src/schooltool/gradebook/activity.py (+55/-2) src/schooltool/gradebook/browser/course_worksheets.py (+452/-0) src/schooltool/gradebook/browser/flourish.zcml (+180/-10) src/schooltool/gradebook/browser/gradebook.py (+10/-2) src/schooltool/gradebook/browser/report_card.py (+14/-0) src/schooltool/gradebook/browser/resources/f_gradebook.css (+5/-0) src/schooltool/gradebook/browser/templates/f_course_worksheet_edit.pt (+45/-0) src/schooltool/gradebook/browser/templates/f_course_worksheet_templates.pt (+26/-0) src/schooltool/gradebook/browser/templates/f_course_worksheets.pt (+111/-0) src/schooltool/gradebook/browser/templates/f_deploy_as_course_worksheet.pt (+61/-0) src/schooltool/gradebook/browser/templates/f_hide_unhide_course_worksheets.pt (+44/-0) src/schooltool/gradebook/browser/templates/f_manage_course_worksheet_templates.pt (+10/-0) src/schooltool/gradebook/browser/templates/f_manage_course_worksheets.pt (+21/-0) src/schooltool/gradebook/browser/templates/f_manage_report_sheet_templates_overview.pt (+12/-0) src/schooltool/gradebook/browser/templates/f_manage_report_sheets_overview.pt (+2/-2) src/schooltool/gradebook/browser/templates/f_template_manage.pt (+1/-1) src/schooltool/gradebook/browser/templates/f_templates_overview.pt (+4/-0) src/schooltool/gradebook/configure.zcml (+51/-0) src/schooltool/gradebook/interfaces.py (+28/-3) src/schooltool/gradebook/tests/test_gradebook.py (+7/-1) Text conflict in CHANGES.txt |
To merge this branch: | bzr merge lp:~aelkner/schooltool.gradebook/flourish |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Gediminas Paulauskas (community) | Needs Fixing | ||
Review via email: mp+86728@code.launchpad.net |
Commit message
Description of the change
Don't you think such a new big feature, that no one understands until they see it, implies a need for a merge request?
+ At a time when I have said I am making a 2.0.1 release
+ 3 test failures!
+ Behavior has changed, as evidenced by broken tests
To post a comment you must log in.
Revision history for this message
Gediminas Paulauskas (menesis) wrote : | # |
Tests have to be looked at, and something needs fixing.
I don't see any tests or documentation on this feature.
Except a few lines in src/schooltool/
No "What's this?" description of a new feature.
review:
Needs Fixing
Revision history for this message
Tom Hoffman (tom-hoffman) wrote : | # |
This doesn't need to be merged right now -- we'll be returning to these issues after the holidays.
- 415. By Gediminas Paulauskas
-
Preparing release 2.0.1
- 416. By Gediminas Paulauskas
-
Back to development: 2.0.2
Unmerged revisions
- 476. By Alan Elkner
-
merged with trunk
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'CHANGES.txt' |
2 | --- CHANGES.txt 2011-12-22 15:15:53 +0000 |
3 | +++ CHANGES.txt 2011-12-22 16:21:13 +0000 |
4 | @@ -6,7 +6,11 @@ |
5 | ------------------ |
6 | |
7 | - Allow scoresystem point value be equal to the previous grade (https://launchpad.net/bugs/899228) |
8 | +<<<<<<< TREE |
9 | - Updated translations |
10 | +======= |
11 | +- Added course worksheets feature |
12 | +>>>>>>> MERGE-SOURCE |
13 | |
14 | |
15 | 2.0.0 (2011-11-22) |
16 | |
17 | === modified file 'src/schooltool/gradebook/README.txt' |
18 | --- src/schooltool/gradebook/README.txt 2011-08-30 17:24:02 +0000 |
19 | +++ src/schooltool/gradebook/README.txt 2011-12-22 16:21:13 +0000 |
20 | @@ -661,3 +661,22 @@ |
21 | >>> linked_activity.scoresystem.max |
22 | Decimal("20") |
23 | |
24 | +Course Activities |
25 | +----------------- |
26 | + |
27 | +Course leaders can create a set of worksheets that they can later choose to |
28 | +deploy to all the sections of that course for specific terms or the whole |
29 | +school year. There is an adapter that returns this set, which it locates |
30 | +in the course's annotations. |
31 | + |
32 | + >>> alg1_act = interfaces.ICourseActivities(alg1) |
33 | + >>> alg1_act |
34 | + CourseActivities(u'Course Activities') |
35 | + |
36 | +There is also an adapter that returns the deployed worksheets for the course, |
37 | +also stored as annotations. |
38 | + |
39 | + >>> alg1_deployed = interfaces.ICourseDeployedWorksheets(alg1) |
40 | + >>> alg1_deployed |
41 | + CourseDeployedWorksheets(u'Deployed Worksheets') |
42 | + |
43 | |
44 | === modified file 'src/schooltool/gradebook/activity.py' |
45 | --- src/schooltool/gradebook/activity.py 2011-09-01 13:46:58 +0000 |
46 | +++ src/schooltool/gradebook/activity.py 2011-12-22 16:21:13 +0000 |
47 | @@ -37,6 +37,7 @@ |
48 | from schooltool.app.interfaces import ISchoolToolApplication |
49 | from schooltool.gradebook import GradebookMessage as _ |
50 | from schooltool.requirement import requirement, scoresystem |
51 | +from schooltool.requirement.interfaces import IRangedValuesScoreSystem |
52 | from schooltool.gradebook import interfaces |
53 | from schooltool.term.interfaces import IDateManager |
54 | from schooltool.course.interfaces import ISection |
55 | @@ -44,6 +45,8 @@ |
56 | ACTIVITIES_KEY = 'schooltool.gradebook.activities' |
57 | CURRENT_WORKSHEET_KEY = 'schooltool.gradebook.currentworksheet' |
58 | CATEGORY_WEIGHTS_KEY = 'schooltool.gradebook.categoryweights' |
59 | +COURSE_ACTIVITIES_KEY = 'schooltool.gradebook.course_activities' |
60 | +COURSE_DEPLOYED_WORKSHEETS_KEY = 'schooltool.gradebook.course_deployed' |
61 | |
62 | |
63 | def ensureAtLeastOneWorksheet(activities): |
64 | @@ -170,6 +173,14 @@ |
65 | return [] |
66 | |
67 | |
68 | +class CourseActivities(requirement.Requirement): |
69 | + zope.interface.implements(interfaces.ICourseActivities) |
70 | + |
71 | + |
72 | +class CourseDeployedWorksheets(requirement.Requirement): |
73 | + zope.interface.implements(interfaces.ICourseDeployedWorksheets) |
74 | + |
75 | + |
76 | class Worksheet(requirement.Requirement): |
77 | zope.interface.implements(interfaces.IWorksheet, |
78 | annotation.interfaces.IAttributeAnnotatable) |
79 | @@ -198,6 +209,12 @@ |
80 | ann[CATEGORY_WEIGHTS_KEY] = persistent.dict.PersistentDict() |
81 | ann[CATEGORY_WEIGHTS_KEY][category] = weight |
82 | |
83 | + def canAverage(self): |
84 | + for activity in self.values(): |
85 | + if IRangedValuesScoreSystem(activity.scoresystem, None) is None: |
86 | + return False |
87 | + return True |
88 | + |
89 | |
90 | class ReportWorksheet(requirement.Requirement): |
91 | zope.interface.implements(interfaces.IReportWorksheet) |
92 | @@ -205,6 +222,12 @@ |
93 | deployed = False |
94 | |
95 | |
96 | +class CourseWorksheet(requirement.Requirement): |
97 | + zope.interface.implements(interfaces.ICourseWorksheet) |
98 | + |
99 | + deployed = False |
100 | + |
101 | + |
102 | class Activity(requirement.Requirement): |
103 | zope.interface.implements(interfaces.IActivity) |
104 | |
105 | @@ -237,8 +260,6 @@ |
106 | return annotations[ACTIVITIES_KEY] |
107 | except KeyError: |
108 | activities = Activities(_('Activities')) |
109 | - # Make sure that the sections activities include all the activities of |
110 | - # the courses as well |
111 | annotations[ACTIVITIES_KEY] = activities |
112 | zope.container.contained.contained( |
113 | activities, context, 'activities') |
114 | @@ -248,6 +269,38 @@ |
115 | getSectionActivities.factory = Activities |
116 | |
117 | |
118 | +def getCourseActivities(context): |
119 | + '''IAttributeAnnotatable object to ICourseActivities adapter.''' |
120 | + annotations = annotation.interfaces.IAnnotations(context) |
121 | + try: |
122 | + return annotations[COURSE_ACTIVITIES_KEY] |
123 | + except KeyError: |
124 | + activities = CourseActivities(_('Course Activities')) |
125 | + annotations[COURSE_ACTIVITIES_KEY] = activities |
126 | + zope.container.contained.contained( |
127 | + activities, context, 'activities') |
128 | + return activities |
129 | + |
130 | +# Convention to make adapter introspectable |
131 | +getCourseActivities.factory = CourseActivities |
132 | + |
133 | + |
134 | +def getCourseDeployedWorksheets(context): |
135 | + '''IAttributeAnnotatable object to ICourseDeployedWorksheets adapter.''' |
136 | + annotations = annotation.interfaces.IAnnotations(context) |
137 | + try: |
138 | + return annotations[COURSE_DEPLOYED_WORKSHEETS_KEY] |
139 | + except KeyError: |
140 | + worksheets = CourseDeployedWorksheets(_('Deployed Worksheets')) |
141 | + annotations[COURSE_DEPLOYED_WORKSHEETS_KEY] = worksheets |
142 | + zope.container.contained.contained( |
143 | + worksheets, context, 'deployed_worksheets') |
144 | + return worksheets |
145 | + |
146 | +# Convention to make adapter introspectable |
147 | +getCourseDeployedWorksheets.factory = CourseDeployedWorksheets |
148 | + |
149 | + |
150 | class LinkedActivity(Activity): |
151 | zope.interface.implements(interfaces.ILinkedActivity) |
152 | |
153 | |
154 | === added file 'src/schooltool/gradebook/browser/course_worksheets.py' |
155 | --- src/schooltool/gradebook/browser/course_worksheets.py 1970-01-01 00:00:00 +0000 |
156 | +++ src/schooltool/gradebook/browser/course_worksheets.py 2011-12-22 16:21:13 +0000 |
157 | @@ -0,0 +1,452 @@ |
158 | +# |
159 | +# SchoolTool - common information systems platform for school administration |
160 | +# Copyright (c) 2005 Shuttleworth Foundation |
161 | +# |
162 | +# This program is free software; you can redistribute it and/or modify |
163 | +# it under the terms of the GNU General Public License as published by |
164 | +# the Free Software Foundation; either version 2 of the License, or |
165 | +# (at your option) any later version. |
166 | +# |
167 | +# This program is distributed in the hope that it will be useful, |
168 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
169 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
170 | +# GNU General Public License for more details. |
171 | +# |
172 | +# You should have received a copy of the GNU General Public License |
173 | +# along with this program; if not, write to the Free Software |
174 | +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
175 | +# |
176 | +""" |
177 | +Course Worksheet Views |
178 | +""" |
179 | + |
180 | +from zope.container.interfaces import INameChooser |
181 | +from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile |
182 | +from zope.security.checker import canWrite |
183 | +from zope.security.interfaces import Unauthorized |
184 | +from zope.security.proxy import removeSecurityProxy |
185 | +from zope.traversing.api import getName |
186 | +from zope.traversing.browser.absoluteurl import absoluteURL |
187 | +from zope.i18n import translate |
188 | + |
189 | +from z3c.form import form, field, button |
190 | + |
191 | +from schooltool.app.interfaces import ISchoolToolApplication |
192 | +from schooltool.gradebook import GradebookMessage as _ |
193 | +from schooltool.common.inlinept import InheritTemplate |
194 | +from schooltool.common.inlinept import InlineViewPageTemplate |
195 | +from schooltool.course.interfaces import ISectionContainer, ISection |
196 | +from schooltool.person.interfaces import IPerson |
197 | +from schooltool.schoolyear.interfaces import ISchoolYear |
198 | +from schooltool.schoolyear.interfaces import ISchoolYearContainer |
199 | +from schooltool.skin import flourish |
200 | +from schooltool.skin.flourish.page import TertiaryNavigationManager |
201 | +from schooltool.term.interfaces import ITerm |
202 | + |
203 | +from schooltool.gradebook.interfaces import (IActivities, ICourseActivities, |
204 | + ICourseWorksheet, ICourseDeployedWorksheets, IGradebookRoot) |
205 | +from schooltool.gradebook.activity import CourseWorksheet, Activity, Worksheet |
206 | +from schooltool.gradebook.browser.activity import (FlourishActivityAddView, |
207 | + FlourishActivityEditView) |
208 | +from schooltool.gradebook.browser.report_card import copyActivities |
209 | + |
210 | + |
211 | +class FlourishCourseTemplatesView(flourish.page.Page): |
212 | + """A flourish view for managing course worksheet templates""" |
213 | + |
214 | + @property |
215 | + def title(self): |
216 | + return self.context.__parent__.title |
217 | + |
218 | + @property |
219 | + def worksheets(self): |
220 | + return tuple(removeSecurityProxy(self.context).values()) |
221 | + |
222 | + |
223 | +class FlourishCourseWorksheetsLinks(flourish.page.RefineLinksViewlet): |
224 | + """flourish course worksheet templates add links viewlet.""" |
225 | + |
226 | + |
227 | +class FlourishCourseWorksheetAddView(flourish.form.AddForm): |
228 | + """flourish view for adding a course worksheet.""" |
229 | + |
230 | + fields = field.Fields(ICourseWorksheet).select('title') |
231 | + template = InheritTemplate(flourish.page.Page.template) |
232 | + label = None |
233 | + legend = _('Course Worksheet Details') |
234 | + |
235 | + @property |
236 | + def title(self): |
237 | + return self.context.__parent__.title |
238 | + |
239 | + @button.buttonAndHandler(_('Submit'), name='add') |
240 | + def handleAdd(self, action): |
241 | + super(FlourishCourseWorksheetAddView, self).handleAdd.func(self, action) |
242 | + |
243 | + @button.buttonAndHandler(_("Cancel")) |
244 | + def handle_cancel_action(self, action): |
245 | + url = absoluteURL(self.context, self.request) |
246 | + self.request.response.redirect(url) |
247 | + |
248 | + def create(self, data): |
249 | + worksheet = CourseWorksheet(data['title']) |
250 | + return worksheet |
251 | + |
252 | + def add(self, worksheet): |
253 | + chooser = INameChooser(self.context) |
254 | + name = chooser.chooseName(worksheet.title, worksheet) |
255 | + self.context[name] = worksheet |
256 | + self._worksheet = worksheet |
257 | + return worksheet |
258 | + |
259 | + def nextURL(self): |
260 | + return absoluteURL(self.context, self.request) |
261 | + |
262 | + def updateActions(self): |
263 | + super(FlourishCourseWorksheetAddView, self).updateActions() |
264 | + self.actions['add'].addClass('button-ok') |
265 | + self.actions['cancel'].addClass('button-cancel') |
266 | + |
267 | + |
268 | +class FlourishCourseWorksheetEditView(flourish.form.Form, form.EditForm): |
269 | + |
270 | + template = InheritTemplate(flourish.page.Page.template) |
271 | + label = None |
272 | + legend = _('Course Worksheet Template Information') |
273 | + fields = field.Fields(ICourseWorksheet).select('title') |
274 | + |
275 | + @property |
276 | + def title(self): |
277 | + return self.context.title |
278 | + |
279 | + def update(self): |
280 | + if 'form-submitted' in self.request: |
281 | + for activity in self.context.values(): |
282 | + name = 'delete.%s' % activity.__name__ |
283 | + if name in self.request: |
284 | + del self.context[activity.__name__] |
285 | + break |
286 | + return form.EditForm.update(self) |
287 | + |
288 | + @button.buttonAndHandler(_('Submit'), name='apply') |
289 | + def handleApply(self, action): |
290 | + super(FlourishCourseWorksheetEditView, self).handleApply.func(self, action) |
291 | + # XXX: hacky sucessful submit check |
292 | + if (self.status == self.successMessage or |
293 | + self.status == self.noChangesMessage): |
294 | + self.request.response.redirect(self.nextURL()) |
295 | + |
296 | + @button.buttonAndHandler(_("Cancel")) |
297 | + def handle_cancel_action(self, action): |
298 | + self.request.response.redirect(self.nextURL()) |
299 | + |
300 | + def nextURL(self): |
301 | + return absoluteURL(self.context.__parent__, self.request) |
302 | + |
303 | + def updateActions(self): |
304 | + super(FlourishCourseWorksheetEditView, self).updateActions() |
305 | + self.actions['apply'].addClass('button-ok') |
306 | + self.actions['cancel'].addClass('button-cancel') |
307 | + |
308 | + |
309 | +class CourseWorksheetAddLinks(flourish.page.RefineLinksViewlet): |
310 | + """Course worksheet add links viewlet.""" |
311 | + |
312 | + |
313 | +class FlourishCourseActivityAddView(FlourishActivityAddView): |
314 | + legend = _('Course Activity Details') |
315 | + |
316 | + |
317 | +class CourseActivityAddTertiaryNavigationManager( |
318 | + flourish.page.TertiaryNavigationManager): |
319 | + |
320 | + template = InlineViewPageTemplate("") |
321 | + |
322 | + |
323 | +class FlourishCourseActivityEditView(FlourishActivityEditView): |
324 | + legend = _('Course Activity Details') |
325 | + |
326 | + def nextURL(self): |
327 | + return absoluteURL(self.context.__parent__, self.request) |
328 | + |
329 | + |
330 | +class FlourishCourseWorksheetsBase(object): |
331 | + |
332 | + @property |
333 | + def course(self): |
334 | + return self.context |
335 | + |
336 | + @property |
337 | + def schoolyear(self): |
338 | + return ISchoolYear(self.course) |
339 | + |
340 | + @property |
341 | + def deployed(self): |
342 | + return ICourseDeployedWorksheets(self.course) |
343 | + |
344 | + @property |
345 | + def activities(self): |
346 | + return ICourseActivities(self.course) |
347 | + |
348 | + def sheets(self): |
349 | + return [sheet for sheet in self.all_sheets() if not sheet['checked']] |
350 | + |
351 | + def all_sheets(self): |
352 | + schoolyear = self.schoolyear |
353 | + deployments = {} |
354 | + for nm, sheet in self.deployed.items(): |
355 | + sheet = removeSecurityProxy(sheet) |
356 | + index = int(sheet.__name__[sheet.__name__.rfind('_') + 1:]) |
357 | + deployment = deployments.setdefault(index, { |
358 | + 'obj': sheet, |
359 | + 'index': str(index), |
360 | + 'checked': sheet.hidden, |
361 | + 'terms': [False] * len(schoolyear), |
362 | + }) |
363 | + for index, term in enumerate(schoolyear.values()): |
364 | + prefix = 'course_%s_%s' % (self.course.__name__, term.__name__) |
365 | + if sheet.__name__.startswith(prefix): |
366 | + deployment['terms'][index] = True |
367 | + sheets = [v for k, v in sorted(deployments.items())] |
368 | + return ([sheet for sheet in sheets if not sheet['checked']] + |
369 | + [sheet for sheet in sheets if sheet['checked']]) |
370 | + |
371 | + @property |
372 | + def terms(self): |
373 | + result = [{ |
374 | + 'name': '', |
375 | + 'title': _('-- Entire year --'), |
376 | + 'selected': 'selected', |
377 | + }] |
378 | + for term in self.schoolyear.values(): |
379 | + result.append({ |
380 | + 'name': term.__name__, |
381 | + 'title': term.title, |
382 | + 'selected': '', |
383 | + }) |
384 | + return result |
385 | + |
386 | + def getNewIndex(self, sheet, template_title): |
387 | + if sheet.title.startswith(template_title): |
388 | + rest = sheet.title[len(template_title):] |
389 | + if not rest: |
390 | + return 1 |
391 | + elif len(rest) > 1 and rest[0] == '-' and rest[1:].isdigit(): |
392 | + return int(rest[1:]) |
393 | + return 0 |
394 | + |
395 | + def deploy(self, term, template): |
396 | + # get the next index and title |
397 | + highest, title_index = 0, 0 |
398 | + template_title = self.alternate_title |
399 | + for sheet in self.deployed.values(): |
400 | + index = int(sheet.__name__[sheet.__name__.rfind('_') + 1:]) |
401 | + if index > highest: |
402 | + highest = index |
403 | + new_index = self.getNewIndex(sheet, template_title) |
404 | + if new_index > title_index: |
405 | + title_index = new_index |
406 | + root = IGradebookRoot(ISchoolToolApplication(None)) |
407 | + prefix = self.schoolyear.__name__ + '_' |
408 | + for sheet in root.deployed.values(): |
409 | + if sheet.__name__.startswith(prefix): |
410 | + new_index = self.getNewIndex(sheet, template_title) |
411 | + if new_index > title_index: |
412 | + title_index = new_index |
413 | + title = template_title |
414 | + if title_index: |
415 | + title += '-%s' % (title_index + 1) |
416 | + |
417 | + # copy worksheet template to the term or whole year |
418 | + if term: |
419 | + terms = [term] |
420 | + else: |
421 | + terms = self.schoolyear.values() |
422 | + for term in terms: |
423 | + deployedKey = 'course_%s_%s_%s' % (self.course.__name__, |
424 | + term.__name__, highest + 1) |
425 | + deployedWorksheet = Worksheet(title) |
426 | + self.deployed[deployedKey] = deployedWorksheet |
427 | + copyActivities(removeSecurityProxy(template), deployedWorksheet) |
428 | + |
429 | + # now copy the template to all sections in the term |
430 | + sections = ISectionContainer(term) |
431 | + for section in sections.values(): |
432 | + if self.course not in section.courses: |
433 | + continue |
434 | + worksheetCopy = Worksheet(deployedWorksheet.title) |
435 | + worksheetCopy.deployed = True |
436 | + IActivities(section)[deployedWorksheet.__name__] = worksheetCopy |
437 | + copyActivities(deployedWorksheet, worksheetCopy) |
438 | + |
439 | + |
440 | +class FlourishManageCourseWorksheetTemplatesOverview(flourish.page.Content): |
441 | + """A flourish viewlet for showing worksheet templates in course view""" |
442 | + |
443 | + body_template = ViewPageTemplateFile( |
444 | + 'templates/f_manage_course_worksheet_templates.pt') |
445 | + |
446 | + |
447 | +class FlourishManageCourseSheetsOverview(FlourishCourseWorksheetsBase, |
448 | + flourish.page.Content): |
449 | + """A flourish viewlet for showing deployed worksheets in course view""" |
450 | + |
451 | + body_template = ViewPageTemplateFile( |
452 | + 'templates/f_manage_course_worksheets.pt') |
453 | + |
454 | + |
455 | +class FlourishCourseWorksheetsView(FlourishCourseWorksheetsBase, |
456 | + flourish.page.Page): |
457 | + """A flourish view for managing corse worksheet deployment""" |
458 | + |
459 | + def __init__(self, context, request): |
460 | + super(FlourishCourseWorksheetsView, self).__init__(context, request) |
461 | + self.alternate_title = self.request.get('alternate_title') |
462 | + |
463 | + @property |
464 | + def subtitle(self): |
465 | + subtitle = _(u'Worksheets for ${year}', |
466 | + mapping={'year': self.schoolyear.title}) |
467 | + return translate(subtitle, context=self.request) |
468 | + |
469 | + @property |
470 | + def has_error(self): |
471 | + return self.no_template or self.no_title |
472 | + |
473 | + @property |
474 | + def no_template(self): |
475 | + return 'SUBMIT' in self.request and not self.request.get('template') |
476 | + |
477 | + @property |
478 | + def no_title(self): |
479 | + return ('SUBMIT' in self.request and |
480 | + not self.request.get('alternate_title')) |
481 | + |
482 | + @property |
483 | + def templates(self): |
484 | + result = [{ |
485 | + 'name': '', |
486 | + 'title': _('-- Select a template --'), |
487 | + 'selected': 'selected', |
488 | + }] |
489 | + for template in self.activities.values(): |
490 | + result.append({ |
491 | + 'name': template.__name__, |
492 | + 'title': template.title, |
493 | + 'selected': '', |
494 | + }) |
495 | + return result |
496 | + |
497 | + def update(self): |
498 | + if 'CANCEL' in self.request: |
499 | + self.request.response.redirect(self.nextURL()) |
500 | + if 'SUBMIT' in self.request: |
501 | + if self.request.get('template') and self.alternate_title: |
502 | + template = self.activities[self.request['template']] |
503 | + term = self.request.get('term') |
504 | + if term: |
505 | + term = self.schoolyear[term] |
506 | + self.deploy(term, template) |
507 | + self.alternate_title = '' |
508 | + |
509 | + def nextURL(self): |
510 | + return absoluteURL(self.context, self.request) |
511 | + |
512 | + |
513 | +class CourseWorksheetsActionLinks(flourish.page.RefineLinksViewlet): |
514 | + """Course worksheets view action links viewlet.""" |
515 | + |
516 | + |
517 | +class FlourishHideUnhideCourseWorkheetsView(FlourishCourseWorksheetsBase, |
518 | + flourish.page.Page): |
519 | + """A flourish view for hiding/unhiding course worksheet deployments""" |
520 | + |
521 | + @property |
522 | + def subtitle(self): |
523 | + title = _(u'Hide/unhide Deployed Worksheets for ${year}', |
524 | + mapping={'year': self.schoolyear.title}) |
525 | + return translate(title, context=self.request) |
526 | + |
527 | + def update(self): |
528 | + if 'CANCEL' in self.request: |
529 | + self.request.response.redirect(self.nextURL()) |
530 | + elif 'SUBMIT' in self.request: |
531 | + hidden = self.request.get('hidden', []) |
532 | + schoolyear = self.schoolyear |
533 | + for nm, sheet in self.deployed.items(): |
534 | + sheet = removeSecurityProxy(sheet) |
535 | + index = sheet.__name__[sheet.__name__.rfind('_') + 1:] |
536 | + self.handleSheet(sheet, index, hidden) |
537 | + self.request.response.redirect(self.nextURL()) |
538 | + |
539 | + def handleSheet(self, sheet, index, hidden): |
540 | + if index in hidden and not sheet.hidden: |
541 | + sheet.hidden = True |
542 | + elif index not in hidden and sheet.hidden: |
543 | + sheet.hidden = False |
544 | + else: |
545 | + return |
546 | + schoolyear = self.schoolyear |
547 | + for term in schoolyear.values(): |
548 | + deployedKey = 'course_%s_%s_%s' % (self.context.__name__, |
549 | + term.__name__, index) |
550 | + if sheet.__name__ == deployedKey: |
551 | + for section in ISectionContainer(term).values(): |
552 | + if self.context not in section.courses: |
553 | + continue |
554 | + activities = IActivities(section) |
555 | + activities[deployedKey].hidden = sheet.hidden |
556 | + return |
557 | + |
558 | + def nextURL(self): |
559 | + url = absoluteURL(self.context, self.request) |
560 | + return url + '/deployed_worksheets.html' |
561 | + |
562 | + |
563 | +class FlourishDeployAsCourseWorksheetView(FlourishCourseWorksheetsBase, |
564 | + flourish.page.Page): |
565 | + """A flourish view for deploying current gradebook worksheet as a |
566 | + course worksheet. If form data is valid, it creates a course |
567 | + worksheet template as a copy of the context and then deploys that |
568 | + to the course for the given term..""" |
569 | + |
570 | + @property |
571 | + def course(self): |
572 | + courses = list(ISection(self.context).courses) |
573 | + if not courses: |
574 | + return None |
575 | + return courses[0] |
576 | + |
577 | + @property |
578 | + def has_error(self): |
579 | + return self.no_title |
580 | + |
581 | + @property |
582 | + def no_title(self): |
583 | + return 'SUBMIT' in self.request and not self.alternate_title |
584 | + |
585 | + @property |
586 | + def alternate_title(self): |
587 | + if 'alternate_title' in self.request: |
588 | + return self.request['alternate_title'] |
589 | + return self.context.title |
590 | + |
591 | + def update(self): |
592 | + if 'CANCEL' in self.request: |
593 | + self.request.response.redirect(self.nextURL()) |
594 | + if 'SUBMIT' in self.request: |
595 | + if not self.has_error: |
596 | + template = Worksheet(self.alternate_title) |
597 | + chooser = INameChooser(self.activities) |
598 | + name = chooser.chooseName(template.title, template) |
599 | + self.activities[name] = template |
600 | + copyActivities(removeSecurityProxy(self.context), template) |
601 | + term = self.request.get('term') |
602 | + if term: |
603 | + term = self.schoolyear[term] |
604 | + self.deploy(term, template) |
605 | + self.request.response.redirect(self.nextURL()) |
606 | + |
607 | + def nextURL(self): |
608 | + return absoluteURL(self.context, self.request) + '/gradebook' |
609 | + |
610 | |
611 | === modified file 'src/schooltool/gradebook/browser/flourish.zcml' |
612 | --- src/schooltool/gradebook/browser/flourish.zcml 2011-11-07 06:19:05 +0000 |
613 | +++ src/schooltool/gradebook/browser/flourish.zcml 2011-12-22 16:21:13 +0000 |
614 | @@ -140,6 +140,17 @@ |
615 | /> |
616 | |
617 | <flourish:viewlet |
618 | + name="gradebook_actions" |
619 | + after="gradebook_settings" |
620 | + manager="schooltool.skin.flourish.page.IPageRefineManager" |
621 | + class=".gradebook.FlourishGradebookActionsLinks" |
622 | + for="..interfaces.IGradebook" |
623 | + title="Actions" |
624 | + permission="schooltool.edit" |
625 | + view=".gradebook.FlourishGradebookOverview" |
626 | + /> |
627 | + |
628 | + <flourish:viewlet |
629 | name="select_year" |
630 | class=".gradebook.FlourishGradebookYearNavigationViewlet" |
631 | manager=".gradebook.FlourishGradebookYearNavigation" |
632 | @@ -372,8 +383,17 @@ |
633 | |
634 | <!-- Report Sheets --> |
635 | <flourish:viewlet |
636 | + name="manage-report-sheet-templates-overview" |
637 | + after="manage-resources-overview" |
638 | + view="schooltool.app.browser.app.ManageSchool" |
639 | + permission="schooltool.edit" |
640 | + manager="schooltool.skin.flourish.page.IPageContentManager" |
641 | + class=".report_card.FlourishManageReportSheetTemplatesOverview" |
642 | + /> |
643 | + |
644 | + <flourish:viewlet |
645 | name="manage-report-sheets-overview" |
646 | - after="manage-resources-overview" |
647 | + after="manage-report-sheet-templates-overview" |
648 | view="schooltool.app.browser.app.ManageSchool" |
649 | permission="schooltool.edit" |
650 | manager="schooltool.skin.flourish.page.IPageContentManager" |
651 | @@ -518,15 +538,6 @@ |
652 | /> |
653 | </configure> |
654 | |
655 | - <flourish:viewlet |
656 | - name="gradebook/templates" |
657 | - before="report_card_layout" |
658 | - title="Report Sheet Templates" |
659 | - class="schooltool.skin.flourish.page.LinkViewlet" |
660 | - manager="schooltool.app.browser.app.CustomizeSchoolLinks" |
661 | - permission="schooltool.edit" |
662 | - /> |
663 | - |
664 | <flourish:page |
665 | name="report_sheets" |
666 | for="schooltool.app.interfaces.ISchoolToolApplication" |
667 | @@ -958,4 +969,163 @@ |
668 | /> |
669 | </configure> |
670 | |
671 | + <!-- Course Worksheets --> |
672 | + <flourish:viewlet |
673 | + name="manage-course-worksheet-templates" |
674 | + before="manage-course-worksheets" |
675 | + view="schooltool.course.browser.course.FlourishCourseView" |
676 | + permission="schooltool.edit" |
677 | + manager="schooltool.skin.flourish.page.IPageContentManager" |
678 | + class=".course_worksheets.FlourishManageCourseWorksheetTemplatesOverview" |
679 | + /> |
680 | + |
681 | + <flourish:viewlet |
682 | + name="manage-course-worksheets" |
683 | + view="schooltool.course.browser.course.FlourishCourseView" |
684 | + permission="schooltool.edit" |
685 | + manager="schooltool.skin.flourish.page.IPageContentManager" |
686 | + class=".course_worksheets.FlourishManageCourseSheetsOverview" |
687 | + /> |
688 | + |
689 | + <flourish:page |
690 | + name="index.html" |
691 | + for="schooltool.gradebook.interfaces.ICourseActivities" |
692 | + class=".course_worksheets.FlourishCourseTemplatesView" |
693 | + content_template="templates/f_course_worksheet_templates.pt" |
694 | + permission="schooltool.edit" |
695 | + subtitle="Worksheet Templates" |
696 | + /> |
697 | + |
698 | + <flourish:viewlet |
699 | + name="course-worksheets" |
700 | + manager="schooltool.skin.flourish.page.IPageRefineManager" |
701 | + class=".course_worksheets.FlourishCourseWorksheetsLinks" |
702 | + for="schooltool.gradebook.interfaces.ICourseActivities" |
703 | + title="Add" |
704 | + permission="schooltool.edit" |
705 | + view=".course_worksheets.FlourishCourseTemplatesView" |
706 | + /> |
707 | + |
708 | + <flourish:viewlet |
709 | + name="addCourseWorksheet.html" |
710 | + title="Course Worksheet" |
711 | + class="schooltool.skin.flourish.page.LinkViewlet" |
712 | + manager=".course_worksheets.FlourishCourseWorksheetsLinks" |
713 | + permission="schooltool.edit" |
714 | + /> |
715 | + |
716 | + <configure package="schooltool.skin.flourish"> |
717 | + <flourish:page |
718 | + name="addCourseWorksheet.html" |
719 | + for="schooltool.gradebook.interfaces.ICourseActivities" |
720 | + subtitle="New Course Worksheet" |
721 | + class="schooltool.gradebook.browser.course_worksheets.FlourishCourseWorksheetAddView" |
722 | + content_template="templates/z3c-schooltool-form.pt" |
723 | + permission="schooltool.edit" |
724 | + /> |
725 | + |
726 | + <flourish:page |
727 | + name="addCourseActivity.html" |
728 | + for="schooltool.gradebook.interfaces.ICourseWorksheet" |
729 | + subtitle="New Course Activity" |
730 | + class="schooltool.gradebook.browser.course_worksheets.FlourishCourseActivityAddView" |
731 | + content_template="templates/z3c-schooltool-form.pt" |
732 | + permission="schooltool.edit" |
733 | + /> |
734 | + </configure> |
735 | + |
736 | + <flourish:page |
737 | + name="index.html" |
738 | + for="schooltool.gradebook.interfaces.ICourseWorksheet" |
739 | + subtitle="Edit" |
740 | + class=".course_worksheets.FlourishCourseWorksheetEditView" |
741 | + content_template="templates/f_course_worksheet_edit.pt" |
742 | + permission="schooltool.edit" |
743 | + /> |
744 | + |
745 | + <flourish:viewlet |
746 | + name="course-worksheet-add-links" |
747 | + manager="schooltool.skin.flourish.page.IPageRefineManager" |
748 | + class=".course_worksheets.CourseWorksheetAddLinks" |
749 | + view=".course_worksheets.FlourishCourseWorksheetEditView" |
750 | + title="Add" |
751 | + permission="schooltool.edit" |
752 | + /> |
753 | + |
754 | + <flourish:viewlet |
755 | + name="addCourseActivity.html" |
756 | + title="Course Activity" |
757 | + class="schooltool.skin.flourish.page.LinkViewlet" |
758 | + manager=".course_worksheets.CourseWorksheetAddLinks" |
759 | + permission="schooltool.edit" |
760 | + /> |
761 | + |
762 | + <flourish:viewletManager |
763 | + name="tertiary_navigation" |
764 | + provides="schooltool.skin.flourish.page.ITertiaryNavigationManager" |
765 | + class=".course_worksheets.CourseActivityAddTertiaryNavigationManager" |
766 | + view=".course_worksheets.FlourishCourseActivityAddView" |
767 | + permission="zope.Public" |
768 | + /> |
769 | + |
770 | + <flourish:page |
771 | + name="editCourseActivity.html" |
772 | + for="..interfaces.IActivity" |
773 | + subtitle="Edit" |
774 | + content_template="templates/f_add_edit_activity.pt" |
775 | + class=".course_worksheets.FlourishCourseActivityEditView" |
776 | + permission="schooltool.edit" |
777 | + /> |
778 | + |
779 | + <flourish:page |
780 | + name="deployed_worksheets.html" |
781 | + for="schooltool.course.interfaces.ICourse" |
782 | + class=".course_worksheets.FlourishCourseWorksheetsView" |
783 | + content_template="templates/f_course_worksheets.pt" |
784 | + permission="schooltool.edit" |
785 | + /> |
786 | + |
787 | + <flourish:viewlet |
788 | + name="course-worksheets-action-links" |
789 | + manager="schooltool.skin.flourish.page.IPageRefineManager" |
790 | + class=".course_worksheets.CourseWorksheetsActionLinks" |
791 | + view=".course_worksheets.FlourishCourseWorksheetsView" |
792 | + title="Action" |
793 | + permission="schooltool.edit" |
794 | + /> |
795 | + |
796 | + <flourish:viewlet |
797 | + name="hide_unhide_worksheets.html" |
798 | + title="Hide/unhide Worksheets" |
799 | + class="schooltool.skin.flourish.page.LinkViewlet" |
800 | + manager=".course_worksheets.CourseWorksheetsActionLinks" |
801 | + permission="schooltool.edit" |
802 | + /> |
803 | + |
804 | + <flourish:page |
805 | + name="hide_unhide_worksheets.html" |
806 | + for="schooltool.course.interfaces.ICourse" |
807 | + class=".course_worksheets.FlourishHideUnhideCourseWorkheetsView" |
808 | + content_template="templates/f_hide_unhide_course_worksheets.pt" |
809 | + permission="schooltool.edit" |
810 | + /> |
811 | + |
812 | + <flourish:viewlet |
813 | + name="../deploy_as_course_worksheet.html" |
814 | + title="Deploy as Course Worksheet" |
815 | + class="schooltool.skin.flourish.page.LinkViewlet" |
816 | + manager=".gradebook.FlourishGradebookActionsLinks" |
817 | + permission="schooltool.edit" |
818 | + /> |
819 | + |
820 | + <flourish:page |
821 | + name="deploy_as_course_worksheet.html" |
822 | + for="..interfaces.IWorksheet" |
823 | + subtitle="Deploy as Course Worksheet" |
824 | + class=".course_worksheets.FlourishDeployAsCourseWorksheetView" |
825 | + content_template="templates/f_deploy_as_course_worksheet.pt" |
826 | + permission="schooltool.edit" |
827 | + /> |
828 | + |
829 | </configure> |
830 | + |
831 | |
832 | === modified file 'src/schooltool/gradebook/browser/gradebook.py' |
833 | --- src/schooltool/gradebook/browser/gradebook.py 2011-12-20 19:41:39 +0000 |
834 | +++ src/schooltool/gradebook/browser/gradebook.py 2011-12-22 16:21:13 +0000 |
835 | @@ -415,7 +415,7 @@ |
836 | self.due_date_hide = prefs.get('hide', False) |
837 | |
838 | self.apply_all_colspan = 1 |
839 | - if gradebook.context.deployed: |
840 | + if not gradebook.context.canAverage(): |
841 | self.total_hide = True |
842 | self.average_hide = True |
843 | if not self.absences_hide: |
844 | @@ -1057,6 +1057,10 @@ |
845 | """flourish Gradebook Settings links viewlet.""" |
846 | |
847 | |
848 | +class FlourishGradebookActionsLinks(flourish.page.RefineLinksViewlet): |
849 | + """flourish Gradebook Actions links viewlet.""" |
850 | + |
851 | + |
852 | class GradebookTertiaryNavigationManager(flourish.page.TertiaryNavigationManager): |
853 | |
854 | template = InlineViewPageTemplate(""" |
855 | @@ -1075,8 +1079,11 @@ |
856 | current = gradebook.context.__name__ |
857 | for worksheet in gradebook.worksheets: |
858 | url = '%s/gradebook' % absoluteURL(worksheet, self.request) |
859 | + classes = worksheet.__name__ == current and ['active'] or [] |
860 | + if worksheet.deployed: |
861 | + classes.append('deployed') |
862 | result.append({ |
863 | - 'class': worksheet.__name__ == current and 'active' or None, |
864 | + 'class': classes and ' '.join(classes) or None, |
865 | 'viewlet': u'<a href="%s">%s</a>' % (url, worksheet.title[:15]), |
866 | }) |
867 | return result |
868 | @@ -1902,3 +1909,4 @@ |
869 | return None |
870 | can_view = flourish.canView(self.gradebook) |
871 | return can_view |
872 | + |
873 | |
874 | === modified file 'src/schooltool/gradebook/browser/report_card.py' |
875 | --- src/schooltool/gradebook/browser/report_card.py 2011-11-12 04:02:28 +0000 |
876 | +++ src/schooltool/gradebook/browser/report_card.py 2011-12-22 16:21:13 +0000 |
877 | @@ -221,6 +221,14 @@ |
878 | return [] |
879 | |
880 | |
881 | +class FlourishManageReportSheetTemplatesOverview(FlourishReportSheetsBase, |
882 | + flourish.page.Content): |
883 | + """A flourish viewlet for showing report sheet templates in school view""" |
884 | + |
885 | + body_template = ViewPageTemplateFile( |
886 | + 'templates/f_manage_report_sheet_templates_overview.pt') |
887 | + |
888 | + |
889 | class FlourishManageReportSheetsOverview(FlourishReportSheetsBase, |
890 | flourish.page.Content): |
891 | """A flourish viewlet for showing deployed report sheets in school view""" |
892 | @@ -500,6 +508,12 @@ |
893 | def title(self): |
894 | return self.context.title |
895 | |
896 | + def display_scoresystem(self, activity): |
897 | + ss = activity.scoresystem |
898 | + if IRangedValuesScoreSystem.providedBy(ss): |
899 | + return '%s - %s' % (ss.min, ss.max) |
900 | + return ss.title |
901 | + |
902 | def update(self): |
903 | if 'form-submitted' in self.request: |
904 | for activity in self.context.values(): |
905 | |
906 | === modified file 'src/schooltool/gradebook/browser/resources/f_gradebook.css' |
907 | --- src/schooltool/gradebook/browser/resources/f_gradebook.css 2011-08-31 20:16:11 +0000 |
908 | +++ src/schooltool/gradebook/browser/resources/f_gradebook.css 2011-12-22 16:21:13 +0000 |
909 | @@ -33,3 +33,8 @@ |
910 | height: 18px; |
911 | width: 104px; |
912 | } |
913 | + |
914 | +li.deployed a { |
915 | + font-style: italic; |
916 | +} |
917 | + |
918 | |
919 | === added file 'src/schooltool/gradebook/browser/templates/f_course_worksheet_edit.pt' |
920 | --- src/schooltool/gradebook/browser/templates/f_course_worksheet_edit.pt 1970-01-01 00:00:00 +0000 |
921 | +++ src/schooltool/gradebook/browser/templates/f_course_worksheet_edit.pt 2011-12-22 16:21:13 +0000 |
922 | @@ -0,0 +1,45 @@ |
923 | +<div i18n:domain="schooltool.gradebook"> |
924 | + <div metal:use-macro="macro:form"> |
925 | + <metal:block fill-slot="bottom"> |
926 | + <input type="hidden" name="form-submitted" value="" /> |
927 | + <h2 i18n:translate="">Course Activities</h2> |
928 | + <table> |
929 | + <thead> |
930 | + <tr> |
931 | + <th i18n:translate="">Title</th> |
932 | + <th i18n:translate="">Score System</th> |
933 | + <th i18n:translate="">Delete?</th> |
934 | + </tr> |
935 | + </thead> |
936 | + <tal:block repeat="activity context/values"> |
937 | + <tr> |
938 | + <td> |
939 | + <span tal:content="activity/title" /> |
940 | + <a class="modify" href="" title="Edit" |
941 | + tal:attributes="href string:${activity/@@absolute_url}/editCourseActivity.html" |
942 | + i18n:attributes="title"> |
943 | + <img tal:attributes="src context/++resource++schooltool.skin.flourish/edit-icon.png" |
944 | + alt="Edit" |
945 | + i18n:attributes="alt" /> |
946 | + </a> |
947 | + </td> |
948 | + <td tal:content="string: ${activity/scoresystem/min} - ${activity/scoresystem/max}"/> |
949 | + <td> |
950 | + <button class="image" type="submit" title="Delete" value="1" |
951 | + tal:attributes="name string:delete.${activity/__name__};" |
952 | + i18n:attributes="title"> |
953 | + <img alt="Delete" i18n:attributes="alt" |
954 | + tal:attributes="src context/++resource++schooltool.skin.flourish/remove-icon.png" /> |
955 | + </button> |
956 | + </td> |
957 | + </tr> |
958 | + </tal:block> |
959 | + </table> |
960 | + <h3> |
961 | + <a tal:attributes="href view/nextURL" |
962 | + i18n:translate="">Done</a> |
963 | + </h3> |
964 | + </metal:block> |
965 | + </div> |
966 | +</div> |
967 | + |
968 | |
969 | === added file 'src/schooltool/gradebook/browser/templates/f_course_worksheet_templates.pt' |
970 | --- src/schooltool/gradebook/browser/templates/f_course_worksheet_templates.pt 1970-01-01 00:00:00 +0000 |
971 | +++ src/schooltool/gradebook/browser/templates/f_course_worksheet_templates.pt 2011-12-22 16:21:13 +0000 |
972 | @@ -0,0 +1,26 @@ |
973 | +<div tal:define="worksheets view/worksheets" i18n:domain="schooltool.gradebook"> |
974 | + <form method="post" |
975 | + tal:attributes="action string:${context/@@absolute_url}/worksheet_templates.html"> |
976 | + <input type="hidden" name="form-submitted" value="" /> |
977 | + <table> |
978 | + <thead> |
979 | + <tr> |
980 | + <th i18n:translate="">Title</th> |
981 | + </tr> |
982 | + </thead> |
983 | + <tr tal:repeat="worksheet worksheets"> |
984 | + <td> |
985 | + <tal:block replace="structure worksheet/@@link" /> |
986 | + </td> |
987 | + </tr> |
988 | + <tr tal:condition="python: len(worksheets) == 0"> |
989 | + <td i18n:translate="">This year has no course worksheets set up.</td> |
990 | + </tr> |
991 | + </table> |
992 | + </form> |
993 | + <h3> |
994 | + <a tal:attributes="href string:${context/__parent__/@@absolute_url}" |
995 | + i18n:translate="">Done</a> |
996 | + </h3> |
997 | +</div> |
998 | + |
999 | |
1000 | === added file 'src/schooltool/gradebook/browser/templates/f_course_worksheets.pt' |
1001 | --- src/schooltool/gradebook/browser/templates/f_course_worksheets.pt 1970-01-01 00:00:00 +0000 |
1002 | +++ src/schooltool/gradebook/browser/templates/f_course_worksheets.pt 2011-12-22 16:21:13 +0000 |
1003 | @@ -0,0 +1,111 @@ |
1004 | +<div i18n:domain="schooltool.gradebook" |
1005 | + tal:define="sheets view/sheets; terms view/terms; schoolyear view/schoolyear"> |
1006 | + <script type="text/javascript"> |
1007 | + $(document).ready(function() { |
1008 | + $('#template').change(function(e) { |
1009 | + index = e.target.selectedIndex |
1010 | + $('#alternate_title').val(e.target.options[index].text); |
1011 | + }); |
1012 | + }); |
1013 | + </script> |
1014 | + <h3 i18n:translate="">Currently Deployed Worksheets</h3> |
1015 | + <table> |
1016 | + <thead> |
1017 | + <tr> |
1018 | + <th i18n:translate="">Workheet</th> |
1019 | + <tal:block repeat="term schoolyear/values"> |
1020 | + <th tal:content="term/title" /> |
1021 | + </tal:block> |
1022 | + </tr> |
1023 | + </thead> |
1024 | + <tr tal:repeat="sheet sheets"> |
1025 | + <td tal:content="sheet/obj/title" /> |
1026 | + <tal:block repeat="term sheet/terms"> |
1027 | + <td> |
1028 | + <span tal:condition="term" class="ui-icon ui-icon-check ui-icon-center"></span> |
1029 | + </td> |
1030 | + </tal:block> |
1031 | + </tr> |
1032 | + <tr tal:condition="not: sheets"> |
1033 | + <td tal:attributes="colspan python:len(schoolyear)+1" i18n:translate=""> |
1034 | + This year has no worksheets deployed. |
1035 | + </td> |
1036 | + </tr> |
1037 | + </table> |
1038 | + <form method="post" class="standalone" |
1039 | + tal:attributes="action request/getURL"> |
1040 | + <div class="viewspace"> |
1041 | + <div class="status" tal:condition="view/has_error"> |
1042 | + <div class="summary ui-state-error ui-corner-all"> |
1043 | + <span class="ui-icon ui-icon-alert">icon</span> |
1044 | + <span i18n:domain="schooltool" i18n:translate="">Please correct the marked fields below.</span> |
1045 | + </div> |
1046 | + </div> |
1047 | + <fieldset> |
1048 | + <legend> |
1049 | + <span i18n:translate="">Select worksheet to deploy</span> |
1050 | + </legend> |
1051 | + <div class="row"> |
1052 | + <div class="label"> |
1053 | + <label for="term"> |
1054 | + <span i18n:translate="">Term or Year</span> |
1055 | + </label> |
1056 | + </div> |
1057 | + <p class="hint" i18n:translate=""> |
1058 | + Select a term or deploy to the entire year. |
1059 | + </p> |
1060 | + <div class="widget"> |
1061 | + <select id="term" name="term"> |
1062 | + <tal:block repeat="term terms"> |
1063 | + <option tal:attributes="value term/name; selected term/selected" |
1064 | + tal:content="term/title" /> |
1065 | + </tal:block> |
1066 | + </select> |
1067 | + </div> |
1068 | + </div> |
1069 | + <div class="row"> |
1070 | + <div class="label"> |
1071 | + <label for="template"> |
1072 | + <span i18n:translate="">Worksheet Template</span> |
1073 | + </label> |
1074 | + </div> |
1075 | + <div class="error" tal:condition="view/no_template"> |
1076 | + <div class="error" i18n:translate="">Required input is missing.</div> |
1077 | + </div> |
1078 | + <div class="widget"> |
1079 | + <select id="template" name="template"> |
1080 | + <tal:block repeat="template view/templates"> |
1081 | + <option tal:attributes="value template/name; selected template/selected" |
1082 | + tal:content="template/title" /> |
1083 | + </tal:block> |
1084 | + </select> |
1085 | + </div> |
1086 | + </div> |
1087 | + <div class="row"> |
1088 | + <div class="label"> |
1089 | + <label for="term"> |
1090 | + <span i18n:translate="">Title</span> |
1091 | + </label> |
1092 | + </div> |
1093 | + <p class="hint" i18n:translate=""> |
1094 | + If you deploy the same template multiple times, give each deployment |
1095 | + an easily distinguishable name. |
1096 | + </p> |
1097 | + <div class="error" tal:condition="view/no_title"> |
1098 | + <div class="error" i18n:translate="">Required input is missing.</div> |
1099 | + </div> |
1100 | + <div class="widget"> |
1101 | + <input type="text" name="alternate_title" id="alternate_title" |
1102 | + tal:attributes="value view/alternate_title" /> |
1103 | + </div> |
1104 | + </div> |
1105 | + </fieldset> |
1106 | + </div> |
1107 | + <div class="buttons controls"> |
1108 | + <input type="submit" class="button-ok" name="SUBMIT" value="Submit" |
1109 | + i18n:attributes="value" /> |
1110 | + <tal:block metal:use-macro="view/@@standard_macros/cancel-button" /> |
1111 | + </div> |
1112 | + </form> |
1113 | +</div> |
1114 | + |
1115 | |
1116 | === added file 'src/schooltool/gradebook/browser/templates/f_deploy_as_course_worksheet.pt' |
1117 | --- src/schooltool/gradebook/browser/templates/f_deploy_as_course_worksheet.pt 1970-01-01 00:00:00 +0000 |
1118 | +++ src/schooltool/gradebook/browser/templates/f_deploy_as_course_worksheet.pt 2011-12-22 16:21:13 +0000 |
1119 | @@ -0,0 +1,61 @@ |
1120 | +<div i18n:domain="schooltool.gradebook" |
1121 | + tal:define="terms view/terms"> |
1122 | + <form method="post" class="standalone" |
1123 | + tal:attributes="action request/getURL"> |
1124 | + <div class="viewspace"> |
1125 | + <div class="status" tal:condition="view/has_error"> |
1126 | + <div class="summary ui-state-error ui-corner-all"> |
1127 | + <span class="ui-icon ui-icon-alert">icon</span> |
1128 | + <span i18n:domain="schooltool" i18n:translate="">Please correct the marked fields below.</span> |
1129 | + </div> |
1130 | + </div> |
1131 | + <fieldset> |
1132 | + <legend> |
1133 | + <span i18n:translate="">Select term or year to deploy</span> |
1134 | + </legend> |
1135 | + <div class="row"> |
1136 | + <div class="label"> |
1137 | + <label for="term"> |
1138 | + <span i18n:translate="">Term or Year</span> |
1139 | + </label> |
1140 | + </div> |
1141 | + <p class="hint" i18n:translate=""> |
1142 | + Select a term or deploy to the entire year. |
1143 | + </p> |
1144 | + <div class="widget"> |
1145 | + <select id="term" name="term"> |
1146 | + <tal:block repeat="term terms"> |
1147 | + <option tal:attributes="value term/name; selected term/selected" |
1148 | + tal:content="term/title" /> |
1149 | + </tal:block> |
1150 | + </select> |
1151 | + </div> |
1152 | + </div> |
1153 | + <div class="row"> |
1154 | + <div class="label"> |
1155 | + <label for="term"> |
1156 | + <span i18n:translate="">Title</span> |
1157 | + </label> |
1158 | + </div> |
1159 | + <p class="hint" i18n:translate=""> |
1160 | + If you deploy the same template multiple times, give each deployment |
1161 | + an easily distinguishable name. |
1162 | + </p> |
1163 | + <div class="error" tal:condition="view/no_title"> |
1164 | + <div class="error" i18n:translate="">Required input is missing.</div> |
1165 | + </div> |
1166 | + <div class="widget"> |
1167 | + <input type="text" name="alternate_title" id="alternate_title" |
1168 | + tal:attributes="value view/alternate_title" /> |
1169 | + </div> |
1170 | + </div> |
1171 | + </fieldset> |
1172 | + </div> |
1173 | + <div class="buttons controls"> |
1174 | + <input type="submit" class="button-ok" name="SUBMIT" value="Submit" |
1175 | + i18n:attributes="value" /> |
1176 | + <tal:block metal:use-macro="view/@@standard_macros/cancel-button" /> |
1177 | + </div> |
1178 | + </form> |
1179 | +</div> |
1180 | + |
1181 | |
1182 | === added file 'src/schooltool/gradebook/browser/templates/f_hide_unhide_course_worksheets.pt' |
1183 | --- src/schooltool/gradebook/browser/templates/f_hide_unhide_course_worksheets.pt 1970-01-01 00:00:00 +0000 |
1184 | +++ src/schooltool/gradebook/browser/templates/f_hide_unhide_course_worksheets.pt 2011-12-22 16:21:13 +0000 |
1185 | @@ -0,0 +1,44 @@ |
1186 | +<div i18n:domain="schooltool.gradebook" |
1187 | + tal:define="sheets view/all_sheets; schoolyear view/schoolyear"> |
1188 | + <h3 i18n:translate="">Currently Deployed WorkSheets</h3> |
1189 | + <form method="post" class="standalone" |
1190 | + tal:attributes="action request/getURL"> |
1191 | + <table> |
1192 | + <thead> |
1193 | + <tr> |
1194 | + <th i18n:translate="">Deployed Worksheet</th> |
1195 | + <th i18n:translate="">Index</th> |
1196 | + <tal:block repeat="term schoolyear/values"> |
1197 | + <th tal:content="term/title" /> |
1198 | + </tal:block> |
1199 | + <th i18n:translate="">Hidden?</th> |
1200 | + </tr> |
1201 | + </thead> |
1202 | + <tr tal:repeat="sheet sheets"> |
1203 | + <td tal:content="sheet/obj/title" /> |
1204 | + <td tal:content="sheet/index" /> |
1205 | + <tal:block repeat="term sheet/terms"> |
1206 | + <td> |
1207 | + <span tal:condition="term" class="ui-icon ui-icon-check ui-icon-center"></span> |
1208 | + </td> |
1209 | + </tal:block> |
1210 | + <td> |
1211 | + <input type="checkbox" name="hidden:list" |
1212 | + tal:attributes="value sheet/index; |
1213 | + checked sheet/checked" /> |
1214 | + </td> |
1215 | + </tr> |
1216 | + <tr tal:condition="not: sheets"> |
1217 | + <td tal:attributes="colspan python:len(schoolyear)+3" i18n:translate=""> |
1218 | + This year has no worksheets deployed. |
1219 | + </td> |
1220 | + </tr> |
1221 | + </table> |
1222 | + <div class="buttons controls"> |
1223 | + <input type="submit" class="button-ok" name="SUBMIT" value="Submit" |
1224 | + i18n:attributes="value" /> |
1225 | + <tal:block metal:use-macro="view/@@standard_macros/cancel-button" /> |
1226 | + </div> |
1227 | + </form> |
1228 | +</div> |
1229 | + |
1230 | |
1231 | === added file 'src/schooltool/gradebook/browser/templates/f_manage_course_worksheet_templates.pt' |
1232 | --- src/schooltool/gradebook/browser/templates/f_manage_course_worksheet_templates.pt 1970-01-01 00:00:00 +0000 |
1233 | +++ src/schooltool/gradebook/browser/templates/f_manage_course_worksheet_templates.pt 2011-12-22 16:21:13 +0000 |
1234 | @@ -0,0 +1,10 @@ |
1235 | +<div class="manage-view" i18n:domain="schooltool"> |
1236 | + <h3> |
1237 | + <a title="Manage Worksheet Templates" |
1238 | + tal:attributes="href string:${context/@@absolute_url}/activities" |
1239 | + i18n:attributes="title" |
1240 | + i18n:translate=""> |
1241 | + Worksheet Templates |
1242 | + </a> |
1243 | + </h3> |
1244 | +</div> |
1245 | |
1246 | === added file 'src/schooltool/gradebook/browser/templates/f_manage_course_worksheets.pt' |
1247 | --- src/schooltool/gradebook/browser/templates/f_manage_course_worksheets.pt 1970-01-01 00:00:00 +0000 |
1248 | +++ src/schooltool/gradebook/browser/templates/f_manage_course_worksheets.pt 2011-12-22 16:21:13 +0000 |
1249 | @@ -0,0 +1,21 @@ |
1250 | +<div class="manage-view" i18n:domain="schooltool" |
1251 | + tal:define="sheets view/sheets"> |
1252 | + <h3> |
1253 | + <a title="Manage Deployed Worksheets" |
1254 | + tal:attributes="href string:${context/@@absolute_url}/deployed_worksheets.html" |
1255 | + i18n:attributes="title" |
1256 | + i18n:translate=""> |
1257 | + Deployed Worksheets |
1258 | + </a> |
1259 | + </h3> |
1260 | + <p i18n:translate="" tal:condition="sheets"> |
1261 | + There are |
1262 | + <metal:block tal:replace="python:len(sheets)" i18n:name="count"/> |
1263 | + worksheets deployed in |
1264 | + <metal:block tal:replace="view/schoolyear/title" i18n:name="schoolyear"/> |
1265 | + </p> |
1266 | + <p i18n:translate="" tal:condition="not: sheets"> |
1267 | + There are no worksheets deployed in |
1268 | + <metal:block tal:replace="view/schoolyear/title" i18n:name="schoolyear"/> |
1269 | + </p> |
1270 | +</div> |
1271 | |
1272 | === added file 'src/schooltool/gradebook/browser/templates/f_manage_report_sheet_templates_overview.pt' |
1273 | --- src/schooltool/gradebook/browser/templates/f_manage_report_sheet_templates_overview.pt 1970-01-01 00:00:00 +0000 |
1274 | +++ src/schooltool/gradebook/browser/templates/f_manage_report_sheet_templates_overview.pt 2011-12-22 16:21:13 +0000 |
1275 | @@ -0,0 +1,12 @@ |
1276 | +<div class="manage-view" i18n:domain="schooltool" |
1277 | + tal:condition="view/has_schoolyear" |
1278 | + tal:define="sheets view/sheets"> |
1279 | + <h3> |
1280 | + <a title="Manage Report Sheet Templates" |
1281 | + tal:attributes="href string:${context/@@absolute_url}/gradebook/templates" |
1282 | + i18n:attributes="title" |
1283 | + i18n:translate=""> |
1284 | + Report Sheet Templates |
1285 | + </a> |
1286 | + </h3> |
1287 | +</div> |
1288 | |
1289 | === modified file 'src/schooltool/gradebook/browser/templates/f_manage_report_sheets_overview.pt' |
1290 | --- src/schooltool/gradebook/browser/templates/f_manage_report_sheets_overview.pt 2011-08-29 01:25:08 +0000 |
1291 | +++ src/schooltool/gradebook/browser/templates/f_manage_report_sheets_overview.pt 2011-12-22 16:21:13 +0000 |
1292 | @@ -2,11 +2,11 @@ |
1293 | tal:condition="view/has_schoolyear" |
1294 | tal:define="sheets view/sheets"> |
1295 | <h3> |
1296 | - <a title="Manage Report Sheets" |
1297 | + <a title="Manage Deployed Report Sheets" |
1298 | tal:attributes="href string:${context/@@absolute_url}/report_sheets" |
1299 | i18n:attributes="title" |
1300 | i18n:translate=""> |
1301 | - Report Sheets |
1302 | + Deployed Report Sheets |
1303 | </a> |
1304 | </h3> |
1305 | <p i18n:translate="" tal:condition="sheets"> |
1306 | |
1307 | === modified file 'src/schooltool/gradebook/browser/templates/f_template_manage.pt' |
1308 | --- src/schooltool/gradebook/browser/templates/f_template_manage.pt 2011-10-01 07:08:33 +0000 |
1309 | +++ src/schooltool/gradebook/browser/templates/f_template_manage.pt 2011-12-22 16:21:13 +0000 |
1310 | @@ -23,7 +23,7 @@ |
1311 | i18n:attributes="alt" /> |
1312 | </a> |
1313 | </td> |
1314 | - <td tal:content="activity/scoresystem/title "/> |
1315 | + <td tal:content="python: view.display_scoresystem(activity)" /> |
1316 | <td> |
1317 | <button class="image" type="submit" title="Delete" value="1" |
1318 | tal:attributes="name string:delete.${activity/__name__};" |
1319 | |
1320 | === modified file 'src/schooltool/gradebook/browser/templates/f_templates_overview.pt' |
1321 | --- src/schooltool/gradebook/browser/templates/f_templates_overview.pt 2011-09-26 18:30:13 +0000 |
1322 | +++ src/schooltool/gradebook/browser/templates/f_templates_overview.pt 2011-12-22 16:21:13 +0000 |
1323 | @@ -15,5 +15,9 @@ |
1324 | </tr> |
1325 | </table> |
1326 | </form> |
1327 | + <h3> |
1328 | + <a tal:attributes="href string:${context/schooltool:app/@@absolute_url}/manage" |
1329 | + i18n:translate="">Done</a> |
1330 | + </h3> |
1331 | </div> |
1332 | |
1333 | |
1334 | === modified file 'src/schooltool/gradebook/configure.zcml' |
1335 | --- src/schooltool/gradebook/configure.zcml 2011-11-22 17:30:59 +0000 |
1336 | +++ src/schooltool/gradebook/configure.zcml 2011-12-22 16:21:13 +0000 |
1337 | @@ -57,6 +57,18 @@ |
1338 | factory=".activity.getSectionActivities" |
1339 | trusted="true" |
1340 | /> |
1341 | + <adapter |
1342 | + for="schooltool.course.interfaces.ICourse" |
1343 | + provides=".interfaces.ICourseActivities" |
1344 | + factory=".activity.getCourseActivities" |
1345 | + trusted="true" |
1346 | + /> |
1347 | + <adapter |
1348 | + for="schooltool.course.interfaces.ICourse" |
1349 | + provides=".interfaces.ICourseDeployedWorksheets" |
1350 | + factory=".activity.getCourseDeployedWorksheets" |
1351 | + trusted="true" |
1352 | + /> |
1353 | |
1354 | <!-- Activity Content and Security --> |
1355 | <class class=".gradebook_init.GradebookRoot"> |
1356 | @@ -109,6 +121,26 @@ |
1357 | set_schema=".interfaces.IActivities" |
1358 | /> |
1359 | </class> |
1360 | + <class class=".activity.CourseActivities"> |
1361 | + <require |
1362 | + permission="schooltool.view" |
1363 | + interface=".interfaces.ICourseActivities" |
1364 | + /> |
1365 | + <require |
1366 | + permission="schooltool.edit" |
1367 | + set_schema=".interfaces.ICourseActivities" |
1368 | + /> |
1369 | + </class> |
1370 | + <class class=".activity.CourseDeployedWorksheets"> |
1371 | + <require |
1372 | + permission="schooltool.view" |
1373 | + interface=".interfaces.ICourseDeployedWorksheets" |
1374 | + /> |
1375 | + <require |
1376 | + permission="schooltool.edit" |
1377 | + set_schema=".interfaces.ICourseDeployedWorksheets" |
1378 | + /> |
1379 | + </class> |
1380 | <class class=".activity.Worksheet"> |
1381 | <allow interface="zope.interface.common.mapping.IReadMapping" /> |
1382 | <require |
1383 | @@ -136,6 +168,19 @@ |
1384 | attributes="changePosition" |
1385 | /> |
1386 | </class> |
1387 | + <class class=".activity.CourseWorksheet"> |
1388 | + <allow interface="zope.interface.common.mapping.IReadMapping" /> |
1389 | + <require |
1390 | + permission="schooltool.view" |
1391 | + attributes="keys __iter__ values items __len__ title deployed" |
1392 | + /> |
1393 | + <require |
1394 | + permission="schooltool.edit" |
1395 | + interface="zope.interface.common.mapping.IWriteMapping" |
1396 | + set_schema=".interfaces.ICourseWorksheet" |
1397 | + attributes="changePosition" |
1398 | + /> |
1399 | + </class> |
1400 | <class class=".activity.Activity"> |
1401 | <allow interface="zope.interface.common.mapping.IReadMapping" /> |
1402 | <require |
1403 | @@ -304,6 +349,12 @@ |
1404 | name="activities" |
1405 | adapter="schooltool.gradebook.interfaces.IActivities" |
1406 | /> |
1407 | + <adapterTraverserPlugin |
1408 | + for="schooltool.course.interfaces.ICourse" |
1409 | + layer="zope.publisher.interfaces.http.IHTTPRequest" |
1410 | + name="activities" |
1411 | + adapter="schooltool.gradebook.interfaces.ICourseActivities" |
1412 | + /> |
1413 | |
1414 | <!-- special traversal adapter for traversing from worksheet to gradebook --> |
1415 | <adapter |
1416 | |
1417 | === modified file 'src/schooltool/gradebook/interfaces.py' |
1418 | --- src/schooltool/gradebook/interfaces.py 2011-08-30 16:15:01 +0000 |
1419 | +++ src/schooltool/gradebook/interfaces.py 2011-12-22 16:21:13 +0000 |
1420 | @@ -89,6 +89,18 @@ |
1421 | contains('.IWorksheet') |
1422 | |
1423 | |
1424 | +class ICourseActivities(interfaces.IRequirement): |
1425 | + """Container of Course Worksheet Templates that can be deployed""" |
1426 | + |
1427 | + contains('.ICourseWorksheet') |
1428 | + |
1429 | + |
1430 | +class ICourseDeployedWorksheets(interfaces.IRequirement): |
1431 | + """Container of Deployed Course Worksheets (by term)""" |
1432 | + |
1433 | + contains('.IWorksheet') |
1434 | + |
1435 | + |
1436 | class IWorksheet(interfaces.IRequirement): |
1437 | '''A list of activities that must be fulfilled in a course or section.''' |
1438 | |
1439 | @@ -111,12 +123,15 @@ |
1440 | """Set the weight for the given category. Any numeric type is |
1441 | acceptable""" |
1442 | |
1443 | + def canAverage(): |
1444 | + """return True if activities have scoresystems that can be averaged""" |
1445 | + |
1446 | containers(IActivities) |
1447 | contains('.IActivity') |
1448 | |
1449 | |
1450 | class IReportWorksheet(interfaces.IRequirement): |
1451 | - '''A list of report card activities that get copied into sections.''' |
1452 | + '''A worksheet template to get copied into section gradebooks.''' |
1453 | |
1454 | containers(IGradebookTemplates, IGradebookDeployed) |
1455 | contains('.IReportActivity') |
1456 | @@ -126,13 +141,23 @@ |
1457 | description=_(u'Identifies the report sheet in teacher gradebooks.')) |
1458 | |
1459 | |
1460 | +class ICourseWorksheet(interfaces.IRequirement): |
1461 | + '''A worksheet template to get copied into section gradebooks.''' |
1462 | + |
1463 | + contains('.IActivity') |
1464 | + |
1465 | + title = zope.schema.TextLine( |
1466 | + title=_(u'Title'), |
1467 | + description=_(u'Identifies the course worksheet in gradebooks.')) |
1468 | + |
1469 | + |
1470 | class IActivity(interfaces.IRequirement): |
1471 | '''An activity to be graded''' |
1472 | |
1473 | due_date = zope.schema.Date( |
1474 | title=_("Due Date"), |
1475 | description=_("The date the activity is due to be graded."), |
1476 | - required=True) |
1477 | + required=False) |
1478 | |
1479 | label = zope.schema.TextLine( |
1480 | title=_(u"Label"), |
1481 | @@ -164,7 +189,7 @@ |
1482 | |
1483 | |
1484 | class IReportActivity(IActivity): |
1485 | - '''An activity to be deployed to section activities''' |
1486 | + '''A report card activity to be deployed to section activities''' |
1487 | |
1488 | containers(IReportWorksheet) |
1489 | |
1490 | |
1491 | === modified file 'src/schooltool/gradebook/tests/test_gradebook.py' |
1492 | --- src/schooltool/gradebook/tests/test_gradebook.py 2011-08-30 16:15:01 +0000 |
1493 | +++ src/schooltool/gradebook/tests/test_gradebook.py 2011-12-22 16:21:13 +0000 |
1494 | @@ -28,7 +28,7 @@ |
1495 | from zope.component import provideAdapter, provideUtility |
1496 | from zope.interface import classImplements |
1497 | |
1498 | -from schooltool.course.interfaces import ISection |
1499 | +from schooltool.course.interfaces import ICourse, ISection |
1500 | from schooltool.relationship.tests import setUpRelationships |
1501 | from schooltool.person.person import Person |
1502 | from schooltool.requirement import testing |
1503 | @@ -48,6 +48,12 @@ |
1504 | provideAdapter( |
1505 | activity.getSectionActivities, |
1506 | (ISection,), interfaces.IActivities) |
1507 | + provideAdapter( |
1508 | + activity.getCourseActivities, |
1509 | + (ICourse,), interfaces.ICourseActivities) |
1510 | + provideAdapter( |
1511 | + activity.getCourseDeployedWorksheets, |
1512 | + (ICourse,), interfaces.ICourseDeployedWorksheets) |
1513 | |
1514 | provideAdapter(gradebook.Gradebook) |
1515 |
I have removed your merge from flourish branch.
# Your local branch will conflict. Push it aside rejected
# $ bzr branch . ../flourish-
# and get the real trunk
# $ bzr pull --overwrite lp:schooltool.gradebook