Author: dammina
Date: Tue Jul 29 20:49:38 2014
New Revision: 1614483
URL: http://svn.apache.org/r1614483
Log:
The new functionality provides the users the freedom to change the number of
tickets at any moment.
Modified:
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/htdocs/js/batchcreate.js
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/theme.py
Modified:
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/htdocs/js/batchcreate.js
URL:
http://svn.apache.org/viewvc/bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/htdocs/js/batchcreate.js?rev=1614483&r1=1614482&r2=1614483&view=diff
==============================================================================
---
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/htdocs/js/batchcreate.js
(original)
+++
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/htdocs/js/batchcreate.js
Tue Jul 29 20:49:38 2014
@@ -175,7 +175,26 @@ function emptyTable(products,href,token)
}
table.appendChild(tbody);
form.appendChild(table);
+
+ remove_row_button = document.createElement("button");
+ remove_row_button.setAttribute("class","btn pull-right");
+ remove_row_button.setAttribute("type","button");
+ remove_row_button.setAttribute("onclick","remove_row_btn_action()");
+ remove_row_button.setAttribute("id","bct-rmv-empty-row");
+ remove_row_button.appendChild(document.createTextNode("-"));
+ form.appendChild(remove_row_button);
+ add_row_button = document.createElement("button");
+ add_row_button.setAttribute("class","btn pull-right");
+ add_row_button.setAttribute("type","button");
+ add_row_button.addEventListener("click", function(event) {
+ add_row_btn_action(products);
+ event.preventDefault();
+ });
+ add_row_button.setAttribute("id","bct-add-empty-row");
+ add_row_button.appendChild(document.createTextNode("+"));
+ form.appendChild(add_row_button);
+
submit_button = document.createElement("button");
submit_button.setAttribute("class","btn pull-right");
submit_button.setAttribute("type","button");
@@ -282,3 +301,144 @@ function submit_btn_action() {
contentDiv.appendChild(div);
});
}
+
+function add_row_btn_action(products){
+ // alert("1");
+
+ var headers =
{"summary":"Summary","description":"Description","product":"Product","status":"Status","priority":"Priority"}
+ var statuses = ["accepted", "assigned", "closed", "new", "reopened"];
+ var priorities = ["blocker", "critical", "major", "minor", "trivial"];
+ var types = ["defect", "enhancement", "task"];
+
+ tr_rows = document.createElement("tr");
+
+ for (header in headers){
+ if (header == "summary"){
+ td_row = document.createElement("td");
+ input_summary = document.createElement("input");
+ input_summary.setAttribute("type","text");
+
input_summary.setAttribute("id","field-summary"+i);
+
input_summary.setAttribute("class","input-block-level");
+
input_summary.setAttribute("name","field_summary"+i);
+ td_row.appendChild(input_summary);
+ tr_rows.appendChild(td_row);
+ }
+ else if (header == "description") {
+ td_row = document.createElement("td");
+ input_description =
document.createElement("textarea");
+
input_description.setAttribute("id","field-description"+i);
+
input_description.setAttribute("class","input-block-level");
+
input_description.setAttribute("name","field_description"+i);
+ input_description.setAttribute("rows","2");
+ input_description.setAttribute("cols","28");
+ td_row.appendChild(input_description);
+ tr_rows.appendChild(td_row);
+ }
+ else if (header == "status") {
+ td_row = document.createElement("td");
+ input_status = document.createElement("select");
+
input_status.setAttribute("id","field-status"+i);
+
input_status.setAttribute("class","input-block-level");
+
input_status.setAttribute("name","field_status"+i);
+ for (status in statuses){
+ option =
document.createElement("option");
+
option.setAttribute("value",statuses[status]);
+
option.appendChild(document.createTextNode(statuses[status]));
+ input_status.appendChild(option);
+ }
+ td_row.appendChild(input_status);
+ tr_rows.appendChild(td_row);
+ }
+ else if (header == "priority") {
+ td_row = document.createElement("td");
+ input_priority =
document.createElement("select");
+
input_priority.setAttribute("id","field-priority"+i);
+
input_priority.setAttribute("class","input-block-level");
+
input_priority.setAttribute("name","field_priority"+i);
+ for (priority in priorities){
+ option =
document.createElement("option");
+
option.setAttribute("value",priorities[priority]);
+
option.appendChild(document.createTextNode(priorities[priority]));
+ input_priority.appendChild(option);
+ }
+ td_row.appendChild(input_priority);
+ tr_rows.appendChild(td_row);
+ }
+ /*else if (header == "type") {
+ td_row = document.createElement("td");
+ input_type = document.createElement("select");
+ input_type.setAttribute("id","field-type"+i);
+
input_type.setAttribute("class","input-block-level");
+ input_type.setAttribute("name","field_type"+i);
+ for (type in types){
+ option =
document.createElement("option");
+
option.setAttribute("value",types[type]);
+
option.appendChild(document.createTextNode(types[type]));
+ input_type.appendChild(option);
+ }
+ td_row.appendChild(input_type);
+ tr_rows.appendChild(td_row);
+ }*/
+ else if (header == "product") {
+ td_row = document.createElement("td");
+ field_product =
document.createElement("select");
+
field_product.setAttribute("id","field-product"+i);
+
field_product.setAttribute("class","input-block-level");
+
field_product.setAttribute("name","field_product"+i);
+ for (product in products){
+ option =
document.createElement("option");
+
option.setAttribute("value",(products[product])[0]);
+
option.appendChild(document.createTextNode((products[product])[1]));
+ field_product.appendChild(option);
+ }
+ td_row.appendChild(field_product);
+ tr_rows.appendChild(td_row);
+ }
+ /*else if (header == "owner"){
+ td_row = document.createElement("td");
+ input_owner = document.createElement("input");
+ input_owner.setAttribute("type","text");
+ input_owner.setAttribute("id","field-owner"+i);
+
input_owner.setAttribute("class","input-block-level");
+
input_owner.setAttribute("name","field_owner"+i);
+ td_row.appendChild(input_owner);
+ tr_rows.appendChild(td_row);
+ }*/
+ /*else if (header == "cc"){
+ td_row = document.createElement("td");
+ input_cc = document.createElement("input");
+ input_cc.setAttribute("type","text");
+ input_cc.setAttribute("id","field-cc"+i);
+
input_cc.setAttribute("class","input-block-level");
+ input_cc.setAttribute("name","field_cc"+i);
+ td_row.appendChild(input_cc);
+ tr_rows.appendChild(td_row);
+ }*/
+ /*else if (header == "milestone"){
+ td_row = document.createElement("td");
+ input_milestone =
document.createElement("input");
+ input_milestone.setAttribute("type","text");
+
input_milestone.setAttribute("id","field-milestone"+i);
+
input_milestone.setAttribute("class","input-block-level");
+
input_milestone.setAttribute("name","field_milestone"+i);
+ td_row.appendChild(input_milestone);
+ tr_rows.appendChild(td_row);
+ }*/
+ /*else if (header == "keywords"){
+ td_row = document.createElement("td");
+ input_keywords =
document.createElement("input");
+ input_keywords.setAttribute("type","text");
+
input_keywords.setAttribute("id","field-keywords"+i);
+
input_keywords.setAttribute("class","input-block-level");
+
input_keywords.setAttribute("name","field_keywords"+i);
+ td_row.appendChild(input_keywords);
+ tr_rows.appendChild(td_row);
+ }*/
+
+ }
+
document.getElementById("empty-table").childNodes[1].childNodes[1].childNodes[1].appendChild(tr_rows);
+}
+
+function remove_row_btn_action(){
+
document.getElementById("empty-table").childNodes[1].childNodes[1].childNodes[1].lastChild.remove();
+}
Modified:
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/theme.py
URL:
http://svn.apache.org/viewvc/bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/theme.py?rev=1614483&r1=1614482&r2=1614483&view=diff
==============================================================================
---
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/theme.py
(original)
+++
bloodhound/branches/bep_0011_batch_create_tickets/bloodhound_theme/bhtheme/theme.py
Tue Jul 29 20:49:38 2014
@@ -36,14 +36,8 @@ from trac.util.compat import set
from trac.util.presentation import to_json
from trac.versioncontrol.web_ui.browser import BrowserModule
from trac.web.api import IRequestFilter, ITemplateStreamFilter
-from trac.web.chrome import (
- add_stylesheet,
- add_warning,
- INavigationContributor,
- ITemplateProvider,
- prevnext_nav,
- Chrome,
- add_script)
+from trac.web.chrome import (add_stylesheet, add_warning,
INavigationContributor,
+ ITemplateProvider, prevnext_nav, Chrome,
add_script)
from trac.web.main import IRequestHandler
from trac.wiki.admin import WikiAdmin
from trac.wiki.formatter import format_to_html
@@ -63,9 +57,7 @@ try:
except ImportError:
ProductTicketModule = None
-
class BloodhoundTheme(ThemeBase):
-
"""Look and feel of Bloodhound issue tracker.
"""
template = htdocs = css = screenshot = disable_trac_css = True
@@ -168,34 +160,24 @@ class BloodhoundTheme(ThemeBase):
)
labels_application_short = Option('labels', 'application_short',
- 'Bloodhound', """A short version of
application name most commonly
+ 'Bloodhound', """A short version of application name most commonly
displayed in text, titles and labels""", doc_domain='bhtheme')
labels_application_full = Option('labels', 'application_full',
- 'Apache Bloodhound', """This is full name
with trade mark and
+ 'Apache Bloodhound', """This is full name with trade mark and
everything, it is currently used in footers and about page only""",
doc_domain='bhtheme')
- labels_footer_left_prefix = Option(
- 'labels',
- 'footer_left_prefix',
- '',
+ labels_footer_left_prefix = Option('labels', 'footer_left_prefix', '',
"""Text to display before full application name in footers""",
- doc_domain='bhtheme')
+ doc_domain='bhtheme')
- labels_footer_left_postfix = Option(
- 'labels',
- 'footer_left_postfix',
- '',
+ labels_footer_left_postfix = Option('labels', 'footer_left_postfix', '',
"""Text to display after full application name in footers""",
- doc_domain='bhtheme')
+ doc_domain='bhtheme')
- labels_footer_right = Option(
- 'labels',
- 'footer_right',
- '',
- """Text to use as the right aligned footer""",
- doc_domain='bhtheme')
+ labels_footer_right = Option('labels', 'footer_right', '',
+ """Text to use as the right aligned footer""", doc_domain='bhtheme')
_wiki_pages = None
Chrome.default_html_doctype = DocType.HTML5
@@ -365,13 +347,7 @@ class BloodhoundTheme(ThemeBase):
# Request modifiers
- def _modify_search_data(
- self,
- req,
- template,
- data,
- content_type,
- is_active):
+ def _modify_search_data(self, req, template, data, content_type,
is_active):
"""Insert breadcumbs and context navigation items in search web UI
"""
if is_active:
@@ -405,7 +381,7 @@ class BloodhoundTheme(ThemeBase):
self._modify_resource_breadcrumb(req, template, data, content_type,
is_active)
- # add a creation event to the changelog if the ticket exists
+ #add a creation event to the changelog if the ticket exists
ticket = data['ticket']
if ticket.exists:
data['changes'] = [{'comment': '',
@@ -417,7 +393,7 @@ class BloodhoundTheme(ThemeBase):
'date': ticket['time'],
},
] + data['changes']
- # and set default order
+ #and set default order
if not req.session.get('ticket_comments_order'):
req.session['ticket_comments_order'] = 'newest'
@@ -440,13 +416,7 @@ class BloodhoundTheme(ThemeBase):
if mname:
data['milestone'] = Milestone(self.env, mname)
- def _modify_admin_breadcrumb(
- self,
- req,
- template,
- data,
- content_type,
- is_active):
+ def _modify_admin_breadcrumb(self, req, template, data, content_type,
is_active):
# override 'normal' product list with the admin one
def admin_url(prefix):
@@ -495,7 +465,7 @@ class BloodhoundTheme(ThemeBase):
SELECT product, value FROM bloodhound_productconfig
WHERE product IN (%s) AND section='project' AND
option='icon'""" % ', '.join(["%s"] * len(products)),
- tuple(p.prefix for p in products))
+ tuple(p.prefix for p in products))
icons = dict(icons)
data['thumbsize'] = 64
# FIXME: Gray icon for missing products
@@ -510,29 +480,29 @@ class BloodhoundTheme(ThemeBase):
product_ctx(product),
product.description),
links={'extras': (([{'href': req.href.products(
- product.prefix, action='edit'),
- 'title': _('Edit product %(prefix)s',
- prefix=product.prefix),
- 'icon': tag.i(class_='icon-edit'),
- 'label': _('Edit')}, ]
- if 'PRODUCT_MODIFY' in req.perm
- else []) +
- [{'href': product.href(),
- 'title': _('Home page'),
- 'icon': tag.i(class_='icon-home'),
- 'label': _('Home')},
- {'href': product.href.dashboard(),
- 'title': _('Tickets dashboard'),
- 'icon': tag.i(class_='icon-tasks'),
- 'label': _('Tickets')},
- {'href': product.href.wiki(),
- 'title': _('Wiki'),
- 'icon': tag.i(class_='icon-book'),
- 'label': _('Wiki')}]),
- 'main': {'href': product.href(),
- 'title': None,
- 'icon': tag.i(class_='icon-chevron-right'),
- 'label': _('Browse')}})
+ product.prefix, action='edit'),
+ 'title': _('Edit product
%(prefix)s',
+ prefix=product.prefix),
+ 'icon': tag.i(class_='icon-edit'),
+ 'label': _('Edit')},]
+ if 'PRODUCT_MODIFY' in req.perm
+ else []) +
+ [{'href': product.href(),
+ 'title': _('Home page'),
+ 'icon': tag.i(class_='icon-home'),
+ 'label': _('Home')},
+ {'href': product.href.dashboard(),
+ 'title': _('Tickets dashboard'),
+ 'icon': tag.i(class_='icon-tasks'),
+ 'label': _('Tickets')},
+ {'href': product.href.wiki(),
+ 'title': _('Wiki'),
+ 'icon': tag.i(class_='icon-book'),
+ 'label': _('Wiki')}]),
+ 'main': {'href': product.href(),
+ 'title': None,
+ 'icon':
tag.i(class_='icon-chevron-right'),
+ 'label': _('Browse')}})
data['products'] = [product_media_data(icons, product)
for product in products]
@@ -550,16 +520,29 @@ class BloodhoundTheme(ThemeBase):
tag.a(_('Source'),
href=req.href.wiki('TracRepositoryAdmin')))
+class QCTSelectFieldUpdate(Component):
+ implements(IRequestHandler)
+
+ def match_request(self, req):
+ return req.path_info == '/update-menus'
+
+ def process_request(self, req):
+ product = req.args.get('product')
+ fields_to_update = req.args.get('fields_to_update[]');
+ env = ProductEnvironment(self.env.parent, req.args.get('product'))
+ ticket_fields = TicketSystem(env).get_ticket_fields()
+ data = dict([f['name'], f['options']] for f in ticket_fields
+ if f['type'] == 'select' and f['name'] in fields_to_update)
+ req.send(to_json(data), 'application/json')
+
class QuickCreateTicketDialog(Component):
implements(IRequestFilter, IRequestHandler)
- qct_fields = ListOption(
- 'ticket',
- 'quick_create_fields',
- 'product, version, type',
+ qct_fields = ListOption('ticket', 'quick_create_fields',
+ 'product, version, type',
doc="""Multiple selection fields displayed in create ticket menu""",
- doc_domain='bhtheme')
+ doc_domain='bhtheme')
def __init__(self, *args, **kwargs):
import pkg_resources
@@ -610,8 +593,8 @@ class QuickCreateTicketDialog(Component)
new_ticket_url=dum_req.href.products(p, 'newticket'),
description=ProductEnvironment.lookup_env(self.env,
p)
.product.name
- )
- for p in product_field['options']
+ )
+ for p in product_field['options']
if req.perm.has_permission('TICKET_CREATE',
Neighborhood('product', p)
.child(None, None))]
@@ -628,7 +611,7 @@ class QuickCreateTicketDialog(Component)
'fields': [all_fields[k] for k in self.qct_fields
if k in all_fields],
'hidden_fields': [all_fields[k] for k in all_fields.keys()
- if k not in self.qct_fields]}
+ if k not in self.qct_fields] }
return template, data, content_type
# IRequestHandler methods
@@ -652,7 +635,7 @@ class QuickCreateTicketDialog(Component)
attrs = dict([k[6:], v] for k, v in req.args.iteritems()
if k.startswith('field_'))
product, tid = self.create(req, summary, desc, attrs, True)
- except Exception as exc:
+ except Exception, exc:
self.log.exception("BH: Quick create ticket failed %s" % (exc,))
req.send(str(exc), 'plain/text', 500)
else:
@@ -700,7 +683,7 @@ class QuickCreateTicketDialog(Component)
try:
tn = TicketNotifyEmail(env)
tn.notify(t, newticket=True)
- except Exception as e:
+ except Exception, e:
self.log.exception("Failure sending notification on creation "
"of ticket #%s: %s" % (t.id, e))
return t['product'], t.id
@@ -708,7 +691,6 @@ class QuickCreateTicketDialog(Component)
from pkg_resources import get_distribution
application_version = get_distribution('BloodhoundTheme').version
-
class BatchCreateTicketDialog(Component):
implements(
IRequestFilter,