blob: 1f25da6793ce90cc6a1e92787c2e72789aae184b [file] [log] [blame]
from allura.lib.widgets import form_fields as ffw
from pylons import c
from formencode import validators as fev
import ew as ew_core
import ew.jinja2_ew as ew
from forgetracker import model
class TicketCustomFields(ew.CompoundField):
template='jinja:forgetracker:templates/tracker_widgets/ticket_custom_fields.html'
@property
def fields(self):
# milestone is kind of special because of the layout
# add it to the main form rather than handle with the other customs
fields = []
for cf in c.app.globals.custom_fields:
if cf.name != '_milestone':
fields.append(TicketCustomField.make(cf))
return fields
class GenericTicketForm(ew.SimpleForm):
defaults=dict(
ew.SimpleForm.defaults,
name="ticket_form",
submit_text='Save',
ticket=None,
show_comment=False)
def display_field_by_name(self, idx, ignore_errors=False):
field = self.fields[idx]
ctx = self.context_for(field)
display = field.display(**ctx)
if ctx['errors'] and field.show_errors and not ignore_errors:
display = "%s<div class='error'>%s</div>" % (display, ctx['errors'])
return display
@property
def fields(self):
fields = [
ew.TextField(name='summary', label='Title',
attrs={'style':'width: 425px','placeholder':'Title'},
validator=fev.UnicodeString(not_empty=True, messages={'empty':"You must provide a Title"})),
ffw.MarkdownEdit(label='Description',name='description',
attrs={'style':'width: 95%'}),
ew.SingleSelectField(name='status', label='Status',
options=lambda: c.app.globals.all_status_names.split()),
ffw.ProjectUserSelect(name='assigned_to', label='Assigned To'),
ffw.LabelEdit(label='Labels',name='labels', className='ticket_form_tags'),
ew.Checkbox(name='private', label='Mark as Private', attrs={'class':'unlabeled'}),
ew.InputField(name='attachment', label='Attachment', field_type='file', validator=fev.FieldStorageUploadConverter(if_missing=None)),
ffw.MarkdownEdit(name='comment', label='Comment',
attrs={'style':'min-height:7em; width:97%'}),
ew.SubmitButton(label=self.submit_text,name='submit',
attrs={'class':"ui-button ui-widget ui-state-default ui-button-text-only"}),
ew.HiddenField(name='ticket_num', validator=fev.Int(if_missing=None)),
ew.HiddenField(name='super_id', validator=fev.UnicodeString(if_missing=None)) ]
# milestone is kind of special because of the layout
# add it to the main form rather than handle with the other customs
if c.app.globals.custom_fields:
for cf in c.app.globals.custom_fields:
if cf.name == '_milestone':
fields.append(TicketCustomField.make(cf))
break
return ew_core.NameList(fields)
class TicketForm(GenericTicketForm):
template='jinja:forgetracker:templates/tracker_widgets/ticket_form.html'
@property
def fields(self):
fields = ew_core.NameList(super(TicketForm, self).fields)
if c.app.globals.custom_fields:
fields.append(TicketCustomFields(name="custom_fields"))
return fields
def resources(self):
for r in super(TicketForm, self).resources(): yield r
yield ew.JSScript('''
$(function(){
$('#show_attach input').click(function(){
$('#view_attach').show();
$('#show_attach').hide();
});
$('form').submit(function() {
$('input[type=submit]', this).attr('disabled', 'disabled');
});
$('div.reply.discussion-post a.markdown_preview').click(function(){
var arrow = $(this).closest('.discussion-post').find('span.arw');
arrow.hide();
});
$('div.reply.discussion-post a.markdown_edit').click(function(){
var arrow = $(this).closest('.discussion-post').find('span.arw');
arrow.show();
});
});''')
class TicketCustomField(object):
def _select(field):
options = []
for opt in field.options.split():
selected = False
if opt.startswith('*'):
opt = opt[1:]
selected = True
options.append(ew.Option(label=opt,html_value=opt,py_value=opt,selected=selected))
return ew.SingleSelectField(label=field.label, name=str(field.name), options=options)
def _milestone(field):
options = []
for m in field.milestones:
if not m.complete:
options.append(ew.Option(
label=m.name,
py_value=m.name))
ssf = ew.SingleSelectField(
label=field.label, name=str(field.name),
options=options)
return ssf
def _boolean(field):
return ew.Checkbox(label=field.label, name=str(field.name), suppress_label=True)
def _number(field):
return ew.NumberField(label=field.label, name=str(field.name))
def _user(field):
return ffw.ProjectUserSelect(label=field.label, name=str(field.name))
@staticmethod
def _default(field):
return ew.TextField(label=field.label, name=str(field.name))
SELECTOR = dict(
select=_select,
milestone=_milestone,
boolean=_boolean,
sum=_number,
number=_number,
user=_user)
@classmethod
def make(cls, field):
factory = cls.SELECTOR.get(field.get('type'), cls._default)
return factory(field)