Skip to content

Commit 23ebe5d

Browse files
committed
This addresses ease of editing various group attributes, and in particular is
intended to make it easier to see that you can edit things like the external/additional URLs: - Added the ability to edit individual fields in a group's about page, and added edit buttons for editable fields on the about page, just as for documents (the ability to edit all editable fields already was available from the 'Edit group' button on the /group//about/ page). - Made the tab label for the group-about tab consistently say 'About', instead of 'Charter' for some groups. = Shifted the position of the about tab to the start of the tab line. - Removed the datatracker account requirement information at the top of the group edit page for users logged in to their account. - Tweaked the 'Show update' link on the 'Status Update' line. - Changed the label for the external URLs from 'More Info' to 'Additional URLs', which was already in use on the edit form. - Legacy-Id: 12904
1 parent ffa19c9 commit 23ebe5d

8 files changed

Lines changed: 147 additions & 38 deletions

File tree

PLAN

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ Planned work in rough order
1010
* Add a 'rev' field to DocEvent, migrate 'rev' information from New
1111
Revision and Submit DocEvents, and infer 'rev' information for others
1212

13-
* Schema Changes: tags, external links for groups.
14-
1513
* Add "Waiting for implementation" and "Held by WG" states, with comment field
1614

1715
* Break out the htmlzation code used on tools in a library, and use that

ietf/group/tests_info.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,44 @@ def test_edit_info(self):
620620
for prefix in ['ad1','ad2','aread','marschairman','marsdelegate']:
621621
self.assertTrue(prefix+'@' in outbox[0]['To'])
622622

623+
624+
def test_edit_field(self):
625+
make_test_data()
626+
group = Group.objects.get(acronym="mars")
627+
628+
# Edit name
629+
url = urlreverse('ietf.group.views_edit.edit', kwargs=dict(acronym=group.acronym, action="edit", field="name"))
630+
login_testing_unauthorized(self, "secretary", url)
631+
# normal get
632+
r = self.client.get(url)
633+
self.assertEqual(r.status_code, 200)
634+
q = PyQuery(r.content)
635+
self.assertEqual(len(q('div#content > form input[name=name]')), 1)
636+
self.assertEqual(len(q('form input[name=acronym]')), 0)
637+
# edit info
638+
r = self.client.post(url, dict(name="Mars Not Special Interest Group"))
639+
self.assertEqual(r.status_code, 302)
640+
#
641+
group = Group.objects.get(acronym="mars")
642+
self.assertEqual(group.name, "Mars Not Special Interest Group")
643+
644+
645+
# Edit list email
646+
url = urlreverse('ietf.group.views_edit.edit', kwargs=dict(group_type=group.type_id, acronym=group.acronym, action="edit", field="list_email"))
647+
# normal get
648+
r = self.client.get(url)
649+
self.assertEqual(r.status_code, 200)
650+
q = PyQuery(r.content)
651+
self.assertEqual(len(q('div#content > form input[name=list_email]')), 1)
652+
self.assertEqual(len(q('div#content > form input[name=name]')), 0)
653+
# edit info
654+
r = self.client.post(url, dict(list_email="mars@mail"))
655+
self.assertEqual(r.status_code, 302)
656+
#
657+
group = Group.objects.get(acronym="mars")
658+
self.assertEqual(group.list_email, "mars@mail")
659+
660+
623661
def test_edit_reviewers(self):
624662
doc = make_test_data()
625663
review_req = make_review_data(doc)

ietf/group/urls_info_details.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
url(r'^deps/(?P<output_type>[\w-]+)/$', views.dependencies),
2424
url(r'^meetings/$', views.meetings),
2525
url(r'^edit/$', views_edit.edit, {'action': "edit"}),
26+
url(r'^edit/(?P<field>\w+)/?$', views_edit.edit, {'action': "edit"}),
2627
url(r'^conclude/$', views_edit.conclude),
2728
url(r'^milestones/$', milestone_views.edit_milestones, {'milestone_set': "current"}, "group_edit_milestones"),
2829
url(r'^milestones/charter/$', milestone_views.edit_milestones, {'milestone_set': "charter"}, "group_edit_charter_milestones"),

ietf/group/utils.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,9 @@ def construct_group_menu_context(request, group, selected, group_type, others):
169169

170170
# menu entries
171171
entries = []
172+
entries.append(("About", urlreverse("ietf.group.views.group_about", kwargs=kwargs)))
172173
if group.features.has_documents:
173174
entries.append(("Documents", urlreverse("ietf.group.views.group_documents", kwargs=kwargs)))
174-
if group.features.has_chartering_process:
175-
entries.append(("Charter", urlreverse("ietf.group.views.group_about", kwargs=kwargs)))
176-
else:
177-
entries.append(("About", urlreverse("ietf.group.views.group_about", kwargs=kwargs)))
178175
if group.features.has_materials and get_group_materials(group).exists():
179176
entries.append(("Materials", urlreverse("ietf.group.views.materials", kwargs=kwargs)))
180177
if group.features.has_reviews:
@@ -199,6 +196,7 @@ def construct_group_menu_context(request, group, selected, group_type, others):
199196

200197
is_admin = group.has_role(request.user, group.features.admin_roles)
201198
can_manage = can_manage_group_type(request.user, group)
199+
can_edit_group = False # we'll set this further down
202200

203201
if group.features.has_milestones:
204202
if group.state_id != "proposed" and (is_admin or can_manage):
@@ -223,6 +221,7 @@ def construct_group_menu_context(request, group, selected, group_type, others):
223221

224222

225223
if group.state_id != "conclude" and (is_admin or can_manage):
224+
can_edit_group = True
226225
actions.append((u"Edit group", urlreverse("ietf.group.views_edit.edit", kwargs=dict(kwargs, action="edit"))))
227226

228227
if group.features.customize_workflow and (is_admin or can_manage):
@@ -237,6 +236,7 @@ def construct_group_menu_context(request, group, selected, group_type, others):
237236
"menu_entries": entries,
238237
"menu_actions": actions,
239238
"group_type": group_type,
239+
"can_edit_group": can_edit_group,
240240
}
241241

242242
d.update(others)

ietf/group/views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ def group_about(request, acronym, group_type=None):
435435

436436

437437
return render(request, 'group/group_about.html',
438-
construct_group_menu_context(request, group, "charter" if group.features.has_chartering_process else "about", group_type, {
438+
construct_group_menu_context(request, group, "about", group_type, {
439439
"milestones_in_review": group.groupmilestone_set.filter(state="review"),
440440
"milestone_reviewer": milestone_reviewer_for_group_type(group_type),
441441
"requested_close": requested_close,

ietf/group/views_edit.py

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ class GroupForm(forms.Form):
5757
def __init__(self, *args, **kwargs):
5858
self.group = kwargs.pop('group', None)
5959
self.group_type = kwargs.pop('group_type', False)
60+
if "field" in kwargs:
61+
field = kwargs["field"]
62+
del kwargs["field"]
63+
if field in roles_for_group_type(self.group_type):
64+
field = field + "_roles"
65+
else:
66+
field = None
6067

6168
super(self.__class__, self).__init__(*args, **kwargs)
6269

@@ -85,6 +92,10 @@ def __init__(self, *args, **kwargs):
8592
- set(roles_for_group_type(self.group_type)))
8693
for r in role_fields_to_remove:
8794
del self.fields[r + "_roles"]
95+
if field:
96+
for f in self.fields:
97+
if f != field:
98+
del self.fields[f]
8899

89100
def clean_acronym(self):
90101
# Changing the acronym of an already existing group will cause 404s all
@@ -158,6 +169,7 @@ def clean(self):
158169
raise forms.ValidationError("You requested the creation of a BoF, but specified no parent area. A parent is required when creating a bof.")
159170
return cleaned_data
160171

172+
161173
def format_urls(urls, fs="\n"):
162174
res = []
163175
for u in urls:
@@ -221,7 +233,7 @@ def format_urls(urls, fs="\n"):
221233
# return redirect('charter_submit', name=group.charter.name, option="initcharter")
222234

223235
@login_required
224-
def edit(request, group_type=None, acronym=None, action="edit"):
236+
def edit(request, group_type=None, acronym=None, action="edit", field=None):
225237
"""Edit or create a group, notifying parties as
226238
necessary and logging changes as group events."""
227239
if action == "edit":
@@ -241,7 +253,7 @@ def edit(request, group_type=None, acronym=None, action="edit"):
241253
return HttpResponseForbidden("You don't have permission to access this view")
242254

243255
if request.method == 'POST':
244-
form = GroupForm(request.POST, group=group, group_type=group_type)
256+
form = GroupForm(request.POST, group=group, group_type=group_type, field=field)
245257
if form.is_valid():
246258
clean = form.cleaned_data
247259
if new_group:
@@ -284,6 +296,8 @@ def desc(attr, new, old):
284296
return entry % dict(attr=attr, new=new, old=old)
285297

286298
def diff(attr, name):
299+
if field and attr != field:
300+
return
287301
v = getattr(group, attr)
288302
if clean[attr] != v:
289303
changes.append((attr, clean[attr], desc(name, clean[attr], v)))
@@ -335,20 +349,21 @@ def diff(attr, name):
335349
email_personnel_change(request, group, personnel_change_text, changed_personnel)
336350

337351
# update urls
338-
new_urls = clean['urls']
339-
old_urls = format_urls(group.groupurl_set.order_by('url'), ", ")
340-
if ", ".join(sorted(new_urls)) != old_urls:
341-
changes.append(('urls', new_urls, desc('Urls', ", ".join(sorted(new_urls)), old_urls)))
342-
group.groupurl_set.all().delete()
343-
# Add new ones
344-
for u in new_urls:
345-
m = re.search('(?P<url>[\w\d:#@%/;$()~_?\+-=\\\.&]+)( \((?P<name>.+)\))?', u)
346-
if m:
347-
if m.group('name'):
348-
url = GroupURL(url=m.group('url'), name=m.group('name'), group=group)
349-
else:
350-
url = GroupURL(url=m.group('url'), name='', group=group)
351-
url.save()
352+
if 'urls' in clean:
353+
new_urls = clean['urls']
354+
old_urls = format_urls(group.groupurl_set.order_by('url'), ", ")
355+
if ", ".join(sorted(new_urls)) != old_urls:
356+
changes.append(('urls', new_urls, desc('Urls', ", ".join(sorted(new_urls)), old_urls)))
357+
group.groupurl_set.all().delete()
358+
# Add new ones
359+
for u in new_urls:
360+
m = re.search('(?P<url>[\w\d:#@%/;$()~_?\+-=\\\.&]+)( \((?P<name>.+)\))?', u)
361+
if m:
362+
if m.group('name'):
363+
url = GroupURL(url=m.group('url'), name=m.group('name'), group=group)
364+
else:
365+
url = GroupURL(url=m.group('url'), name='', group=group)
366+
url.save()
352367

353368
group.time = datetime.datetime.now()
354369

@@ -384,15 +399,13 @@ def diff(attr, name):
384399
else:
385400
init = dict(ad=request.user.person.id if group_type == "wg" and has_role(request.user, "Area Director") else None,
386401
)
387-
form = GroupForm(initial=init, group=group, group_type=group_type)
402+
form = GroupForm(initial=init, group=group, group_type=group_type, field=field)
388403

389404
return render(request, 'group/edit.html',
390405
dict(group=group,
391406
form=form,
392407
action=action))
393408

394-
395-
396409
class ConcludeForm(forms.Form):
397410
instructions = forms.CharField(widget=forms.Textarea(attrs={'rows': 30}), required=True, strip=False)
398411

ietf/templates/group/edit.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,13 @@ <h1>
3030
{% endif %}
3131
</h1>
3232

33+
{% if not request.user.is_authenticated %}
3334
<p class="alert alert-info">Note that persons with authorization to manage information, e.g.
3435
chairs and delegates, need a datatracker account to actually do
3536
so. New accounts can be <a href="{% url "ietf.ietfauth.views.create_account" %}">created here</a>.</p>
37+
{% else %}
38+
<p></p>
39+
{% endif %}
3640

3741
<form class="form-horizontal" method="post">
3842
{% csrf_token %}

0 commit comments

Comments
 (0)