NewWorkflow: patch-newworkflow-r1064.diff
| File patch-newworkflow-r1064.diff, 89.2 KB (added by pkou <pkou at ua.fm>, 7 years ago) |
|---|
-
htdocs/css/timeline.css
30 30 /* Apply icon background-image twice to avoid hover-flicker in IE/Win */ 31 31 dt.changeset, dt.changeset a { background-image: url(../changeset.png) !important } 32 32 dt.newticket, dt.newticket a { background-image: url(../newticket.png) !important } 33 dt.resolvedticket, dt.resolvedticket a { background-image: url(../resolvedticket.png) !important } 34 dt.reopenedticket, dt.reopenedticket a { background-image: url(../reopenedticket.png) !important } 33 35 dt.closedticket, dt.closedticket a { background-image: url(../closedticket.png) !important } 34 36 dt.wiki, dt.wiki a { background-image: url(../wiki.png) !important } 35 37 dt.milestone, dt.milestone a { background-image: url(../milestone.png) !important } -
wiki-default/TracIni
22 22 See also: TracLogging 23 23 24 24 == [ticket] == 25 || workflow || Ticket workflow class. If not specified, it is ''trac.workflows.SimpleWorkflow'' || 25 26 || default_version || Default version for newly created tickets || 26 27 || default_severity || Default severity for newly created tickets || 27 28 || default_priority || Default priority for newly created tickets || … … 54 55 55 56 [[BR]] 56 57 ---- 57 See also: TracGuide, TracAdmin 58 No newline at end of file 58 See also: TracGuide, TracAdmin -
wiki-default/TracAdmin
23 23 permission add <user> <action> -- Add a new permission rule 24 24 permission remove <user> <action> -- Remove permission rule 25 25 component list -- Show available components 26 component add <name> <owner> -- Add a new component26 component add <name> <owner> [<qaowner>] -- Add a new component 27 27 component rename <name> <newname> -- Rename a component 28 28 component remove <name> -- Remove/uninstall component 29 component chown <name> <owner> -- Change component ownership29 component chown <name> <owner> [<qaowner>] -- Change component ownership 30 30 priority list -- Show possible ticket priorities 31 31 priority add <value> -- Add a priority value option 32 32 priority change <value> <newvalue> -- Change a priority value … … 41 41 version time <name> <time> -- Set version date/time 42 42 version remove <name> -- Remove version 43 43 milestone list -- Show milestones 44 milestone add <name> [ time]-- Add milestone44 milestone add <name> [<owner> [time]] -- Add milestone 45 45 milestone rename <name> <newname> -- Rename milestone 46 46 milestone time <name> <time> -- Set milestone date/time 47 milestone chown <name> <owner> -- Change milestone ownership 47 48 milestone remove <name> -- Remove milestone 48 49 }}} 49 50 -
scripts/trac-admin
290 290 291 291 # ## Component 292 292 _help_component = [('component list', 'Show available components'), 293 ('component add <name> <owner> ', 'Add a new component'),293 ('component add <name> <owner> [<qaowner>]', 'Add a new component'), 294 294 ('component rename <name> <newname>', 'Rename a component'), 295 295 ('component remove <name>', 'Remove/uninstall component'), 296 ('component chown <name> <owner> ', 'Change component ownership')]296 ('component chown <name> <owner> [<qaowner>]', 'Change component ownership')] 297 297 298 298 def complete_component (self, text, line, begidx, endidx): 299 299 if begidx in [16,17]: … … 309 309 try: 310 310 if arg[0] == 'list': 311 311 self._do_component_list() 312 elif arg[0] == 'add' and len(arg) ==3:312 elif arg[0] == 'add' and len(arg) in [3,4]: 313 313 name = arg[1] 314 314 owner = arg[2] 315 self._do_component_add(name, owner) 315 if len(arg) == 4: 316 qaowner = arg[3] 317 else: 318 qaowner = owner 319 self._do_component_add(name, owner, qaowner) 316 320 elif arg[0] == 'rename' and len(arg)==3: 317 321 name = arg[1] 318 322 newname = arg[2] … … 320 324 elif arg[0] == 'remove' and len(arg)==2: 321 325 name = arg[1] 322 326 self._do_component_remove(name) 323 elif arg[0] == 'chown' and len(arg) ==3:327 elif arg[0] == 'chown' and len(arg) in [3,4]: 324 328 name = arg[1] 325 329 owner = arg[2] 326 self._do_component_set_owner(name, owner) 330 if len(arg) == 4: 331 qaowner = arg[3] 332 else: 333 qaowner = owner 334 self._do_component_set_owner(name, owner, qaowner) 327 335 else: 328 336 self.do_help ('component') 329 337 except Exception, e: 330 338 print 'Component %s failed:' % arg[0], e 331 339 332 340 def _do_component_list(self): 333 data = self.db_execsql('SELECT name, owner FROM component')334 self.print_listing(['Name', 'Owner' ], data)341 data = self.db_execsql('SELECT name, owner, qaowner FROM component') 342 self.print_listing(['Name', 'Owner', 'QA Owner'], data) 335 343 336 def _do_component_add(self, name, owner ):337 data = self.db_execsql("INSERT INTO component VALUES('%s', '%s' )"338 % (name, owner))344 def _do_component_add(self, name, owner, qaowner): 345 data = self.db_execsql("INSERT INTO component VALUES('%s', '%s', '%s')" 346 % (name,owner,qaowner)) 339 347 340 348 def _do_component_rename(self, name, newname): 341 349 cnx = self.db_open() … … 360 368 data = self.db_execsql("DELETE FROM component WHERE name='%s'" 361 369 % (name)) 362 370 363 def _do_component_set_owner(self, name, owner ):371 def _do_component_set_owner(self, name, owner, qaowner): 364 372 cnx = self.db_open() 365 373 cursor = cnx.cursor () 366 374 cursor.execute('SELECT name FROM component WHERE name=%s', name) 367 375 data = cursor.fetchone() 368 376 if not data: 369 377 raise Exception("No such component '%s'" % name) 370 data = self.db_execsql("UPDATE component SET owner='%s' WHERE name='%s'"371 % (owner, name))378 data = self.db_execsql("UPDATE component SET owner='%s', qaowner='%s' WHERE name='%s'" 379 % (owner,qaowner,name)) 372 380 373 381 374 382 ## Permission … … 795 803 796 804 ## Milestone 797 805 _help_milestone = [('milestone list', 'Show milestones'), 798 ('milestone add <name> [ time]', 'Add milestone'),806 ('milestone add <name> [<owner> [time]]', 'Add milestone'), 799 807 ('milestone rename <name> <newname>', 800 808 'Rename milestone'), 809 ('milestone chown <name> <newowner>', 'Change milestone owner'), 801 810 ('milestone time <name> <time>', 'Set milestone date (Format: "Jun 3, 2003")'), 802 811 ('milestone remove <name>', 'Remove milestone')] 803 812 … … 805 814 806 815 if begidx in [15,17]: 807 816 comp = self.get_milestone_list () 817 elif begidx > 15 and line.startswith('milestone chown '): 818 comp = self.get_user_list() 808 819 elif begidx < 15: 809 comp = ['list','add','rename',' time','remove']820 comp = ['list','add','rename','chown','time','remove'] 810 821 return self.word_complete(text, comp) 811 822 812 823 def do_milestone(self, line): 813 self._do_mile_ver('milestone', line) 824 type = 'milestone' 825 arg = self.arg_tokenize(line) 826 try: 827 if arg[0] == 'list': 828 self._do_milestone_list() 829 elif arg[0] == 'add' and len(arg) in [2,3,4]: 830 name = arg[1] 831 self._do_mile_ver_add(type, name) 832 if len(arg) >= 3: 833 owner = arg[2] 834 self._do_mile_ver_chown(type, name, owner) 835 if len(arg) >= 4: 836 time = arg[3] 837 self._do_mile_ver_time(type, name, time) 838 elif arg[0] == 'rename' and len(arg)==3: 839 name = arg[1] 840 newname = arg[2] 841 self._do_mile_ver_rename(type, name, newname) 842 elif arg[0] == 'chown' and len(arg)==3: 843 name = arg[1] 844 owner = arg[2] 845 self._do_mile_ver_chown(type, name, owner) 846 elif arg[0] == 'time' and len(arg)==3: 847 name = arg[1] 848 time = arg[2] 849 self._do_mile_ver_time(type, name, time) 850 elif arg[0] == 'remove' and len(arg)==2: 851 name = arg[1] 852 self._do_mile_ver_remove(type, name) 853 else: 854 self.do_help (type) 855 except Exception, e: 856 print 'Command %s failed:' % arg[0], e 814 857 858 def _do_milestone_list(self): 859 data = self.db_execsql("SELECT name,owner,time FROM milestone ORDER BY time,name") 860 data = map(lambda x: (x[0], x[1], x[2] and time.strftime('%c', time.localtime(x[2]))), data) 861 #print data 862 self.print_listing(['Name', 'Owner', 'Time'], data) 815 863 864 816 865 ## Version 817 866 _help_version = [('version list', 'Show versions'), 818 867 ('version add <name> [time]', 'Add version'), … … 832 881 def do_version(self, line): 833 882 self._do_mile_ver('version', line) 834 883 835 # Milestone and Version are identical, methods884 # Milestone and Version are almost identical, methods 836 885 837 886 def _do_mile_ver(self, type, line): 838 887 arg = self.arg_tokenize(line) … … 923 972 else: 924 973 print >> sys.stderr, 'Unknown time format' 925 974 975 def _do_mile_ver_chown(self, type, name, owner): 976 data = self.db_execsql("UPDATE %s SET owner='%s' WHERE name='%s'" 977 % (type, owner, name)); 978 926 979 _help_upgrade = [('upgrade', 'Upgrade database to current version.')] 927 980 def do_upgrade(self, line): 928 981 arg = self.arg_tokenize(line) -
setup.py
198 198 author_email="info@edgewall.com", 199 199 license=LICENSE, 200 200 url=URL, 201 packages=['trac', 'trac.upgrades', 'trac.wikimacros', 'trac.mimeviewers'], 201 packages=['trac', 'trac.upgrades', 'trac.wikimacros', 'trac.mimeviewers', 202 'trac.workflows'], 202 203 data_files=[(_p('share/trac/templates'), glob('templates/*')), 203 204 (_p('share/trac/htdocs'), glob(_p('htdocs/*.*')) + [_p('htdocs/README')]), 204 205 (_p('share/trac/htdocs/css'), glob(_p('htdocs/css/*'))), -
trac/db_default.py
21 21 22 22 23 23 # Database version identifier. Used for automatic upgrades. 24 db_version = 724 db_version = 8 25 25 26 26 def __mkreports(reps): 27 27 """Utility function used to create report data in same syntax as the … … 125 125 ); 126 126 CREATE TABLE component ( 127 127 name text PRIMARY KEY, 128 owner text 128 owner text, 129 qaowner text 129 130 ); 130 131 CREATE TABLE milestone ( 131 132 id integer PRIMARY KEY, 132 133 name text, 133 134 time integer, 135 owner text, 134 136 descr text, 135 137 UNIQUE(name) 136 138 ); … … 209 211 """, 210 212 """ 211 213 SELECT p.value AS __color__, 212 versionAS __group__,213 id AS ticket, summary, component, version, severity,214 (CASE WHEN IFNULL(version, '') = '' THEN 'Not Specified' ELSE 'Version ' || version END) AS __group__, 215 id AS ticket, summary, component, milestone, severity, 214 216 (CASE status WHEN 'assigned' THEN owner||' *' ELSE owner END) AS owner, 215 217 time AS created, 216 218 changetime AS _changetime, description AS _description, … … 218 220 FROM ticket t, enum p 219 221 WHERE status IN ('new', 'assigned', 'reopened') 220 222 AND p.name = t.priority AND p.type = 'priority' 221 ORDER BY ( version IS NULL),version, p.value, severity, time223 ORDER BY (IFNULL(version, '') = '') DESC,version, p.value, severity, time 222 224 """), 223 225 #---------------------------------------------------------------------------- 224 ('A llTickets by Milestone',226 ('Active Tickets by Milestone', 225 227 """ 226 228 This report shows how to color results by priority, 227 229 while grouping results by milestone. … … 231 233 """, 232 234 """ 233 235 SELECT p.value AS __color__, 234 milestone||' Release'AS __group__,236 (CASE WHEN IFNULL(milestone, '') = '' THEN 'Not Assigned' ELSE milestone||' Release' END) AS __group__, 235 237 id AS ticket, summary, component, version, severity, 236 238 (CASE status WHEN 'assigned' THEN owner||' *' ELSE owner END) AS owner, 237 239 time AS created, … … 240 242 FROM ticket t, enum p 241 243 WHERE status IN ('new', 'assigned', 'reopened') 242 244 AND p.name = t.priority AND p.type = 'priority' 243 ORDER BY ( milestone IS NULL),milestone, p.value, severity, time245 ORDER BY (IFNULL(milestone, '') = '') DESC,milestone, p.value, severity, time 244 246 """), 245 247 #---------------------------------------------------------------------------- 246 248 ('Assigned, Active Tickets by Owner', … … 248 250 List assigned tickets, group by ticket owner, sorted by priority. 249 251 """, 250 252 """ 251 252 253 SELECT p.value AS __color__, 253 ownerAS __group__,254 id AS ticket, summary, component, milestone, severity, time AS created,254 (CASE WHEN IFNULL(owner, '') = '' THEN 'Not Assigned' ELSE owner END) AS __group__, 255 id AS ticket, summary, component, version, milestone, severity, time AS created, 255 256 changetime AS _changetime, description AS _description, 256 257 reporter AS _reporter 257 258 FROM ticket t,enum p 258 259 WHERE status = 'assigned' 259 260 AND p.name=t.priority AND p.type='priority' 260 ORDER BY owner, p.value, severity, time261 ORDER BY (IFNULL(owner, '') = '') DESC, owner, p.value, severity, time 261 262 """), 262 263 #---------------------------------------------------------------------------- 263 264 ('Assigned, Active Tickets by Owner (Full Description)', … … 268 269 """ 269 270 SELECT p.value AS __color__, 270 271 owner AS __group__, 271 id AS ticket, summary, component, milestone, severity, time AS created,272 id AS ticket, summary, component, version, milestone, severity, time AS created, 272 273 description AS _description_, 273 274 changetime AS _changetime, reporter AS _reporter 274 275 FROM ticket t, enum p … … 283 284 """, 284 285 """ 285 286 SELECT p.value AS __color__, 286 t.milestoneAS __group__,287 (CASE WHEN IFNULL(t.milestone, '') = '' THEN 'Not Assigned' ELSE t.milestone || ' Release' END) AS __group__, 287 288 (CASE status 288 289 WHEN 'closed' THEN 'color: #777; background: #ddd; border-color: #ccc;' 289 290 ELSE … … 295 296 time AS _time,reporter AS _reporter 296 297 FROM ticket t,enum p 297 298 WHERE p.name=t.priority AND p.type='priority' 298 ORDER BY ( milestone IS NULL), milestone DESC, (status = 'closed'),299 ORDER BY (IFNULL(milestone, '') = '') DESC, milestone DESC, (status = 'closed'), 299 300 (CASE status WHEN 'closed' THEN modified ELSE -p.value END) DESC 300 301 """), 301 302 #---------------------------------------------------------------------------- … … 308 309 """ 309 310 SELECT p.value AS __color__, 310 311 (CASE status WHEN 'assigned' THEN 'Assigned' ELSE 'Owned' END) AS __group__, 311 id AS ticket, summary, component, version, milestone,312 id AS ticket, summary, component, status, version, milestone, 312 313 severity, priority, time AS created, 313 314 changetime AS _changetime, description AS _description, 314 315 reporter AS _reporter 315 316 FROM ticket t, enum p 316 WHERE t.status IN ('new', 'assigned', 'reopened')317 WHERE t.status <> 'closed' 317 318 AND p.name = t.priority AND p.type = 'priority' AND owner = '$USER' 318 319 ORDER BY (status = 'assigned') DESC, p.value, milestone, severity, time 319 320 """), … … 338 339 WHERE status IN ('new', 'assigned', 'reopened') 339 340 AND p.name = t.priority AND p.type = 'priority' 340 341 ORDER BY (owner = '$USER') DESC, p.value, milestone, severity, time 342 """), 343 #---------------------------------------------------------------------------- 344 ('Open Tickets, Mine first', 345 """ 346 * List all not closed tickets by priority. 347 * Show all tickets owned by the logged in user in a group first. 348 """, 349 """ 350 SELECT p.value AS __color__, 351 (CASE owner 352 WHEN '$USER' THEN 'My Tickets' 353 ELSE 'Open Tickets' 354 END) AS __group__, 355 id AS ticket, summary, component, status, version, milestone, severity, 356 (CASE status WHEN 'assigned' THEN owner||' *' ELSE owner END) AS owner, 357 time AS created, 358 changetime AS _changetime, description AS _description, 359 reporter AS _reporter 360 FROM ticket t, enum p 361 WHERE status <> 'closed' 362 AND p.name = t.priority AND p.type = 'priority' 363 ORDER BY (owner = '$USER') DESC, p.value, milestone, severity, time 364 """), 365 #---------------------------------------------------------------------------- 366 ('Open Tickets by Version', 367 """ 368 * List all not closed tickets by priority. 369 * Group results by version. 370 """, 371 """ 372 SELECT p.value AS __color__, 373 (CASE WHEN IFNULL(version, '') = '' THEN 'Not Specified' ELSE 'Version ' || version END) AS __group__, 374 id AS ticket, summary, component, status, milestone, severity, 375 (CASE status WHEN 'assigned' THEN owner||' *' ELSE owner END) AS owner, 376 time AS created, 377 changetime AS _changetime, description AS _description, 378 reporter AS _reporter 379 FROM ticket t, enum p 380 WHERE status <> 'closed' 381 AND p.name = t.priority AND p.type = 'priority' 382 ORDER BY (IFNULL(version, '') = '') desc,version, p.value, severity, time 383 """), 384 #---------------------------------------------------------------------------- 385 ('Open Tickets by Milestone', 386 """ 387 * List all not closed tickets by priority. 388 * Group results by milestone. 389 """, 390 """ 391 SELECT p.value AS __color__, 392 (CASE WHEN IFNULL(milestone, '') = '' THEN 'Not Assigned' ELSE milestone||' Release' END) AS __group__, 393 id AS ticket, summary, component, status, version, severity, 394 (CASE status WHEN 'assigned' THEN owner||' *' ELSE owner END) AS owner, 395 time AS created, 396 changetime AS _changetime, description AS _description, 397 reporter AS _reporter 398 FROM ticket t, enum p 399 WHERE status <> 'closed' 400 AND p.name = t.priority AND p.type = 'priority' 401 ORDER BY (IFNULL(milestone, '') = '') DESC,milestone, p.value, severity, time 402 """), 403 #---------------------------------------------------------------------------- 404 ('Open Tickets by Owner', 405 """ 406 List not closed tickets, group by ticket owner, sorted by priority. 407 """, 408 """ 409 SELECT p.value AS __color__, 410 (CASE WHEN IFNULL(owner, '') = '' THEN 'Not Assigned' ELSE owner END) AS __group__, 411 id AS ticket, summary, component, status, version, milestone, severity, 412 time AS created, changetime AS _changetime, description AS _description, 413 reporter AS _reporter 414 FROM ticket t,enum p 415 WHERE status <> 'closed' 416 AND p.name=t.priority AND p.type='priority' 417 ORDER BY (IFNULL(owner, '') = '') DESC, owner, p.value, severity, time 418 """), 419 #---------------------------------------------------------------------------- 420 ('Open Tickets by Status', 421 """ 422 * List all not closed tickets by priority. 423 * Group results by status. 424 """, 425 """ 426 SELECT p.value AS __color__, 427 status AS __group__, 428 id AS ticket, summary, component, version, milestone, severity, owner, 429 time AS created, 430 changetime AS _changetime, description AS _description, 431 reporter AS _reporter 432 FROM ticket t, enum q, enum p 433 WHERE status <> 'closed' 434 AND q.name = t.status AND q.type = 'status' 435 AND p.name = t.priority AND p.type = 'priority' 436 ORDER BY q.value, p.value, severity, time 437 """), 438 #---------------------------------------------------------------------------- 439 ('Resolved Tickets, Mine first', 440 """ 441 * List all resolved tickets by priority. 442 * Show all tickets owned by the logged in user in a group first. 443 """, 444 """ 445 SELECT p.value AS __color__, 446 (CASE owner 447 WHEN '$USER' THEN 'My Tickets' 448 ELSE 'Active Tickets' 449 END) AS __group__, 450 id AS ticket, summary, component, version, milestone, severity, 451 (CASE status WHEN 'assigned' THEN owner||' *' ELSE owner END) AS owner, 452 time AS created, 453 changetime AS _changetime, description AS _description, 454 reporter AS _reporter 455 FROM ticket t, enum p 456 WHERE status = 'resolved' 457 AND p.name = t.priority AND p.type = 'priority' 458 ORDER BY (owner = '$USER') DESC, p.value, milestone, severity, time 459 """), 460 #---------------------------------------------------------------------------- 461 ('Resolved Tickets by Milestone', 462 """ 463 List resolved tickets, sorted by priority, grouped by milestone 464 """, 465 """ 466 SELECT p.value AS __color__, 467 (CASE WHEN IFNULL(milestone, '') = '' THEN 'Not Assigned' ELSE milestone||' Release' END) AS __group__, 468 id AS ticket, summary, component, version, severity, 469 (CASE status WHEN 'assigned' THEN owner||' *' ELSE owner END) AS owner, 470 time AS created, 471 changetime AS _changetime, description AS _description, 472 reporter AS _reporter 473 FROM ticket t, enum p 474 WHERE status = 'resolved' 475 AND p.name = t.priority AND p.type = 'priority' 476 ORDER BY (IFNULL(milestone, '') = '') DESC,milestone, p.value, severity, time 477 """), 478 #---------------------------------------------------------------------------- 479 ('Resolved Tickets by Owner', 480 """ 481 List resolved tickets, group by ticket owner, sorted by priority. 482 """, 483 """ 484 SELECT p.value AS __color__, 485 (CASE WHEN IFNULL(owner, '') = '' THEN 'Not Assigned' ELSE owner END) AS __group__, 486 id AS ticket, summary, component, version, milestone, severity, time AS created, 487 changetime AS _changetime, description AS _description, 488 reporter AS _reporter 489 FROM ticket t,enum p 490 WHERE status = 'resolved' 491 AND p.name=t.priority AND p.type='priority' 492 ORDER BY (IFNULL(owner, '') = '') DESC, owner, p.value, severity, time 493 """), 494 #---------------------------------------------------------------------------- 495 ('Completed Tickets by Milestone (Full Description)', 496 """ 497 Release Notes: List verified and closed tickets, group by milestone, include description. 498 """, 499 """ 500 SELECT p.value AS __color__, 501 (CASE WHEN IFNULL(milestone, '') = '' THEN 'Not Assigned' ELSE milestone||' Release' END) AS __group__, 502 id AS ticket, summary, component, status, version, severity, time AS created, 503 description AS _description_, 504 changetime AS _changetime, reporter AS _reporter 505 FROM ticket t, enum p 506 WHERE status IN ('verified', 'closed') 507 AND p.name = t.priority AND p.type = 'priority' 508 ORDER BY (IFNULL(milestone, '') = '') DESC,milestone, p.value, severity, time 341 509 """)) 342 510 343 511 … … 347 515 348 516 # (table, (column1, column2), ((row1col1, row1col2), (row2col1, row2col2))) 349 517 data = (('component', 350 ('name', 'owner' ),351 (('component1', 'somebody' ),352 ('component2', 'somebody' ))),518 ('name', 'owner', 'qaowner'), 519 (('component1', 'somebody', 'qasomebody'), 520 ('component2', 'somebody', 'qasomebody'))), 353 521 ('milestone', 354 522 ('name', 'time'), 355 523 (('', 0), … … 367 535 (('status', 'new', 1), 368 536 ('status', 'assigned', 2), 369 537 ('status', 'reopened', 3), 370 ('status', 'closed', 4), 538 ('status', 'resolved', 4), 539 ('status', 'verified', 5), 540 ('status', 'closed', 6), 371 541 ('resolution', 'fixed', 1), 372 542 ('resolution', 'invalid', 2), 373 543 ('resolution', 'wontfix', 3), … … 426 596 ('project', 'footer', 427 597 ' Visit the Trac open source project at<br />' 428 598 '<a href="http://trac.edgewall.com/">http://trac.edgewall.com/</a>'), 599 ('ticket', 'workflow', 'trac.workflows.QaRmtWorkflow'), 429 600 ('ticket', 'default_version', ''), 430 601 ('ticket', 'default_severity', 'normal'), 431 602 ('ticket', 'default_priority', 'normal'), -
trac/Milestone.py
60 60 if not group: 61 61 queries['all_tickets'] = env.href.query({'milestone': milestone}) 62 62 queries['active_tickets'] = env.href.query({ 63 'milestone': milestone, 'status': ['new', 'assigned', 'reopened' ]63 'milestone': milestone, 'status': ['new', 'assigned', 'reopened', 'resolved'] 64 64 }) 65 65 queries['closed_tickets'] = env.href.query({ 66 'milestone': milestone, 'status': 'closed'66 'milestone': milestone, 'status': ['closed', 'verified'] 67 67 }) 68 68 else: 69 69 queries['all_tickets'] = env.href.query({ … … 71 71 }) 72 72 queries['active_tickets'] = env.href.query({ 73 73 'milestone': milestone, grouped_by: group, 74 'status': ['new', 'assigned', 'reopened' ]74 'status': ['new', 'assigned', 'reopened', 'resolved'] 75 75 }) 76 76 queries['closed_tickets'] = env.href.query({ 77 77 'milestone': milestone, grouped_by: group, 78 'status': 'closed'78 'status': ['closed', 'verified'] 79 79 }) 80 80 return queries 81 81 82 82 def calc_ticket_stats(tickets): 83 83 total_cnt = len(tickets) 84 active = [ticket for ticket in tickets if ticket['status'] != 'closed' ]84 active = [ticket for ticket in tickets if ticket['status'] != 'closed' and ticket['status'] != 'verified'] 85 85 active_cnt = len(active) 86 86 closed_cnt = total_cnt - active_cnt 87 87 … … 116 116 if datestr: 117 117 date = self.parse_date(datestr) 118 118 descr = self.args.get('descr', '') 119 owner = self.args.get('owner', '') 119 120 if not id: 120 self.create_milestone(name, date, descr )121 self.create_milestone(name, date, descr, owner) 121 122 else: 122 self.update_milestone(id, name, date, descr )123 self.update_milestone(id, name, date, descr, owner) 123 124 elif id: 124 125 self.req.redirect(self.env.href.milestone(id)) 125 126 else: … … 141 142 'Invalid Date Format') 142 143 return seconds 143 144 144 def create_milestone(self, name, date=0, descr='' ):145 def create_milestone(self, name, date=0, descr='', owner=''): 145 146 self.perm.assert_permission(perm.MILESTONE_CREATE) 146 147 if not name: 147 148 raise TracError('You must provide a name for the milestone.', 148 149 'Required Field Missing') 149 150 cursor = self.db.cursor() 150 151 self.log.debug("Creating new milestone '%s'" % name) 151 cursor.execute("INSERT INTO milestone (id, name, time, descr ) "152 "VALUES (NULL, %s, %d, %s )", name, date, descr)152 cursor.execute("INSERT INTO milestone (id, name, time, descr, owner) " 153 "VALUES (NULL, %s, %d, %s, %s)", name, date, descr, owner) 153 154 self.db.commit() 154 155 self.req.redirect(self.env.href.milestone(name)) 155 156 … … 178 179 else: 179 180 self.req.redirect(self.env.href.milestone(id)) 180 181 181 def update_milestone(self, id, name, date, descr ):182 def update_milestone(self, id, name, date, descr, owner): 182 183 self.perm.assert_permission(perm.MILESTONE_MODIFY) 183 184 cursor = self.db.cursor() 184 185 self.log.info("Updating milestone '%s'" % id) … … 188 189 cursor.execute('UPDATE ticket SET milestone = %s ' 189 190 'WHERE milestone = %s', name, id) 190 191 cursor.execute("UPDATE milestone SET name = %s, time = %d, " 191 "descr = %s WHERE name = %s",192 name, date, descr, id)192 "descr = %s, owner = %s WHERE name = %s", 193 name, date, descr, owner, id) 193 194 self.db.commit() 194 195 self.req.redirect(self.env.href.milestone(name)) 195 196 else: … … 222 223 223 224 def get_milestone(self, name): 224 225 cursor = self.db.cursor() 225 cursor.execute("SELECT name, time, descr FROM milestone "226 cursor.execute("SELECT name, time, descr, owner FROM milestone " 226 227 "WHERE name = %s ORDER BY time, name", name) 227 228 row = cursor.fetchone() 228 229 cursor.close() … … 237 238 t = row['time'] and int(row['time']) 238 239 if t > 0: 239 240 milestone['date'] = time.strftime('%x', time.localtime(t)) 241 milestone['owner'] = row['owner'] or '' 240 242 return milestone 241 243 242 244 def render(self): -
trac/Timeline.py
52 52 REOPENED_TICKET = 4 53 53 WIKI = 5 54 54 MILESTONE = 6 55 VERIFIED_TICKET = 7 56 RESOLVED_TICKET = 8 57 RETESTED_TICKET = 9 55 58 56 59 q = [] 57 60 if changeset: … … 60 63 "FROM revision WHERE time>=%s AND time<=%s" % 61 64 (start, stop)) 62 65 if tickets: 66 # New tickets 63 67 q.append("SELECT time, id AS idata, '' AS tdata, 2 AS type, " 64 68 "summary AS message, reporter AS author " 65 69 "FROM ticket WHERE time>=%s AND time<=%s" % 66 70 (start, stop)) 67 q.append("SELECT time, ticket AS idata, '' AS tdata, 4 AS type, " 68 "'' AS message, author " 69 "FROM ticket_change WHERE field='status' " 70 "AND newvalue='reopened' AND time>=%s AND time<=%s" % 71 (start, stop)) 71 # Reopened tickets 72 72 q.append("SELECT t1.time AS time, t1.ticket AS idata," 73 " '' AS tdata, 4 AS type," 74 " t3.newvalue AS message, t1.author AS author" 75 " FROM ticket_change t1" 76 " LEFT OUTER JOIN ticket_change t3 ON t1.time = t3.time" 77 " AND t1.ticket = t3.ticket AND t3.field = 'comment'" 78 " WHERE t1.field = 'status' AND t1.newvalue = 'reopened'" 79 " AND t1.time >= %s AND t1.time <= %s" % (start,stop)) 80 # Closed tickets (including resolution field for old workflow) 81 q.append("SELECT t1.time AS time, t1.ticket AS idata," 73 82 " t2.newvalue AS tdata, 3 AS type," 74 83 " t3.newvalue AS message, t1.author AS author" 75 84 " FROM ticket_change t1" 76 " INNER JOIN ticket_change t2 ON t1.ticket = t2.ticket"77 " AND t1.time = t2.time "85 " LEFT OUTER JOIN ticket_change t2 ON t1.ticket = t2.ticket" 86 " AND t1.time = t2.time AND t2.field = 'resolution'" 78 87 " LEFT OUTER JOIN ticket_change t3 ON t1.time = t3.time" 79 88 " AND t1.ticket = t3.ticket AND t3.field = 'comment'" 80 89 " WHERE t1.field = 'status' AND t1.newvalue = 'closed'" 81 " AND t2.field = 'resolution'"82 90 " AND t1.time >= %s AND t1.time <= %s" % (start,stop)) 91 # Verified tickets (including resolution field for customized workflows) 92 q.append("SELECT t1.time AS time, t1.ticket AS idata," 93 " t2.newvalue AS tdata, 7 AS type," 94 " t3.newvalue AS message, t1.author AS author" 95 " FROM ticket_change t1" 96 " LEFT OUTER JOIN ticket_change t2 ON t1.ticket = t2.ticket" 97 " AND t1.time = t2.time AND t2.field = 'resolution'" 98 " LEFT OUTER JOIN ticket_change t3 ON t1.time = t3.time" 99 " AND t1.ticket = t3.ticket AND t3.field = 'comment'" 100 " WHERE t1.field = 'status' AND t1.newvalue = 'verified'" 101 " AND t1.oldvalue<>'closed'" 102 " AND t1.time >= %s AND t1.time <= %s" % (start,stop)) 103 # Resolved tickets (including resolution field) 104 q.append("SELECT t1.time AS time, t1.ticket AS idata," 105 " t2.newvalue AS tdata, 8 AS type," 106 " t3.newvalue AS message, t1.author AS author" 107 " FROM ticket_change t1" 108 " LEFT OUTER JOIN ticket_change t2 ON t1.ticket = t2.ticket" 109 " AND t1.time = t2.time AND t2.field = 'resolution'" 110 " LEFT OUTER JOIN ticket_change t3 ON t1.time = t3.time" 111 " AND t1.ticket = t3.ticket AND t3.field = 'comment'" 112 " WHERE t1.field = 'status' AND t1.newvalue = 'resolved'" 113 " AND t1.oldvalue NOT IN ('verified', 'closed')" 114 " AND t1.time >= %s AND t1.time <= %s" % (start,stop)) 115 # Retested tickets 116 q.append("SELECT t1.time AS time, t1.ticket AS idata," 117 " '' AS tdata, 9 AS type," 118 " t3.newvalue AS message, t1.author AS author" 119 " FROM ticket_change t1" 120 " LEFT OUTER JOIN ticket_change t3 ON t1.time = t3.time" 121 " AND t1.ticket = t3.ticket AND t3.field = 'comment'" 122 " WHERE t1.field = 'status' AND t1.newvalue = 'resolved'" 123 " AND t1.oldvalue IN ('verified', 'closed')" 124 " AND t1.time >= %s AND t1.time <= %s" % (start,stop)) 83 125 if wiki: 84 126 q.append("SELECT time, -1 AS idata, name AS tdata, 5 AS type, " 85 127 "comment AS message, author " … … 87 129 (start, stop)) 88 130 if milestone: 89 131 q.append("SELECT time, -1 AS idata, '' AS tdata, 6 AS type, " 90 "name AS message, ''AS author "132 "name AS message, owner AS author " 91 133 "FROM milestone WHERE time>=%s AND time<=%s" % 92 134 (start, stop)) 93 135 … … 110 152 'date': time.strftime('%x', t), 111 153 'datetime': time.strftime('%a, %d %b %Y %H:%M:%S GMT', gmt), 112 154 'idata': int(row['idata']), 113 'tdata': row['tdata'] ,155 'tdata': row['tdata'] or '', 114 156 'type': int(row['type']), 115 157 'message': row['message'] or '', 116 158 'author': util.escape(row['author'] or 'anonymous') -
trac/workflows/Base.py
1 # -*- coding: iso8859-1 -*- 2 # 3 # Copyright (C) 2003, 2004 Edgewall Software 4 # Copyright (C) 2003, 2004 Jonas Borgström <jonas@edgewall.com> 5 # 6 # Trac is free software; you can redistribute it and/or 7 # modify it under the terms of the GNU General Public License as 8 # published by the Free Software Foundation; either version 2 of the 9 # License, or (at your option) any later version. 10 # 11 # Trac is distributed in the hope that it will be useful, 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 # General Public License for more details. 15 # 16 # You should have received a copy of the GNU General Public License 17 # along with this program; if not, write to the Free Software 18 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 # 20 # Author: Pavel Kourochka <pkou@ua.fm> 21 # 22 # Abstract workflow definition 23 24 class WorkflowBase: 25 """ 26 Generic workflow class for Trac. 27 """ 28 29 def __init__(self, env, db, user): 30 """ 31 Constructor for workflow class. 32 """ 33 self.env = env 34 self.db = db 35 self.user = user 36 37 def get_actions(self, ticket): 38 """ 39 For existing tickets only. 40 Return the list of available actions for specified ticket. 41 """ 42 raise Exception, "WorkflowBase::get_actions not implemented" 43 44 def do_action(self, ticket, action, args): 45 """ 46 For new and existing tickets. 47 Perform action on a ticket. For new tickets, action name is 'create'. 48 """ 49 raise Exception, "WorkflowBase::do_action not implemented" 50 51 def get_actions_template(self, ticket): 52 """ 53 For new and existing tickets. 54 Return the name of ClearSilver template file for the workflow. 55 Return None if no additional template is required. 56 """ 57 return None 58 59 def init_template(self, ticket, hdf): 60 """ 61 For new and existing tickets. 62 Initialize ClearSilver variables for actions template. 63 Called if get_actions_template() returns file name only. 64 """ 65 pass 66 67 def validate(self, ticket): 68 """ 69 For new and existing tickets. 70 Validate ticket. 71 Return list of Wiki strings that describe errors in the ticket. 72 """ 73 return [] 74 75 def on_insert(self, ticket): 76 """ 77 For new tickets only. 78 Update ticket fields just before inserting the ticket into database. 79 """ 80 pass 81 82 def on_update(self, ticket): 83 """ 84 For existing tickets only. 85 Update ticket fields just before saving the ticket into database. 86 """ 87 pass -
trac/workflows/QaRmtWorkflow.py
1 # -*- coding: iso8859-1 -*- 2 # 3 # Copyright (C) 2003, 2004 Edgewall Software 4 # Copyright (C) 2003, 2004 Jonas Borgström <jonas@edgewall.com> 5 # 6 # Trac is free software; you can redistribute it and/or 7 # modify it under the terms of the GNU General Public License as 8 # published by the Free Software Foundation; either version 2 of the 9 # License, or (at your option) any later version. 10 # 11 # Trac is distributed in the hope that it will be useful, 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 # General Public License for more details. 15 # 16 # You should have received a copy of the GNU General Public License 17 # along with this program; if not, write to the Free Software 18 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 # 20 # Author: Pavel Kourochka <pkou@ua.fm> 21 # 22 # Workflow definition for development, QA, and release management teams 23 24 from trac.workflows.SimpleWorkflow import SimpleWorkflow 25 26 class QaRmtWorkflow(SimpleWorkflow): 27 28 def get_actions(self, ticket): 29 actions = { 30 'new': ['leave','reassign','resolve', 'accept'], 31 'assigned': ['leave','reassign','resolve', ], 32 'reopened': ['leave','reassign','resolve', ], 33 'resolved': ['leave','reassign', 'reopen', 'close','verify'], 34 'verified': ['leave','reassign', 'reopen','retest','close' ], 35 'closed': ['leave', 'reopen','retest' ] 36 } 37 return actions.get(ticket['status'], ['leave']) 38 39 def do_action(self, ticket, action, args): 40 if action == 'accept': 41 ticket['status'] = 'assigned' 42 ticket['owner'] = self.user 43 elif action == 'resolve': 44 ticket['status'] = 'resolved' 45 ticket['resolution'] = args.get('resolve_resolution') 46 ticket['owner'] = '' 47 elif action == 'verify': 48 ticket['status'] = 'verified' 49 ticket['owner'] = '' 50 elif action == 'close': 51 ticket['status'] = 'closed' 52 elif action == 'reassign': 53 newowner = args.get('reassign_owner') 54 if ticket['owner'] != newowner: 55 if ticket['status'] == 'assigned': ticket['status'] = 'new' 56 ticket['owner'] = newowner 57 elif action == 'reopen': 58 ticket['status'] = 'reopened' 59 ticket['resolution'] = '' 60 ticket['owner'] = '' 61 elif action == 'retest': 62 ticket['status'] = 'resolved' 63 ticket['owner'] = '' 64 65 def get_actions_template(self, ticket): 66 if ticket.has_key('id'): 67 return 'ticket_workflow_qarmt.cs' 68 else: 69 return None 70 71 def on_insert(self, ticket): 72 SimpleWorkflow.on_insert(self, ticket) 73 74 # The owner field defaults to the milestone owner if 75 # the component does not have any owner 76 cursor = self.db.cursor() 77 if ticket.get('owner', '') == '': 78 cursor.execute('SELECT owner FROM milestone ' 79 'WHERE name=%s', ticket.get('milestone', '')) 80 ticket['owner'] = cursor.fetchone()[0] or '' 81 82 def on_update(self, ticket): 83 SimpleWorkflow.on_update(self, ticket) 84 if not ticket._old: return # Not modified 85 86 cursor = self.db.cursor() 87 status = ticket.get('status', 'new') 88 component = ticket.get('component', '') 89 milestone = ticket.get('milestone', '') 90 91 # If the milestone is changed on a 'new' ticket then owner field 92 # is updated accordingly if the component does not have any owner. 93 # (related to #623). 94 if status == 'new' and ticket._old.has_key('milestone') and \ 95 not ticket._old.has_key('component') and \ 96 not ticket._old.has_key('owner'): 97 cursor.execute('SELECT owner FROM component ' 98 'WHERE name=%s', component) 99 if not cursor.fetchone()[0]: 100 cursor.execute('SELECT owner FROM milestone ' 101 'WHERE name=%s', ticket._old['milestone']) 102 old_owner = cursor.fetchone()[0] 103 if ticket['owner'] == old_owner: 104 cursor.execute('SELECT owner FROM milestone ' 105 'WHERE name=%s', milestone) 106 ticket['owner'] = cursor.fetchone()[0] or '' 107 108 # 1. The owner field defaults to the component owner for active tickets 109 if ticket.get('owner', '') == '' and status in ['new', 'reopened']: 110 cursor.execute('SELECT owner FROM component ' 111 'WHERE name=%s', component) 112 newowner = cursor.fetchone()[0] 113 if newowner: ticket['owner'] = newowner 114 115 # 2. The owner field defaults to component QA owner for testing tickets 116 if ticket.get('owner', '') == '' and status == 'resolved': 117 cursor.execute('SELECT qaowner FROM component ' 118 'WHERE name=%s', component) 119 newowner = cursor.fetchone()[0] 120 if newowner: ticket['owner'] = newowner 121 122 # 3. The owner field defaults to milestone owner for open tickets 123 if ticket.get('owner', '') == '' and status != 'closed': 124 cursor.execute('SELECT owner FROM milestone ' 125 'WHERE name=%s', milestone) 126 newowner = cursor.fetchone()[0] 127 if newowner: ticket['owner'] = newowner 128 129 # 4. The owner field defaults to reporter for verified tickets 130 if ticket.get('owner', '') == '' and status == 'verified': 131 reporter = ticket.get('reporter', '') 132 if reporter: ticket['owner'] = reporter -
trac/workflows/__init__.py
1 __all__ = ['Base', 'SimpleWorkflow', 'QaRmtWorkflow'] -
trac/workflows/SimpleWorkflow.py
1 # -*- coding: iso8859-1 -*- 2 # 3 # Copyright (C) 2003, 2004 Edgewall Software 4 # Copyright (C) 2003, 2004 Jonas Borgström <jonas@edgewall.com> 5 # 6 # Trac is free software; you can redistribute it and/or 7 # modify it under the terms of the GNU General Public License as 8 # published by the Free Software Foundation; either version 2 of the 9 # License, or (at your option) any later version. 10 # 11 # Trac is distributed in the hope that it will be useful, 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 # General Public License for more details. 15 # 16 # You should have received a copy of the GNU General Public License 17 # along with this program; if not, write to the Free Software 18 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 # 20 # Author: Pavel Kourochka <pkou@ua.fm> 21 # 22 # Simple workflow definition (as in Trac 0.8) 23 24 from trac.workflows.Base import WorkflowBase 25 26 class SimpleWorkflow(WorkflowBase): 27 28 def get_actions(self, ticket): 29 actions = { 30 'new': ['leave', 'resolve', 'reassign', 'accept'], 31 'assigned': ['leave', 'resolve', 'reassign' ], 32 'reopened': ['leave', 'resolve', 'reassign' ], 33 'closed': ['leave', 'reopen'] 34 } 35 return actions.get(ticket['status'], ['leave']) 36 37 def do_action(self, ticket, action, args): 38 if action == 'accept': 39 ticket['status'] = 'assigned' 40 ticket['owner'] = self.user 41 elif action == 'resolve': 42 ticket['status'] = 'closed' 43 ticket['resolution'] = args.get('resolve_resolution') 44 elif action == 'reassign': 45 ticket['owner'] = args.get('reassign_owner') 46 ticket['status'] = 'new' 47 elif action == 'reopen': 48 ticket['status'] = 'reopened' 49 ticket['resolution'] = '' 50 51 def get_actions_template(self, ticket): 52 if ticket.has_key('id'): 53 return 'ticket_workflow_simple.cs' 54 else: 55 return None 56 57 def init_template(self, ticket, hdf): 58 WorkflowBase.init_template(self, ticket, hdf) 59 if ticket.has_key('id'): 60 for a in self.get_actions(ticket): 61 hdf.setValue('ticket.workflow.action.' + a, '1') 62 63 def validate(self, ticket): 64 err = WorkflowBase.validate(self, ticket) 65 if not ticket.get('summary'): 66 err.append("The ticket must contain '''Summary''' field.") 67 return err 68 69 def on_insert(self, ticket): 70 WorkflowBase.on_insert(self, ticket) 71 72 # The owner field defaults to the component owner 73 cursor = self.db.cursor() 74 if ticket.get('owner', '') == '': 75 cursor.execute('SELECT owner FROM component ' 76 'WHERE name=%s', ticket.get('component', '')) 77 ticket['owner'] = cursor.fetchone()[0] or '' 78 79 def on_update(self, ticket): 80 WorkflowBase.on_update(self, ticket) 81 if not ticket._old: return # Not modified 82 83 # If the component is changed on a 'new' ticket then owner field 84 # is updated accordingly. (#623). 85 cursor = self.db.cursor() 86 if ticket['status'] == 'new' and ticket._old.has_key('component') and \ 87 not ticket._old.has_key('owner'): 88 cursor.execute('SELECT owner FROM component ' 89 'WHERE name=%s', ticket._old['component']) 90 old_owner = cursor.fetchone()[0] 91 if ticket['owner'] == old_owner: 92 cursor.execute('SELECT owner FROM component ' 93 'WHERE name=%s', ticket['component']) 94 ticket['owner'] = cursor.fetchone()[0] or '' -
trac/Roadmap.py
48 48 icalhref += '&show=all' 49 49 self.req.hdf.setValue('roadmap.href.list', 50 50 self.env.href.roadmap()) 51 query = "SELECT name, time, descr FROM milestone " \51 query = "SELECT name, time, descr, owner FROM milestone " \ 52 52 "WHERE name != '' " \ 53 53 "ORDER BY (IFNULL(time, 0) = 0) ASC, time ASC, name" 54 54 else: 55 55 self.req.hdf.setValue('roadmap.showall', '1') 56 56 self.req.hdf.setValue('roadmap.href.list', 57 57 self.env.href.roadmap('all')) 58 query = "SELECT name, time, descr FROM milestone " \58 query = "SELECT name, time, descr, owner FROM milestone " \ 59 59 "WHERE name != '' " \ 60 60 "AND (time IS NULL OR time = 0 OR time > %d) " \ 61 61 "ORDER BY (IFNULL(time, 0) = 0) ASC, time ASC, name" % time() … … 74 74 milestone = { 75 75 'name': row['name'], 76 76 'href': self.env.href.milestone(row['name']), 77 'owner': row['owner'] or '', 77 78 'time': row['time'] and int(row['time']) 78 79 } 79 80 descr = row['descr'] … … 113 114 status = ticket['status'] 114 115 if status == 'new' or status == 'reopened' and not ticket['owner']: 115 116 return 'NEEDS-ACTION' 116 elif status == 'assigned' or status == 'reopened':117 elif status != 'closed': 117 118 return 'IN-PROCESS' 118 119 elif status == 'closed': 119 120 if ticket['resolution'] == 'fixed': return 'COMPLETED' -
trac/upgrades/db8.py
1 sql = """ 2 -- Add statuses 'resolved' and 'verified' 3 UPDATE enum SET value = 6 WHERE type = 'status' AND name = 'closed'; 4 INSERT INTO enum (type, name, value) VALUES ('status', 'resolved', 4); 5 INSERT INTO enum (type, name, value) VALUES ('status', 'verified', 5); 6 7 -- Add QA Contact to 'component' 8 CREATE TEMPORARY TABLE component_backup AS SELECT * FROM component; 9 DROP TABLE component; 10 CREATE TABLE component ( 11 name text PRIMARY KEY, 12 owner text, 13 qaowner text 14 ); 15 INSERT INTO component SELECT name, owner, owner AS qaowner FROM component_backup; 16 DROP TABLE component_backup; 17 18 -- Add Release Manager Contact to 'milestone' 19 CREATE TEMPORARY TABLE milestone_backup AS SELECT * FROM milestone; 20 DROP TABLE milestone; 21 CREATE TABLE milestone ( 22 id integer PRIMARY KEY, 23 name text, 24 time integer, 25 owner text, 26 descr text, 27 UNIQUE(name) 28 ); 29 INSERT INTO milestone SELECT id, name, time, '' AS owner, descr FROM milestone_backup; 30 DROP TABLE milestone_backup; 31 32 -- Modify 'All Tickets by Version' report 33 UPDATE report SET sql = ' 34 SELECT p.value AS __color__, 35 (CASE WHEN IFNULL(version, '''') = '''' THEN ''Not Specified'' ELSE ''Version '' || version END) AS __group__, 36 id AS ticket, summary, component, milestone, severity, 37 (CASE status WHEN ''assigned'' THEN owner||'' *'' ELSE owner END) AS owner, 38 time AS created, 39 changetime AS _changetime, description AS _description, 40 reporter AS _reporter 41 FROM ticket t, enum p 42 WHERE status IN (''new'', ''assigned'', ''reopened'') 43 AND p.name = t.priority AND p.type = ''priority'' 44 ORDER BY (IFNULL(version, '''') = '''') DESC,version, p.value, severity, time 45 ' WHERE title = 'Active Tickets by Version'; 46 47 -- Modify 'All Tickets by Milestone' report 48 UPDATE report SET sql = ' 49 SELECT p.value AS __color__, 50 (CASE WHEN IFNULL(milestone, '''') = '''' THEN ''Not Assigned'' ELSE milestone||'' Release'' END) AS __group__, 51 id AS ticket, summary, component, version, severity, 52 (CASE status WHEN ''assigned'' THEN owner||'' *'' ELSE owner END) AS owner, 53 time AS created, 54 changetime AS _changetime, description AS _description, 55 reporter AS _reporter 56 FROM ticket t, enum p 57 WHERE status IN (''new'', ''assigned'', ''reopened'') 58 AND p.name = t.priority AND p.type = ''priority'' 59 ORDER BY (IFNULL(milestone, '''') = '''') DESC,milestone, p.value, severity, time 60 ', title = 'Active Tickets by Milestone' 61 WHERE title = 'All Tickets by Milestone'; 62 63 -- Modify 'Assigned, Active Tickets by Owner' report 64 UPDATE report SET sql = ' 65 SELECT p.value AS __color__, 66 (CASE WHEN IFNULL(owner, '''') = '''' THEN ''Not Assigned'' ELSE owner END) AS __group__, 67 id AS ticket, summary, component, version, milestone, severity, time AS created, 68 changetime AS _changetime, description AS _description, 69 reporter AS _reporter 70 FROM ticket t,enum p 71 WHERE status = ''assigned'' 72 AND p.name=t.priority AND p.type=''priority'' 73 ORDER BY (IFNULL(owner, '''') = '''') DESC, owner, p.value, severity, time 74 ' WHERE title = 'Assigned, Active Tickets by Owner'; 75 76 -- Modify 'Assigned, Active Tickets by Owner (Full Description)' report 77 UPDATE report SET sql = ' 78 SELECT p.value AS __color__, 79 owner AS __group__, 80 id AS ticket, summary, component, version, milestone, severity, time AS created, 81 description AS _description_, 82 changetime AS _changetime, reporter AS _reporter 83 FROM ticket t, enum p 84 WHERE status = ''assigned'' 85 AND p.name = t.priority AND p.type = ''priority'' 86 ORDER BY owner, p.value, severity, time 87 ' WHERE title = 'Assigned, Active Tickets by Owner (Full Description)'; 88 89 -- Modify 'All Tickets By Milestone (Including closed)' report 90 UPDATE report SET sql = ' 91 SELECT p.value AS __color__, 92 (CASE WHEN IFNULL(t.milestone, '''') = '''' THEN ''Not Assigned'' ELSE t.milestone || '' Release'' END) AS __group__, 93 (CASE status 94 WHEN ''closed'' THEN ''color: #777; background: #ddd; border-color: #ccc;'' 95 ELSE 96 (CASE owner WHEN ''$USER'' THEN ''font-weight: bold'' END) 97 END) AS __style__, 98 id AS ticket, summary, component, status, 99 resolution,version, severity, priority, owner, 100 changetime AS modified, 101 time AS _time,reporter AS _reporter 102 FROM ticket t,enum p 103 WHERE p.name=t.priority AND p.type=''priority'' 104 ORDER BY (IFNULL(milestone, '''') = '''') DESC, milestone DESC, (status = ''closed''), 105 (CASE status WHEN ''closed'' THEN modified ELSE -p.value END) DESC 106 ' WHERE title = 'All Tickets By Milestone (Including closed)'; 107 108 -- Modify 'My Tickets' report 109 UPDATE report SET sql = ' 110 SELECT p.value AS __color__, 111 (CASE status WHEN ''assigned'' THEN ''Assigned'' ELSE ''Owned'' END) AS __group__, 112 id AS ticket, summary, component, status, version, milestone, 113 severity, priority, time AS created, 114 changetime AS _changetime, description AS _description, 115 reporter AS _reporter 116 FROM ticket t, enum p 117 WHERE t.status <> ''closed'' 118 AND p.name = t.priority AND p.type = ''priority'' AND owner = ''$USER'' 119 ORDER BY (status = ''assigned'') DESC, p.value, milestone, severity, time 120 ' WHERE title = 'My Tickets'; 121 122 -- New reports 123 124 INSERT INTO report VALUES(NULL,NULL,'Open Tickets, Mine first',' 125 SELECT p.value AS __color__, 126 (CASE owner 127 WHEN ''$USER'' THEN ''My Tickets'' 128 ELSE ''Open Tickets'' 129 END) AS __group__, 130 id AS ticket, summary, component, status, version, milestone, severity, 131 (CASE status WHEN ''assigned'' THEN owner||'' *'' ELSE owner END) AS owner, 132 time AS created, 133 changetime AS _changetime, description AS _description, 134 reporter AS _reporter 135 FROM ticket t, enum p 136 WHERE status <> ''closed'' 137 AND p.name = t.priority AND p.type = ''priority'' 138 ORDER BY (owner = ''$USER'') DESC, p.value, milestone, severity, time 139 ',' 140 * List all not closed tickets by priority. 141 * Show all tickets owned by the logged in user in a group first. 142 '); 143 144 INSERT INTO report VALUES(NULL,NULL,'Open Tickets by Version',' 145 SELECT p.value AS __color__, 146 (CASE WHEN IFNULL(version, '''') = '''' THEN ''Not Specified'' ELSE ''Version '' || version END) AS __group__, 147 id AS ticket, summary, component, status, milestone, severity, 148 (CASE status WHEN ''assigned'' THEN owner||'' *'' ELSE owner END) AS owner, 149 time AS created, 150 changetime AS _changetime, description AS _description, 151 reporter AS _reporter 152 FROM ticket t, enum p 153 WHERE status <> ''closed'' 154 AND p.name = t.priority AND p.type = ''priority'' 155 ORDER BY (IFNULL(version, '''') = '''') desc,version, p.value, severity, time 156 ',' 157 * List all not closed tickets by priority. 158 * Group results by version. 159 '); 160 161 INSERT INTO report VALUES(NULL,NULL,'Open Tickets by Milestone',' 162 SELECT p.value AS __color__, 163 (CASE WHEN IFNULL(milestone, '''') = '''' THEN ''Not Assigned'' ELSE milestone||'' Release'' END) AS __group__, 164 id AS ticket, summary, component, status, version, severity, 165 (CASE status WHEN ''assigned'' THEN owner||'' *'' ELSE owner END) AS owner, 166 time AS created, 167 changetime AS _changetime, description AS _description, 168 reporter AS _reporter 169 FROM ticket t, enum p 170 WHERE status <> ''closed'' 171 AND p.name = t.priority AND p.type = ''priority'' 172 ORDER BY (IFNULL(milestone, '''') = '''') DESC,milestone, p.value, severity, time 173 ',' 174 * List all not closed tickets by priority. 175 * Group results by milestone. 176 '); 177 178 INSERT INTO report VALUES(NULL,NULL,'Open Tickets by Owner',' 179 SELECT p.value AS __color__, 180 (CASE WHEN IFNULL(owner, '''') = '''' THEN ''Not Assigned'' ELSE owner END) AS __group__, 181 id AS ticket, summary, component, status, version, milestone, severity, 182 time AS created, changetime AS _changetime, description AS _description, 183 reporter AS _reporter 184 FROM ticket t,enum p 185 WHERE status <> ''closed'' 186 AND p.name=t.priority AND p.type=''priority'' 187 ORDER BY (IFNULL(owner, '''') = '''') DESC, owner, p.value, severity, time 188 ',' 189 List not closed tickets, group by ticket owner, sorted by priority. 190 '); 191 192 INSERT INTO report VALUES(NULL,NULL,'Open Tickets by Status',' 193 SELECT p.value AS __color__, 194 status AS __group__, 195 id AS ticket, summary, component, version, milestone, severity, owner, 196 time AS created, 197 changetime AS _changetime, description AS _description, 198 reporter AS _reporter 199 FROM ticket t, enum q, enum p 200 WHERE status <> ''closed'' 201 AND q.name = t.status AND q.type = ''status'' 202 AND p.name = t.priority AND p.type = ''priority'' 203 ORDER BY q.value, p.value, severity, time 204 ',' 205 * List all not closed tickets by priority. 206 * Group results by status. 207 '); 208 209 INSERT INTO report VALUES(NULL,NULL,'Resolved Tickets, Mine first',' 210 SELECT p.value AS __color__, 211 (CASE owner 212 WHEN ''$USER'' THEN ''My Tickets'' 213 ELSE ''Active Tickets'' 214 END) AS __group__, 215 id AS ticket, summary, component, version, milestone, severity, 216 (CASE status WHEN ''assigned'' THEN owner||'' *'' ELSE owner END) AS owner, 217 time AS created, 218 changetime AS _changetime, description AS _description, 219 reporter AS _reporter 220 FROM ticket t, enum p 221 WHERE status = ''resolved'' 222 AND p.name = t.priority AND p.type = ''priority'' 223 ORDER BY (owner = ''$USER'') DESC, p.value, milestone, severity, time 224 ',' 225 * List all resolved tickets by priority. 226 * Show all tickets owned by the logged in user in a group first. 227 '); 228 229 INSERT INTO report VALUES(NULL,NULL,'Resolved Tickets by Milestone',' 230 SELECT p.value AS __color__, 231 (CASE WHEN IFNULL(milestone, '''') = '''' THEN ''Not Assigned'' ELSE milestone||'' Release'' END) AS __group__, 232 id AS ticket, summary, component, version, severity, 233 (CASE status WHEN ''assigned'' THEN owner||'' *'' ELSE owner END) AS owner, 234 time AS created, 235 changetime AS _changetime, description AS _description, 236 reporter AS _reporter 237 FROM ticket t, enum p 238 WHERE status = ''resolved'' 239 AND p.name = t.priority AND p.type = ''priority'' 240 ORDER BY (IFNULL(milestone, '''') = '''') DESC,milestone, p.value, severity, time 241 ',' 242 List resolved tickets, sorted by priority, grouped by milestone 243 '); 244 245 INSERT INTO report VALUES(NULL,NULL,'Resolved Tickets by Owner',' 246 SELECT p.value AS __color__, 247 (CASE WHEN IFNULL(owner, '''') = '''' THEN ''Not Assigned'' ELSE owner END) AS __group__, 248 id AS ticket, summary, component, version, milestone, severity, time AS created, 249 changetime AS _changetime, description AS _description, 250 reporter AS _reporter 251 FROM ticket t,enum p 252 WHERE status = ''resolved'' 253 AND p.name=t.priority AND p.type=''priority'' 254 ORDER BY (IFNULL(owner, '''') = '''') DESC, owner, p.value, severity, time 255 ',' 256 List resolved tickets, group by ticket owner, sorted by priority. 257 '); 258 259 INSERT INTO report VALUES(NULL,NULL,'Completed Tickets by Milestone (Full Description)',' 260 SELECT p.value AS __color__, 261 (CASE WHEN IFNULL(milestone, '''') = '''' THEN ''Not Assigned'' ELSE milestone||'' Release'' END) AS __group__, 262 id AS ticket, summary, component, status, version, severity, time AS created, 263 description AS _description_, 264 changetime AS _changetime, reporter AS _reporter 265 FROM ticket t, enum p 266 WHERE status IN (''verified'', ''closed'') 267 AND p.name = t.priority AND p.type = ''priority'' 268 ORDER BY (IFNULL(milestone, '''') = '''') DESC,milestone, p.value, severity, time 269 ',' 270 Release Notes: List verified and closed tickets, group by milestone, include description. 271 '); 272 """ 273 274 def do_upgrade(env, ver, cursor): 275 cursor.execute(sql) -
trac/upgrades/__init__.py
1 __all__ = ['db2', 'db3', 'db4', 'db5', 'db6', 'db7' ]1 __all__ = ['db2', 'db3', 'db4', 'db5', 'db6', 'db7', 'db8'] -
trac/Ticket.py
130 130 131 131 if not self._old and not comment: return # Not modified 132 132 133 # If the component is changed on a 'new' ticket then owner field134 # is updated accordingly. (#623).135 if self['status'] == 'new' and self._old.has_key('component') and \136 not self._old.has_key('owner'):137 cursor.execute('SELECT owner FROM component '138 'WHERE name=%s', self._old['component'])139 old_owner = cursor.fetchone()[0]140 if self['owner'] == old_owner:141 cursor.execute('SELECT owner FROM component '142 'WHERE name=%s', self['component'])143 self['owner'] = cursor.fetchone()[0]144 145 146 133 for name in self._old.keys(): 147 134 if name[:7] == 'custom_': 148 135 fname = name[7:] … … 264 251 i += 1 265 252 266 253 254 def get_workflow(env, db, user): 255 # from trac.workflows.Simple import SimpleWorkflow 256 # return SimpleWorkflow(env, db, user) 257 modulename = env.get_config('ticket', 'workflow', \ 258 'trac.workflows.SimpleWorkflow') 259 i = modulename.rfind('.') 260 if i == -1: 261 classname = modulename 262 else: 263 classname = modulename[i+1:] 264 265 module = __import__(modulename, globals(), locals(), [classname]) 266 constructor = getattr(module, classname) 267 workflow = constructor(env, db, user) 268 269 from workflows.Base import WorkflowBase 270 if not isinstance(workflow, WorkflowBase): 271 raise EnvironmentError, "Workflow class %s from %s must be " \ 272 "descendant of class WorkflowBase from " \ 273 "trac.workflows.base" \ 274 % (classname, modulename) 275 276 return workflow 277 278 267 279 class NewticketModule(Module): 268 280 template_name = 'newticket.cs' 269 281 270 def create_ticket(self): 271 if not self.args.get('summary'): 272 raise util.TracError('Tickets must contain Summary.') 273 274 ticket = Ticket() 275 ticket.populate(self.args) 282 def create_ticket(self, ticket, workflow): 276 283 ticket.setdefault('reporter',self.req.authname) 277 284 278 # The owner field defaults to the component owner 279 cursor = self.db.cursor() 280 if ticket.get('component') and ticket.get('owner', '') == '': 281 cursor.execute('SELECT owner FROM component ' 282 'WHERE name=%s', ticket['component']) 283 owner = cursor.fetchone()[0] 284 ticket['owner'] = owner 285 285 workflow.on_insert(ticket) 286 286 tktid = ticket.insert(self.db) 287 287 288 288 # Notify … … 294 294 def render (self): 295 295 self.perm.assert_permission(perm.TICKET_CREATE) 296 296 297 if self.args.has_key('create'): 298 self.create_ticket() 297 ticket = Ticket() 299 298 300 ticket = Ticket() 299 preview = self.args.has_key('preview') 300 do_create = self.args.has_key('create') 301 301 ticket.populate(self.args) 302 303 workflow = get_workflow(self.env, self.db, self.req.authname) 304 305 # Validate the ticket 306 err = [] 307 if preview or do_create: 308 err.extend(workflow.validate(ticket)) 309 if len(err) != 0: preview = 1 310 311 # Create the ticket if not in preview mode 312 if not preview and do_create: 313 workflow.do_action(ticket, 'create', self.args) 314 self.create_ticket(ticket, workflow) 315 302 316 ticket.setdefault('component', 303 317 self.env.get_config('ticket', 'default_component')) 304 318 ticket.setdefault('milestone', … … 320 334 evals = util.mydict(zip(ticket.keys(), 321 335 map(lambda x: util.escape(x), ticket.values()))) 322 336 util.add_to_hdf(evals, self.req.hdf, 'newticket') 337 if len(err) != 0: 338 self.req.hdf.setValue('newticket.workflow.error', 339 wiki_to_html(' * ' + '\n * '.join(err), 340 self.req.hdf, self.env, self.db)) 341 tpl = workflow.get_actions_template(ticket) 342 if tpl: 343 self.req.hdf.setValue('newticket.workflow.template', tpl) 344 workflow.init_template(ticket, self.req.hdf) 323 345 324 346 util.sql_to_hdf(self.db, 'SELECT name FROM component ORDER BY name', 325 347 self.req.hdf, 'newticket.components') … … 334 356 class TicketModule (Module): 335 357 template_name = 'ticket.cs' 336 358 337 def save_changes (self, id):359 def save_changes (self, ticket, workflow): 338 360 self.perm.assert_permission (perm.TICKET_MODIFY) 339 ticket = Ticket(self.db, id)340 361 341 if not self.args.get('summary'):342 raise util.TracError('Tickets must contain Summary.')343 344 362 if self.args.has_key('description'): 345 363 self.perm.assert_permission (perm.TICKET_ADMIN) 346 364 347 365 if self.args.has_key('reporter'): 348 366 self.perm.assert_permission (perm.TICKET_ADMIN) 349 367 350 # TODO: this should not be hard-coded like this351 action = self.args.get('action', None)352 if action == 'accept':353 ticket['status'] = 'assigned'354 ticket['owner'] = self.req.authname355 if action == 'resolve':356 ticket['status'] = 'closed'357 ticket['resolution'] = self.args.get('resolve_resolution')358 elif action == 'reassign':359 ticket['owner'] = self.args.get('reassign_owner')360 ticket['status'] = 'new'361 elif action == 'reopen':362 ticket['status'] = 'reopened'363 ticket['resolution'] = ''364 365 ticket.populate(self.args)366 367 368 now = int(time.time()) 368 369 370 workflow.on_update(ticket) 369 371 ticket.save_changes(self.db, 370 372 self.args.get('author', self.req.authname), 371 373 self.args.get('comment'), … … 373 375 374 376 tn = TicketNotifyEmail(self.env) 375 377 tn.notify(ticket, newticket=0, modtime=now) 376 self.req.redirect(self.env.href.ticket( id))378 self.req.redirect(self.env.href.ticket(ticket['id'])) 377 379 378 380 def insert_ticket_data(self, hdf, id, ticket, reporter_id): 379 381 """Insert ticket data into the hdf""" … … 431 433 def render (self): 432 434 self.perm.assert_permission (perm.TICKET_VIEW) 433 435 434 action = self.args.get('action', 'view')435 preview = self.args.has_key('preview')436 437 436 if not self.args.has_key('id'): 438 437 self.req.redirect(self.env.href.wiki()) 439 438 440 439 id = int(self.args.get('id')) 440 ticket = Ticket(self.db, id) 441 441 442 if not preview \ 443 and action in ['leave', 'accept', 'reopen', 'resolve', 'reassign']: 444 self.save_changes (id) 442 action = self.args.get('action', None) 443 preview = self.args.has_key('preview') 444 if action or preview: 445 ticket.populate(self.args) 445 446 446 ticket = Ticket(self.db, id) 447 workflow = get_workflow(self.env, self.db, self.req.authname) 448 449 # Validate ticket 450 err = [] 451 if action or preview: 452 actions = workflow.get_actions(ticket) 453 if action not in actions: 454 err.append("Invalid action '''%s''' is performed on the ticket. " \ 455 "Allowed actions are <''%s''>." % \ 456 (action, ', '.join(actions))) 457 err.extend(workflow.validate(ticket)) 458 if len(err) != 0: preview = 1 459 460 # Save changes if not in preview mode 461 if not preview and action: 462 workflow.do_action(ticket, action, self.args) 463 self.save_changes(ticket, workflow) 464 447 465 reporter_id = util.get_reporter_id(self.req) 448 466 449 467 if preview: 450 # Use user supplied values 451 for field in Ticket.std_fields: 452 if self.args.has_key(field) and field != 'reporter': 453 ticket[field] = self.args.get(field) 454 self.req.hdf.setValue('ticket.action', action) 468 if action: self.req.hdf.setValue('ticket.action', action) 455 469 reporter_id = self.args.get('author') 456 470 comment = self.args.get('comment') 457 471 if comment: … … 462 476 self.req.hdf, self.env, self.db)) 463 477 464 478 self.insert_ticket_data(self.req.hdf, id, ticket, reporter_id) 479 if len(err) != 0: 480 self.req.hdf.setValue('ticket.workflow.error', 481 wiki_to_html(' * ' + '\n * '.join(err), 482 self.req.hdf, self.env, self.db)) 483 tpl = workflow.get_actions_template(ticket) 484 if tpl: 485 self.req.hdf.setValue('ticket.workflow.template', tpl) 486 workflow.init_template(ticket, self.req.hdf) 465 487 466 488 cursor = self.db.cursor() 467 489 cursor.execute("SELECT max(id) FROM ticket") -
trac/WikiFormatter.py
125 125 elif row[1] == 'closed': 126 126 return '<a href="%s" title="CLOSED : %s"><del>#%d</del></a>' % (self._href.ticket(number), summary, number) 127 127 else: 128 return '<a href="%s" title="%s ">#%d</a>' % (self._href.ticket(number), summary, number)128 return '<a href="%s" title="%s : %s">#%d</a>' % (self._href.ticket(number), row[1].upper(), summary, number) 129 129 130 130 def _changesethref_formatter(self, match, fullmatch): 131 131 number = int(match[1:-1]) … … 158 158 elif row[1] == 'closed': 159 159 return self._href.ticket(args), '<del>%s:%s</del>' % (module, args), 0, 'CLOSED: ' + summary 160 160 else: 161 return self._href.ticket(args), '%s:%s' % (module, args), 0, summary161 return self._href.ticket(args), '%s:%s' % (module, args), 0, row[1].upper() + ': ' + summary 162 162 else: 163 163 return self._href.ticket(args), '%s:%s' % (module, args), 1, '' 164 164 elif module == 'wiki': -
templates/ticket_workflow_qarmt.cs
1 <?cs 2 if !ticket.action ?><?cs 3 set:ticket.action = 'leave' ?><?cs 4 /if ?><?cs 5 def action_radio(id) ?> 6 <input type="radio" id="<?cs var id ?>" name="action" value="<?cs var id ?>" 7 <?cs if $ticket.action == $id ?> checked="checked"<?cs /if ?> /><?cs 8 /def ?> 9 10 <?cs 11 if ticket.workflow.action.leave ?><?cs 12 call:action_radio('leave') ?> 13 <label for="leave">leave as <?cs var:ticket.status ?></label><br /><?cs 14 /if ?><?cs 15 if ticket.workflow.action.accept ?><?cs 16 call action_radio('accept') ?> 17 <label for="accept">accept ticket</label><br /><?cs 18 /if ?><?cs 19 if ticket.workflow.action.resolve ?><?cs 20 call:action_radio('resolve') ?> 21 <label for="resolve">resolve</label> 22 <label for="resolve_resolution">as:</label><?cs 23 call:hdf_select(enums.resolution, "resolve_resolution", 24 args.resolve_resolution) ?><br /><?cs 25 /if ?><?cs 26 if ticket.workflow.action.verify ?><?cs 27 call action_radio('verify') ?> 28 <label for="verify">verify ticket</label><br /><?cs 29 /if ?><?cs 30 if ticket.workflow.action.close ?><?cs 31 call action_radio('close') ?> 32 <label for="close">close ticket</label><br /><?cs 33 /if ?><?cs 34 if ticket.workflow.action.reopen ?><?cs 35 call:action_radio('reopen') ?> 36 <label for="reopen">reopen ticket</label><br /><?cs 37 /if ?><?cs 38 if ticket.workflow.action.retest ?><?cs 39 call:action_radio('retest') ?> 40 <label for="retest">retest ticket</label><br /><?cs 41 /if ?><?cs 42 if ticket.workflow.action.reassign ?><?cs 43 call:action_radio('reassign') ?> 44 <label for="reassign">reassign</label> 45 <label for="reassign_owner">to:</label> 46 <input type="text" id="reassign_owner" name="reassign_owner" size="40" 47 value=<?cs if args.reassign_to ?>"<?cs var:args.reassign_to ?>" 48 <?cs else ?>"<?cs var:trac.authname ?>" 49 <?cs /if ?> /><?cs 50 /if ?> 51 52 <?cs 53 if ticket.workflow.action.resolve || ticket.workflow.action.reassign ?> 54 <script type="text/javascript"><?cs 55 if ticket.workflow.action.resolve ?> 56 var resolve = document.getElementById("resolve");<?cs 57 /if ?><?cs 58 if ticket.workflow.action.reassign ?> 59 var reassign = document.getElementById("reassign");<?cs 60 /if ?> 61 var updateActionFields = function() {<?cs 62 if ticket.workflow.action.resolve ?> 63 enableControl('resolve_resolution', resolve.checked);<?cs 64 /if ?><?cs 65 if ticket.workflow.action.reassign ?> 66 enableControl('reassign_owner', reassign.checked);<?cs 67 /if ?> 68 }; 69 addEvent(window, 'load', updateActionFields);<?cs 70 if ticket.workflow.action.leave ?> 71 addEvent(document.getElementById("leave"), 'click', updateActionFields);<?cs 72 /if ?><?cs 73 if ticket.workflow.action.accept ?> 74 addEvent(document.getElementById("accept"), 'click', updateActionFields);<?cs 75 /if ?><?cs 76 if ticket.workflow.action.resolve ?> 77 addEvent(resolve, 'click', updateActionFields);<?cs 78 /if ?><?cs 79 if ticket.workflow.action.verify ?> 80 addEvent(document.getElementById("verify"), 'click', updateActionFields);<?cs 81 /if ?><?cs 82 if ticket.workflow.action.close ?> 83 addEvent(document.getElementById("close"), 'click', updateActionFields);<?cs 84 /if ?><?cs 85 if ticket.workflow.action.reopen ?> 86 addEvent(document.getElementById("reopen"), 'click', updateActionFields);<?cs 87 /if ?><?cs 88 if ticket.workflow.action.retest ?> 89 addEvent(document.getElementById("retest"), 'click', updateActionFields);<?cs 90 /if ?><?cs 91 if ticket.workflow.action.reassign ?> 92 addEvent(reassign, 'click', updateActionFields);<?cs 93 /if ?> 94 </script> 95 <?cs /if ?> -
templates/roadmap.cs
22 22 var:milestone.name ?></em></a></h2> 23 23 <p class="date"><?cs if:milestone.date ?> 24 24 <?cs var:milestone.date ?><?cs else ?>No date set<?cs /if ?> 25 <?cs if:milestone.owner ?> (<?cs var:milestone.owner ?>)<?cs /if ?> 25 26 </p> 26 27 <?cs with:stats = milestone.stats ?> 27 28 <?cs if:#stats.total_tickets > #0 ?> -
templates/ticket.cs
33 33 <div id="ticket"> 34 34 <div class="date"><?cs var:ticket.opened ?></div> 35 35 <h1>Ticket #<?cs var:ticket.id ?> <?cs 36 if:ticket. status == 'closed' ?>(Closed: <?cs var:ticket.resolution ?>)<?cs36 if:ticket.resolution ?>(<?cs var:ticket.status ?>: <?cs var:ticket.resolution ?>)<?cs 37 37 elif:ticket.status != 'new' ?>(<?cs var:ticket.status ?>)<?cs 38 38 /if ?></h1> 39 39 <h2><?cs var:ticket.summary ?></h2> … … 208 208 </div><?cs /if ?> 209 209 </fieldset> 210 210 211 <fieldset id="action"> 212 <legend>Action</legend><?cs 213 if:!ticket.action ?><?cs set:ticket.action = 'leave' ?><?cs 214 /if ?><?cs 215 def:action_radio(id) ?> 216 <input type="radio" id="<?cs var:id ?>" name="action" value="<?cs 217 var:id ?>"<?cs if:$ticket.action == $id ?> checked="checked"<?cs 218 /if ?> /><?cs 219 /def ?> 220 <?cs call:action_radio('leave') ?> 221 <label for="leave">leave as <?cs var:ticket.status ?></label><br /><?cs 222 if $ticket.status == "new" ?> 223 <?cs call:action_radio('accept') ?> 224 <label for="accept">accept ticket</label><br /><?cs 225 /if ?><?cs 226 if $ticket.status == "closed" ?> 227 <?cs call:action_radio('reopen') ?> 228 <label for="reopen">reopen ticket</label><br /><?cs 229 /if ?><?cs 230 if $ticket.status == "new" || $ticket.status == "assigned" || $ticket.status == "reopened" ?> 231 <?cs call:action_radio('resolve') ?> 232 <label for="resolve">resolve</label> 233 <label for="resolve_resolution">as:</label> 234 <?cs call:hdf_select(enums.resolution, "resolve_resolution", args.resolve_resolution) ?><br /> 235 <?cs call:action_radio('reassign') ?> 236 <label for="reassign">reassign</label> 237 <label for="reassign_owner">to:</label> 238 <input type="text" id="reassign_owner" name="reassign_owner" size="40" value="<?cs 239 if:args.reassign_to ?><?cs var:args.reassign_to ?><?cs 240 else ?><?cs var:trac.authname ?><?cs /if ?>" /><?cs 241 /if ?><?cs 242 if $ticket.status == "new" || $ticket.status == "assigned" || $ticket.status == "reopened" ?> 243 <script type="text/javascript"> 244 var resolve = document.getElementById("resolve"); 245 var reassign = document.getElementById("reassign"); 246 var updateActionFields = function() { 247 enableControl('resolve_resolution', resolve.checked); 248 enableControl('reassign_owner', reassign.checked); 249 }; 250 addEvent(window, 'load', updateActionFields); 251 addEvent(document.getElementById("leave"), 'click', updateActionFields);<?cs 252 if $ticket.status == "new" ?> 253 addEvent(document.getElementById("accept"), 'click', updateActionFields);<?cs 254 /if ?> 255 addEvent(resolve, 'click', updateActionFields); 256 addEvent(reassign, 'click', updateActionFields); 257 </script><?cs 258 /if ?> 259 </fieldset> 211 <?cs if ticket.workflow.template ?> 212 <fieldset id="action"> 213 <legend>Action</legend> 214 <?cs include ticket.workflow.template ?> 215 </fieldset> 216 <?cs /if ?> 260 217 218 <?cs if ticket.workflow.error ?> 219 <div class="system-message"> 220 <h2>Ticket Error</h2> 221 <p class="message"><?cs var ticket.workflow.error ?></p> 222 <strong>The ticket will not be saved.</strong> 223 </div> 224 <?cs /if ?> 225 261 226 <div class="buttons"> 262 227 <input type="reset" value="Reset" /> 263 228 <input type="submit" name="preview" value="Preview" /> -
templates/ticket_workflow_simple.cs
1 <?cs 2 if !ticket.action ?><?cs 3 set:ticket.action = 'leave' ?><?cs 4 /if ?><?cs 5 def action_radio(id) ?> 6 <input type="radio" id="<?cs var id ?>" name="action" value="<?cs var id ?>" 7 <?cs if $ticket.action == $id ?> checked="checked"<?cs /if ?> /><?cs 8 /def ?> 9 10 <?cs 11 if ticket.workflow.action.leave ?><?cs 12 call:action_radio('leave') ?> 13 <label for="leave">leave as <?cs var:ticket.status ?></label><br /><?cs 14 /if ?><?cs 15 if ticket.workflow.action.accept ?><?cs 16 call action_radio('accept') ?> 17 <label for="accept">accept ticket</label><br /><?cs 18 /if ?><?cs 19 if ticket.workflow.action.resolve ?><?cs 20 call:action_radio('resolve') ?> 21 <label for="resolve">resolve</label> 22 <label for="resolve_resolution">as:</label><?cs 23 call:hdf_select(enums.resolution, "resolve_resolution", 24 args.resolve_resolution) ?><br /><?cs 25 /if ?><?cs 26 if ticket.workflow.action.reopen ?><?cs 27 call:action_radio('reopen') ?> 28 <label for="reopen">reopen ticket</label><br /><?cs 29 /if ?><?cs 30 if ticket.workflow.action.reassign ?><?cs 31 call:action_radio('reassign') ?> 32 <label for="reassign">reassign</label> 33 <label for="reassign_owner">to:</label> 34 <input type="text" id="reassign_owner" name="reassign_owner" size="40" 35 value=<?cs if args.reassign_to ?>"<?cs var:args.reassign_to ?>" 36 <?cs else ?>"<?cs var:trac.authname ?>" 37 <?cs /if ?> /><?cs 38 /if ?> 39 40 <?cs 41 if ticket.workflow.action.resolve || ticket.workflow.action.reassign ?> 42 <script type="text/javascript"><?cs 43 if ticket.workflow.action.resolve ?> 44 var resolve = document.getElementById("resolve");<?cs 45 /if ?><?cs 46 if ticket.workflow.action.reassign ?> 47 var reassign = document.getElementById("reassign");<?cs 48 /if ?> 49 var updateActionFields = function() {<?cs 50 if ticket.workflow.action.resolve ?> 51 enableControl('resolve_resolution', resolve.checked);<?cs 52 /if ?><?cs 53 if ticket.workflow.action.reassign ?> 54 enableControl('reassign_owner', reassign.checked);<?cs 55 /if ?> 56 }; 57 addEvent(window, 'load', updateActionFields);<?cs 58 if ticket.workflow.action.leave ?> 59 addEvent(document.getElementById("leave"), 'click', updateActionFields);<?cs 60 /if ?><?cs 61 if ticket.workflow.action.accept ?> 62 addEvent(document.getElementById("accept"), 'click', updateActionFields);<?cs 63 /if ?><?cs 64 if ticket.workflow.action.resolve ?> 65 addEvent(resolve, 'click', updateActionFields);<?cs 66 /if ?><?cs 67 if ticket.workflow.action.reopen ?> 68 addEvent(document.getElementById("reopen"), 'click', updateActionFields);<?cs 69 /if ?><?cs 70 if ticket.workflow.action.reassign ?> 71 addEvent(reassign, 'click', updateActionFields);<?cs 72 /if ?> 73 </script> 74 <?cs /if ?> -
templates/timeline_rss.cs
43 43 $item.href, $item.msg_escwiki) 44 44 ?><?cs elif:item.type == #3 45 45 ?><!-- Closed ticket --> <?cs call:rss_item('Ticket', 46 'Ticket #'+$item.idata+' resolved: '+$item.shortmsg,46 'Ticket #'+$item.idata+' closed: '+$item.shortmsg, 47 47 $item.href, $item.msg_escwiki) 48 48 ?><?cs elif:item.type == #4 49 49 ?><!-- Reopened ticket --><?cs call:rss_item('Ticket', 50 50 '#'+$item.idata+' reopened: '+$item.shortmsg, 51 51 $item.href, $item.msg_escwiki) 52 ?><?cs elif:item.type == #7 53 ?><!-- Verified ticket --><?cs call:rss_item('Ticket', 54 '#'+$item.idata+' verified: '+$item.shortmsg, 55 $item.href, $item.msg_escwiki) 56 ?><?cs elif:item.type == #8 57 ?><!-- Resolved ticket --> <?cs call:rss_item('Ticket', 58 'Ticket #'+$item.idata+' resolved: '+$item.shortmsg, 59 $item.href, $item.msg_escwiki) 60 ?><?cs elif:item.type == #9 61 ?><!-- Retested ticket --><?cs call:rss_item('Ticket', 62 '#'+$item.idata+' retested: '+$item.shortmsg, 63 $item.href, $item.msg_escwiki) 52 64 ?><?cs elif:item.type == #5 53 65 ?><!-- Wiki change --><?cs call:rss_item('Wiki', 54 66 $item.tdata+" page edited.", … … 62 74 <?cs /if ?> 63 75 <?cs /each ?> 64 76 </channel> 65 </rss> 66 No newline at end of file 77 </rss> -
templates/newticket.cs
69 69 </div><?cs /if ?> 70 70 </fieldset> 71 71 72 <?cs if newticket.workflow.template ?> 73 <fieldset id="action"> 74 <legend>Action</legend> 75 <?cs include newticket.workflow.template ?> 76 </fieldset> 77 <?cs /if ?> 78 79 <?cs if newticket.workflow.error ?> 80 <div class="system-message"> 81 <h2>Ticket Error</h2> 82 <p class="message"><?cs var newticket.workflow.error ?></p> 83 <strong>The ticket will not be created.</strong> 84 </div> 85 <?cs /if ?> 86 72 87 <div class="buttons"> 73 <input type="submit" value="Preview" /> 88 <input type="submit" name="preview" value="Preview" /> 74 89 <input type="submit" name="create" value="Submit ticket" /> 75 90 </div> 76 91 </form> -
templates/milestone.cs
56 56 var:milestone.name ?>" /> 57 57 </div> 58 58 <div class="field"> 59 <label for="owner">Owner of the milestone (Release Manager):</label><br /> 60 <input type="text" id="owner" name="owner" size="32" value="<?cs 61 var:milestone.owner ?>" /> 62 </div> 63 <div class="field"> 59 64 <label for="datemode">Completion date:</label><br /> 60 65 <select name="datemode" id="datemode" 61 66 onchange="enableControl('date',this.value=='manual'); … … 108 113 <?cs else ?> 109 114 <em class="date"><?cs if:milestone.date ?> 110 115 <?cs var:milestone.date ?><?cs else ?>No date set<?cs /if ?> 116 <?cs if:milestone.owner ?> (<?cs var:milestone.owner ?>)<?cs /if ?> 111 117 </em> 112 118 <div class="descr"><?cs var:milestone.descr ?></div> 113 119 <?cs /if ?> … … 120 126 <thead><tr> 121 127 <th class="name" rowspan="2"><?cs var:milestone.stats.grouped_by ?></th> 122 128 <th class="tickets" scope="col" colspan="2">Tickets</th> 123 <th class="progress" rowspan="2">Percent Resolved</th>129 <th class="progress" rowspan="2">Percent Completed</th> 124 130 </tr><tr> 125 131 <th class="open" scope="col">Active</th> 126 132 <th class="closed" scope="col">Closed</th> -
templates/timeline.cs
60 60 61 61 <?cs each:item = timeline.items ?> 62 62 <?cs call:day_separator(item.date) ?> 63 <?cs if:item.tdata && item.message ?> 64 <?cs set:ticketmsg = $item.tdata + ' - ' + $item.message ?> 65 <?cs elif:item.tdata ?> 66 <?cs set:ticketmsg = $item.tdata ?> 67 <?cs else ?> 68 <?cs set:ticketmsg = $item.message ?> 69 <?cs /if ?> 63 70 <?cs if:item.type == #1 ?><!-- Changeset --> 64 71 <?cs call:tlitem(item.href, 'changeset', 65 72 'Changeset <em>['+$item.idata+']</em> by '+$item.author,$item.node_list+item.message) ?> … … 67 74 <?cs call:tlitem(item.href, 'newticket', 68 75 'Ticket <em>#'+$item.idata+'</em> created by '+$item.author, item.message) ?> 69 76 <?cs elif:item.type == #3 ?><!-- Closed ticket --> 70 <?cs if:item.message ?>71 <?cs set:imessage = ' - ' + $item.message ?>72 <?cs else ?>73 <?cs set:imessage = '' ?>74 <?cs /if ?>75 77 <?cs call:tlitem(item.href, 'closedticket', 76 'Ticket <em>#'+$item.idata+'</em> resolved by '+$item.author, 77 $item.tdata+$imessage) ?> 78 'Ticket <em>#'+$item.idata+'</em> closed by '+$item.author, $ticketmsg) ?> 78 79 <?cs elif:item.type == #4 ?><!-- Reopened ticket --> 79 <?cs call:tlitem(item.href, 'newticket', 80 'Ticket <em>#'+$item.idata+'</em> reopened by '+$item.author, '') ?> 80 <?cs call:tlitem(item.href, 'reopenedticket', 81 'Ticket <em>#'+$item.idata+'</em> reopened by '+$item.author, item.message) ?> 82 <?cs elif:item.type == #7 ?><!-- Verified ticket --> 83 <?cs call:tlitem(item.href, 'closedticket', 84 'Ticket <em>#'+$item.idata+'</em> verified by '+$item.author, $ticketmsg) ?> 85 <?cs elif:item.type == #8 ?><!-- Resolved ticket --> 86 <?cs call:tlitem(item.href, 'resolvedticket', 87 'Ticket <em>#'+$item.idata+'</em> resolved by '+$item.author, $ticketmsg) ?> 88 <?cs elif:item.type == #9 ?><!-- Retested ticket --> 89 <?cs call:tlitem(item.href, 'reopenedticket', 90 'Ticket <em>#'+$item.idata+'</em> retested by '+$item.author, item.message) ?> 81 91 <?cs elif:item.type == #5 ?><!-- Wiki change --> 82 92 <?cs call:tlitem(item.href, 'wiki', 83 93 '<em>'+$item.tdata+'</em> edited by '+$item.author, item.message) ?>
