#4686 closed enhancement (fixed)
Ticket duplication using Trac
Reported by: | Owned by: | Christian Boos | |
---|---|---|---|
Priority: | normal | Milestone: | 0.11 |
Component: | ticket system | Version: | |
Severity: | normal | Keywords: | copy ticketclone |
Cc: | Branch: | ||
Release Notes: | |||
API Changes: | |||
Internal Changes: |
Description (last modified by )
It should be possible to create a new ticket by duplicating an existing ticket.
Use Cases
(from #th1214)
We just migrated to Trac from Bugzilla. The only feature we miss is the ability to clone a ticket into the new ticket fields. It would be great to have the Clone a Trac Ticket functionality.
(original request)
I'm hoping this has been done before and I'm just unable
to find it. I have a collection of HW which assigns tasks to multiple teams when it arrives. To help manage this data
I want to use Trac tasks. I have a GUI front end which solicits for all the data required in creating a task. It also solicits which teams are impacted. I want to create
as many issues as there are teams impacted with the components of each driving the owner.
I then want to be able to use the front end to manage
status on each of the opened tasks.
So tickets 45, 46, 47 might all have the same data but have different components
where Teams A, B, and C all have very different assignments.
I don't wish to reinvent the wheel. Is something similar to this already done?
tracking the status of an issue in different release lines
When there's a regression for a bug, instead of reopening the ticket (which will loose the information that this bug has been effectively fixed for the milestone indicated), one could duplicate it and schedule it for a given milestone on the other release line, see #4298.
creating ticket templates
One could have a wiki page with links to a few "typical" tickets that could be used as a templates for creating new tickets. Such tickets could have among other things prefilled descriptions, see #4044.
Attachments (1)
Change History (32)
comment:1 by , 18 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
comment:2 by , 18 years ago
(this proposal sounded a bit like the "clone ticket" functionality … not sure there's already a ticket opened for that though)
comment:3 by , 18 years ago
Resolution: | wontfix |
---|---|
Status: | closed → reopened |
This is essentially cloning an existing ticket. Not an easy way to do this from my perspective. Have been trying to either use the macros to facilitate or to use eggs. Neither has been fruitful to date. What is the timeline for having clone feature. I found a clone defect that was a year old.
comment:4 by , 18 years ago
Keywords: | copy clone added |
---|---|
Milestone: | → 1.0 |
Summary: | Front-end display and duplication using Trac → Ticket duplication using Trac |
What is the timeline for having clone feature. I found a clone defect that was a year old.
I was looking for a duplicate of this request but didn't find it… care to give the ticket number?
I agree that a Clone Ticket functionality can be useful in some scenarios, like one way to deal with the single issue, multiple releases problem (see #4298), or creating ticket templates (see #4044).
comment:5 by , 18 years ago
I have written by own version and I'll post those changes here shortly. Up to you if you'd like to use this to close the other clone issue.
comment:7 by , 18 years ago
Replying to ThurnerRupert <rupert.thurner@gmail.com>:
closed the other one as inferior proposal.
FYI: There is still another clone request th:#1214 out there that is different enough, imho, from this ticket.
follow-up: 9 comment:8 by , 18 years ago
Description: | modified (diff) |
---|
#Th1214 you meant ;-)
Well, I agree that the original description was not explicitly targeted at ticket duplication, it's only because of comment:2 and comment:3 that this ticket has been focused on the ticket cloning topic. I'll cleanup the description to reflect that, as otherwise I think that #Th1214 should be implemented in the base ticket system, for the reasons mentioned in comment:4.
comment:9 by , 18 years ago
Replying to cboos:
#Th1214 you meant ;-)
Well, I agree that the original description was not explicitly targeted at ticket duplication, it's only because of comment:2 and comment:3 that this ticket has been focused on the ticket cloning topic. I'll cleanup the description to reflect that, as otherwise I think that #Th1214 should be implemented in the base ticket system, for the reasons mentioned in comment:4.
yep. I goofed up. 1214 is on Trac-hacks. Thanks for the correction! I'll be more careful about that.
comment:10 by , 18 years ago
I forgot about this work.
I made two changes to allow a version of cloning The first was in the style sheet.
/usr/share/trac/template/ticket.cs <div class="buttons"> <input type="hidden" name="ts" value="<?cs var:ticket.ts ?>" /> <input type="hidden" name="replyto" value="<?cs var:ticket.replyto ?>" /> <input type="hidden" name="cnum" value="<?cs var:ticket.cnum ?>" /> <input type="submit" name="preview" value="Preview" accesskey="r" /> <input type="submit" value="Submit changes" /> <p> <input type="submit" name="clone" value="Clone" /> </div> Only 2 new lines in the above: 335,336d333 < <p> < <input type="submit" name="clone" value="Clone" />
The second change was to
/usr/lib/python2-3/site-packages/trac/ticket/web_ui.py
where I made a copy new ticket in a clone request
def clone_request(self, req, db): req.perm.assert_permission('TICKET_CREATE') db = self.env.get_db_cnx() if req.method == 'POST' and 'owner' in req.args and \ not req.perm.has_permission('TICKET_MODIFY'): del req.args['owner'] if not req.args.get('summary'): raise TracError('Tickets must contain a summary.') ticket = Ticket(self.env, db=db) ticket.populate(req.args) ticket.values['reporter'] = get_reporter_id(req, 'reporter') ticket['status'] = 'new' self._validate_ticket(req, ticket) ticket.insert(db=db) db.commit() # Notify try: tn = TicketNotifyEmail(self.env) tn.notify(ticket, newticket=True) except Exception, e: self.log.exception("Failure sending notification on creation of " "ticket #%s: %s" % (ticket.id, e)) # Redirect the user to the newly created ticket if req.args.get('attachment'): req.redirect(req.href.attachment('ticket', ticket.id, action='new')) else: req.redirect(req.href.ticket(ticket.id)) ticket = Ticket(self.env, db=db) ticket.populate(req.args) ticket.values['reporter'] = get_reporter_id(req, 'reporter') if ticket.values.has_key('description'): description = wiki_to_html(ticket['description'], self.env, req, db) req.hdf['newticket.description_preview'] = description req.hdf['title'] = 'New Ticket' req.hdf['newticket'] = ticket.values field_names = [field['name'] for field in ticket.fields if not field.get('custom')] if 'owner' in field_names: curr_idx = field_names.index('owner') if 'cc' in field_names: insert_idx = field_names.index('cc') else: insert_idx = len(field_names) if curr_idx < insert_idx: ticket.fields.insert(insert_idx, ticket.fields[curr_idx]) del ticket.fields[curr_idx] for field in ticket.fields: name = field['name'] del field['name'] if name in ('summary', 'reporter', 'description', 'type', 'status', 'resolution'): field['skip'] = True elif name == 'owner': field['label'] = 'Assign to' if not req.perm.has_permission('TICKET_MODIFY'): field['skip'] = True elif name == 'milestone': # Don't make completed milestones available for selection options = field['options'][:] for option in field['options']: milestone = Milestone(self.env, option, db=db) if milestone.is_completed: options.remove(option) field['options'] = options req.hdf['newticket.fields.' + name] = field if req.perm.has_permission('TICKET_APPEND'): req.hdf['newticket.can_attach'] = True req.hdf['newticket.attachment'] = req.args.get('attachment') add_stylesheet(req, 'common/css/ticket.css') return 'newticket.cs', None then later in the file defined the call to the above method as elif req.args.has_key('clone'): self.clone_request(req, db) # Use user supplied values ticket.populate(req.args) req.hdf['ticket.action'] = action req.hdf['ticket.ts'] = req.args.get('ts') req.hdf['ticket.reassign_owner'] = req.args.get('reassign_owner') \ or req.authname req.hdf['ticket.resolve_resolution'] = req.args.get('resolve_resolution') comment = req.args.get('comment') if comment: req.hdf['ticket.comment'] = comment # Wiki format a preview of comment req.hdf['ticket.comment_preview'] = wiki_to_html( comment, self.env, req, db) self._do_save(req, db, ticket)
I'm sure there are better ways to take advantage of Plugins but this was the fastest way for me to get this done.
comment:11 by , 18 years ago
Owner: | changed from | to
---|---|
Status: | reopened → new |
I'm sure there are better ways to take advantage of Plugins but this was the fastest way for me to get this done.
You should preferably produce a patch for this change, that way others can easily take benefit from your work (do a svn checkout
of the SubversionRepository, make you changes there, then at the top-level of the checkout, do svn diff > ticket_cloning_for_trac-0.10.patch
).
For 0.11, I think we can come up with a simpler solution, I'll try to post one for comments a bit later on.
comment:12 by , 18 years ago
Just thought it was worth mentioning that the Datamover plugin can copy tickets both between envs and within the same env.
comment:13 by , 18 years ago
Milestone: | 1.0 → 0.11 |
---|---|
Resolution: | → fixed |
Status: | new → closed |
Implemented in r5457.
comment:14 by , 18 years ago
Resolution: | fixed |
---|---|
Status: | closed → reopened |
could you pls make this available to any user, not only admin? for trying to use this as "ticket template" (see #4044) it is essential.
allow reopen pls …
comment:15 by , 18 years ago
Ah, you're right. Then perhaps we could make use of a new permission here, or a configuration setting.
follow-up: 20 comment:16 by , 18 years ago
A TICKET_CLONE permission seems the most appropriate thing, then depending on the expected usage, the trac admin can grant that permission to anonymous, authenticated, or any other combination.
There's also some discussion going on about the placement of this "Clone" button. Some options are:
- leave it like it is, in the ticket box
- move it alongside with the other "actions" (which IMO should better be kept focused on the workflow related changes)
- move it at the bottom of the page, next to the "Preview" and "Submit" ones, at the right side of the screen
I'd be interested to get feedback from future users of this feature.
by , 18 years ago
Attachment: | clone_as_action.png added |
---|
Yet another possibility, the "clone" as an action distinct from the ones modifying the ticket itself
follow-up: 19 comment:17 by , 18 years ago
coderanger prototyped the attachment:clone_as_action.png alternative, which also has implications in the ITicketActionController API that would essentially allow to integrate those clone and delete operations in the upcoming bulk editor (#525).
comment:18 by , 18 years ago
ad ticket_clone permission: please not
i'm wondering what the gain would be. either you are allowed to create a new ticket or not, no matter where you get it from. and you are allowed to view a ticket or not. if you have both you are able to clone. but its very well possible i'm overlooking something. i'd prefer if trac could stay as slim as possible = asap :)
position of clone
i like the position where it currently is, beside the reply, as it is on top and saves us from scrolling down. even the delete should go, a very good idea of coderanger. but i would not mind it on the bottom additionally if somebody insists all the actions should stay there.
what we really miss on the bottom is the "next - previous" link, as we often have queries, edit one ticket, go to next, edit, go to next, edit … and so on. currently this is a scrolling exercise.
or, what i personally find even more attractive, turn the order upside down, as it is with roundup, see http://www.selenic.com/mercurial/bts/issue552. this would leave all the links, buttons, editable fields in front of your nose, just the "old" things down.
but what i find counter-intuitive on the png (clone as action) is the two clicks you are forcing, as only one is necessary. you do not change and clone or change and delete at the same time, and then applying it. so i guess its against good ui design principles.
usage, positioning of link —> avoid scrolling and clicking
we plan to create some open tickets with contents (e.g. headlines, prio, type, etc filled out), mark it somehow (maybe keyword) to present it in a query/list. how we get this list behind the "new" i'm not sure yet - but maybe having a page with the link would be sufficient. or how we could get a clone icon in every line of the list …
comment:19 by , 18 years ago
Replying to cboos:
coderanger prototyped the attachment:clone_as_action.png alternative, which also has implications in the ITicketActionController API that would essentially allow to integrate those clone and delete operations in the upcoming bulk editor (#525).
I'm really not a big fan of seeing Trac UI becoming a little bit more like too many other bug tracking tools that exhibit far too many fields and buttons. I initially chose Trac because of its clean and lean UI, and I hope it will stay simple.
Why not keeping the current style (as with the th:wiki:TicketDeletePlugin), that would be "Reply Delete" in the yellow box?
Having a ticket UI that involves scrolling to reach the numerous fields does not sound like user friendly… Keep in mind something essential: the more buttons and fields are shown, the less the people who want to fill in a bug.
Features that are rarely used (such as deleting a ticket) should not clutter the whole UI, even for the admin accounts.
follow-ups: 21 31 comment:20 by , 18 years ago
Replying to cboos:
A TICKET_CLONE permission seems the most appropriate thing, then depending on the expected usage, the trac admin can grant that permission to anonymous, authenticated, or any other combination.
Agreed. In my case, we have people who want the clone functionality who aren't ticket admins.
follow-up: 22 comment:21 by , 18 years ago
Replying to ecarter:
Replying to cboos:
A TICKET_CLONE permission seems the most appropriate thing, then depending on the expected usage, the trac admin can grant that permission to anonymous, authenticated, or any other combination.
Agreed. In my case, we have people who want the clone functionality who aren't ticket admins.
would it not be sufficient to be allowed to have ticket create? i.e. no additional right necessary? for displaying the ticket itself, ticket read of course is necessary.
follow-up: 23 comment:22 by , 18 years ago
Replying to ThurnerRupert:
would it not be sufficient to be allowed to have ticket create? i.e. no additional right necessary? for displaying the ticket itself, ticket read of course is necessary.
Well, yes… and no.
On the one hand, ticket cloning is just creating a ticket. On the otherhand, it's a fast way to create a ticket. For internal systems, that's not a problem, but for public-facing sites, that could become a nuisance. But, adding TICKET_CLONE
does increase the complexity of the system. Hmm… and you can already pre-fill fields via the url when you just have ticket create… so… maybe TICKET_CREATE
should be all we check. I'm undecided.
comment:23 by , 18 years ago
Replying to ecarter:
Replying to ThurnerRupert:
would it not be sufficient to be allowed to have ticket create? i.e. no additional right necessary? for displaying the ticket itself, ticket read of course is necessary.
… I'm undecided.
Yes, I think it's a matter of local policy, and if there must be a "one size fits all", then we'd rather go in the direction pointed out by eblot: "clean and lean UI, … hope it will stay simple."
That's admittedly not an easy goal to fulfill when you're adding features, but we should strive to it ;-)
Introducing a TICKET_CLONE permission is somewhat abusing the permission system in order to be able to adapt the UI to the expected "role" of the user. It's probably not the "best" way to do it, but the more flexible given the tools at hand. Maybe a special naming of the permission would help here, showing that it's more a capability than a permission? (e.g. ticket_clone_control
)
comment:24 by , 18 years ago
Milestone: | 0.11.1 → 0.11 |
---|---|
Resolution: | → fixed |
Status: | reopened → closed |
Ok, for now we're already checking for TICKET_CREATE, so I think the "ticket duplication" can be considered to be implemented.
This doesn't mean it can't be improved upon in the next releases:
- for the presentation point of view (though there seems to be more people liking the current way than the alternatives)
- regarding (ab)using the permission system as a way to configure the UI (e.g. use something like TICKET_clone_operation - can't be all lower case as suggested in comment:23)
comment:25 by , 17 years ago
Resolution: | fixed |
---|---|
Status: | closed → reopened |
As discussed on trac-dev, I'll try to make a ITemplateStreamFilter sample plugin out of this.
comment:26 by , 17 years ago
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
With r6153, this feature is now available as a single file plugin. Install by copying source:trunk/sample-plugins/ticket_clone.py in your <env>/plugins folder.
comment:27 by , 16 years ago
Type: | enhancement → defect |
---|
comment:28 by , 16 years ago
Type: | defect → enhancement |
---|
comment:29 by , 13 years ago
Keywords: | ticketclone added; clone removed |
---|
comment:30 by , 12 years ago
For reference, the ticket clone feature is now an optional component which can be found in source:tags/trac-1.0/tracopt/ticket/clone.py
comment:31 by , 11 years ago
Replying to ecarter:
Replying to cboos:
A TICKET_CLONE permission seems the most appropriate thing, then depending on the expected usage, the trac admin can grant that permission to anonymous, authenticated, or any other combination.
Agreed. In my case, we have people who want the clone functionality who aren't ticket admins.
Another ticket has been raised for this issue, #10948.
As the author I wish to cancel.