Skip to content

Commit 73f9fe3

Browse files
committed
Allow the user to select a referenced liaison. Fixes ietf-tools#381
- Legacy-Id: 2538
1 parent 2003275 commit 73f9fe3

7 files changed

Lines changed: 133 additions & 3 deletions

File tree

ietf/liaisons/forms.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from django import forms
55
from django.conf import settings
6+
from django.db.models import Q
67
from django.forms.util import ErrorList
78
from django.forms.fields import email_re
89
from django.template.loader import render_to_string
@@ -12,7 +13,7 @@
1213
from ietf.liaisons.models import LiaisonDetail, Uploads, OutgoingLiaisonApproval, SDOs
1314
from ietf.liaisons.utils import IETFHM
1415
from ietf.liaisons.widgets import (FromWidget, ReadOnlyWidget, ButtonWidget,
15-
ShowAttachmentsWidget)
16+
ShowAttachmentsWidget, RelatedLiaisonWidget)
1617

1718

1819
class LiaisonForm(forms.ModelForm):
@@ -33,11 +34,13 @@ class LiaisonForm(forms.ModelForm):
3334
require=['id_attach_title', 'id_attach_file'],
3435
required_label='title and file'),
3536
required=False)
37+
related_to = forms.ModelChoiceField(LiaisonDetail.objects.all(), label=u'Related Liaison', widget=RelatedLiaisonWidget, required=False)
3638

3739
fieldsets = [('From', ('from_field', 'replyto')),
3840
('To', ('organization', 'to_poc')),
3941
('Other email addresses', ('response_contact', 'technical_contact', 'cc1')),
4042
('Purpose', ('purpose', 'purpose_text', 'deadline_date')),
43+
('References', ('related_to', )),
4144
('Liaison Statement', ('title', 'body', 'attachments')),
4245
('Add attachment', ('attach_title', 'attach_file', 'attach_button')),
4346
]
@@ -318,7 +321,7 @@ class Meta:
318321
model = LiaisonDetail
319322
fields = ('from_raw_body', 'to_body', 'to_poc', 'cc1', 'last_modified_date', 'title',
320323
'response_contact', 'technical_contact', 'purpose_text', 'body',
321-
'deadline_date', 'purpose', 'replyto', )
324+
'deadline_date', 'purpose', 'replyto', 'related_to')
322325

323326
def __init__(self, *args, **kwargs):
324327
super(EditLiaisonForm, self).__init__(*args, **kwargs)

ietf/liaisons/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@
2828
url(r'^for_approval/(?P<object_id>\d+)/$', 'liaison_approval_detail', name='liaison_approval_detail'),
2929
url(r'^add/$', 'add_liaison', name='add_liaison'),
3030
url(r'^ajax/get_info/$', 'get_info', name='get_info'),
31+
url(r'^ajax/liaison_list/$', 'ajax_liaison_list', name='ajax_liaison_list'),
3132
)

ietf/liaisons/views.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,12 @@ def liaison_detail(request, object_id):
167167
def liaison_edit(request, object_id):
168168
liaison = get_object_or_404(LiaisonDetail, pk=object_id)
169169
return add_liaison(request, liaison=liaison)
170+
171+
def ajax_liaison_list(request):
172+
public_liaisons = LiaisonDetail.objects.filter(Q(approval__isnull=True)|Q(approval__approved=True)).order_by("-submitted_date")
173+
174+
return object_list(request, public_liaisons,
175+
allow_empty=True,
176+
template_name='liaisons/liaisondetail_simple_list.html',
177+
extra_context={}
178+
)

ietf/liaisons/widgets.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from django.conf import settings
2+
from django.core.urlresolvers import reverse
23
from django.db.models.query import QuerySet
3-
from django.forms.widgets import Select, Widget
4+
from django.forms.widgets import Select, Widget, TextInput
45
from django.utils.safestring import mark_safe
56

67

@@ -64,3 +65,33 @@ def render(self, name, value, attrs=None):
6465
html += u'No files attached'
6566
html += u'</div></div>'
6667
return mark_safe(html)
68+
69+
70+
class RelatedLiaisonWidget(TextInput):
71+
72+
def render(self, name, value, attrs=None):
73+
if not value:
74+
value = ''
75+
title = ''
76+
noliaison = 'inline'
77+
deselect = 'none'
78+
else:
79+
from ietf.liaisons.models import LiaisonDetail
80+
liaison = LiaisonDetail.objects.get(pk=value)
81+
title = liaison.title
82+
if not title:
83+
files = liaison.uploads_set.all()
84+
if files:
85+
title = files[0].file_title
86+
else:
87+
title = 'Liaison #%s' % liaison.pk
88+
noliaison = 'none'
89+
deselect = 'inline'
90+
html = u'<span class="noRelated" style="display: %s;">No liaison selected</span>' % noliaison
91+
html += u'<span class="relatedLiaisonWidgetTitle">%s</span>' % title
92+
html += u'<input type="hidden" name="%s" class="relatedLiaisonWidgetValue" value="%s" /> ' % (name, value)
93+
html += u'<span style="display: none;" class="listURL">%s</span> ' % reverse('ajax_liaison_list')
94+
html += u'<div style="display: none;" class="relatedLiaisonWidgetDialog" id="related-dialog" title="Select a liaison"></div> '
95+
html += '<input type="button" id="id_%s" value="Select liaison" /> ' % name
96+
html += '<input type="button" style="display: %s;" id="id_no_%s" value="Deselect liaison" />' % (deselect, name)
97+
return mark_safe(html)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<table class="ietf-table" width="100%">
2+
<tr><th width="9%">Date</th><th width="20%">From</th><th width="20%">To</th><th width="50%">Title</th></tr>
3+
4+
{% for liaison in object_list %}
5+
<tr class="{% cycle oddrow,evenrow %}">
6+
<td style="white-space:nowrap;">{{ liaison.submitted_date|date:"Y-m-d" }}</td>
7+
<td>{{ liaison.from_body|escape }}</td>
8+
<td>
9+
{% if liaison.by_secretariat %}
10+
{% if liaison.submitter_email %}
11+
<a href="mailto:{{ liaison.submitter_email}}">{{ liaison.submitter_name|escape }}</a>
12+
{% else %}
13+
{{ liaison.submitter_name|escape }}
14+
{% endif %}
15+
{% else %}
16+
{{ liaison.to_body|escape }}
17+
{% endif %}
18+
</td>
19+
<td>
20+
{% if liaison.by_secretariat %}
21+
{% for file in liaison.uploads_set.all %}
22+
<a href="https://datatracker.ietf.org/documents/LIAISON/file{{ file.file_id }}{{ file.file_extension }}">{{ file.file_title|escape }}</a><br/>
23+
{% endfor %}
24+
{% else %}
25+
<a href="{{ liaison.detail_id }}/">{{ liaison.title|escape }}</a>
26+
{% endif %}
27+
<span style="display: none" class="liaisonPK">{{ liaison.pk }}</span>
28+
</td>
29+
</tr>
30+
{% endfor %}
31+
32+
</table>

static/images/ajax-loader.gif

847 Bytes
Loading

static/js/liaisons.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@
140140
var cancel = form.find('#id_cancel');
141141
var cancel_dialog = form.find('#cancel-dialog');
142142
var config = {};
143+
var related_trigger = form.find('#id_related_to');
144+
var related_dialog = form.find('#related-dialog');
145+
var unrelate_trigger = form.find('#id_no_related_to');
143146

144147
var readConfig = function() {
145148
var confcontainer = form.find('.formconfig');
@@ -232,13 +235,56 @@
232235
cancel_dialog.dialog("open");
233236
};
234237

238+
var getRelatedLink = function() {
239+
link = $(this).text();;
240+
pk = $(this).nextAll('.liaisonPK').text();
241+
widget = related_trigger.parent();
242+
widget.find('.relatedLiaisonWidgetTitle').text(link);
243+
widget.find('.relatedLiaisonWidgetValue').val(pk);
244+
widget.find('.noRelated').hide();
245+
unrelate_trigger.show();
246+
related_dialog.dialog('close');
247+
return false;
248+
};
249+
250+
var selectNoRelated = function() {
251+
widget = $(this).parent();
252+
widget.find('.relatedLiaisonWidgetTitle').text('');
253+
widget.find('.noRelated').show();
254+
widget.find('.relatedLiaisonWidgetValue').val('');
255+
$(this).hide();
256+
return false;
257+
};
258+
259+
var selectRelated = function() {
260+
widget = $(this).parent();
261+
url = widget.find('.listURL').text();
262+
title = widget.find('.relatedLiaisonWidgetTitle');
263+
related_dialog.html('<img src="/images/ajax-loader.gif" />');
264+
related_dialog.dialog('open');
265+
$.ajax({
266+
url: url,
267+
type: 'GET',
268+
cache: false,
269+
async: true,
270+
dataType: 'html',
271+
success: function(response){
272+
related_dialog.html(response);
273+
related_dialog.find('a').click(getRelatedLink);
274+
}
275+
});
276+
return false;
277+
};
278+
235279
var initTriggers = function() {
236280
organization.change(updateInfo);
237281
organization.change(checkOtherSDO);
238282
from.change(updateInfo);
239283
reply.keyup(updateFrom);
240284
purpose.change(updatePurpose);
241285
cancel.click(cancelForm);
286+
related_trigger.click(selectRelated);
287+
unrelate_trigger.click(selectNoRelated);
242288
};
243289

244290
var updateOnInit = function() {
@@ -275,6 +321,14 @@
275321
}
276322
}
277323
});
324+
325+
related_dialog.dialog({
326+
height: 400,
327+
width: 800,
328+
draggable: true,
329+
modal: true,
330+
autoOpen: false
331+
});
278332
};
279333

280334
var initForm = function() {

0 commit comments

Comments
 (0)