Adds views of active areas, area groups, teams, and directorates.
Adds navigation to those views to the base menus. Unifies URL patterns shared between group/urls and group/urls_info, exposing the same view at, e.g., /group/stir and /wg/stir/. Improves testing, primarily of group/info.py Commit ready for merge. - Legacy-Id: 9924
This commit is contained in:
parent
a4c6842e16
commit
461af5af19
14
ietf/doc/templatetags/active_groups_menu.py
Normal file
14
ietf/doc/templatetags/active_groups_menu.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
from django import template
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
from ietf.name.models import GroupTypeName
|
||||
|
||||
register = template.Library()
|
||||
|
||||
@register.simple_tag
|
||||
def active_groups_menu():
|
||||
parents = GroupTypeName.objects.filter(slug__in=['ag','area','team','dir'])
|
||||
for p in parents:
|
||||
p.menu_url = '/%s/'%p.slug
|
||||
return render_to_string('base/menu_active_groups.html', { 'parents': parents })
|
||||
|
|
@ -167,14 +167,29 @@ def get_or_create_initial_charter(group, group_type):
|
|||
return charter
|
||||
|
||||
@login_required
|
||||
def submit_initial_charter(request, group_type, acronym=None):
|
||||
if not can_manage_group_type(request.user, group_type):
|
||||
return HttpResponseForbidden("You don't have permission to access this view")
|
||||
def submit_initial_charter(request, group_type=None, acronym=None):
|
||||
|
||||
# This needs refactoring.
|
||||
# The signature assumed you could have groups with the same name, but with different types, which we do not allow.
|
||||
# Consequently, this can be called with an existing group acronym and a type
|
||||
# that doesn't match the existing group type. The code below essentially ignores the group_type argument.
|
||||
#
|
||||
# If possible, the use of get_or_create_initial_charter should be moved
|
||||
# directly into charter_submit, and this function should go away.
|
||||
|
||||
if acronym==None:
|
||||
raise Http404
|
||||
|
||||
group = get_object_or_404(Group, acronym=acronym)
|
||||
if not group.features.has_chartering_process:
|
||||
raise Http404
|
||||
|
||||
# This is where we start ignoring the passed in group_type
|
||||
group_type = group.type_id
|
||||
|
||||
if not can_manage_group_type(request.user, group_type):
|
||||
return HttpResponseForbidden("You don't have permission to access this view")
|
||||
|
||||
if not group.charter:
|
||||
group.charter = get_or_create_initial_charter(group, group_type)
|
||||
group.save()
|
||||
|
|
|
@ -20,6 +20,7 @@ class GroupFeatures(object):
|
|||
self.default_tab = "group_docs"
|
||||
elif group.type_id in ("team",):
|
||||
self.has_materials = True
|
||||
self.default_tab = "group_about"
|
||||
|
||||
if self.has_chartering_process:
|
||||
self.about_page = "group_charter"
|
||||
|
|
|
@ -189,16 +189,43 @@ def wg_charters_by_acronym(request, group_type):
|
|||
{ 'groups': groups },
|
||||
content_type='text/plain; charset=UTF-8')
|
||||
|
||||
def active_groups(request, group_type):
|
||||
if group_type == "wg":
|
||||
def active_groups(request, group_type=None):
|
||||
|
||||
if not group_type:
|
||||
return active_group_types(request)
|
||||
elif group_type == "wg":
|
||||
return active_wgs(request)
|
||||
elif group_type == "rg":
|
||||
return active_rgs(request)
|
||||
elif group_type == "ag":
|
||||
return active_ags(request)
|
||||
elif group_type == "area":
|
||||
return active_areas(request)
|
||||
elif group_type == "team":
|
||||
return active_teams(request)
|
||||
elif group_type == "dir":
|
||||
return active_dirs(request)
|
||||
else:
|
||||
raise Http404
|
||||
|
||||
def active_group_types(request):
|
||||
grouptypes = GroupTypeName.objects.filter(slug__in=['wg','rg','ag','team','dir','area'])
|
||||
return render(request, 'group/active_groups.html', {'grouptypes':grouptypes})
|
||||
|
||||
def active_dirs(request):
|
||||
dirs = Group.objects.filter(type="dir", state="active").order_by("name")
|
||||
for group in dirs:
|
||||
group.chairs = sorted(roles(group, "chair"), key=extract_last_name)
|
||||
group.ads = sorted(roles(group, "ad"), key=extract_last_name)
|
||||
group.secretaries = sorted(roles(group, "secr"), key=extract_last_name)
|
||||
return render(request, 'group/active_dirs.html', {'dirs' : dirs })
|
||||
|
||||
def active_teams(request):
|
||||
teams = Group.objects.filter(type="team", state="active").order_by("name")
|
||||
for group in teams:
|
||||
group.chairs = sorted(roles(group, "chair"), key=extract_last_name)
|
||||
return render(request, 'group/active_teams.html', {'teams' : teams })
|
||||
|
||||
def active_areas(request):
|
||||
areas = Group.objects.filter(type="area", state="active").order_by("name")
|
||||
return render(request, 'group/active_areas.html', {'areas': areas })
|
||||
|
@ -235,6 +262,15 @@ def active_rgs(request):
|
|||
|
||||
return render(request, 'group/active_rgs.html', { 'irtf': irtf, 'groups': groups })
|
||||
|
||||
def active_ags(request):
|
||||
|
||||
groups = Group.objects.filter(type="ag", state="active").order_by("acronym")
|
||||
for group in groups:
|
||||
group.chairs = sorted(roles(group, "chair"), key=extract_last_name)
|
||||
group.ads = sorted(roles(group, "ad"), key=extract_last_name)
|
||||
|
||||
return render(request, 'group/active_ags.html', { 'groups': groups })
|
||||
|
||||
def bofs(request, group_type):
|
||||
groups = Group.objects.filter(type=group_type, state="bof")
|
||||
return render(request, 'group/bofs.html',dict(groups=groups))
|
||||
|
|
|
@ -63,21 +63,25 @@ class GroupTests(TestCase):
|
|||
make_test_data()
|
||||
for group in Group.objects.filter(Q(type="wg") | Q(type="rg")):
|
||||
client = Client(Accept='application/pdf')
|
||||
r = client.get(urlreverse("ietf.group.info.dependencies_dot",
|
||||
kwargs=dict(acronym=group.acronym)))
|
||||
self.assertTrue(r.status_code == 200, "Failed to receive "
|
||||
"a dot dependency graph for group: %s"%group.acronym)
|
||||
self.assertGreater(len(r.content), 0, "Dot dependency graph for group "
|
||||
"%s has no content"%group.acronym)
|
||||
for url in [ urlreverse("ietf.group.info.dependencies_dot",kwargs=dict(acronym=group.acronym)),
|
||||
urlreverse("ietf.group.info.dependencies_dot",kwargs=dict(acronym=group.acronym,group_type=group.type_id)),
|
||||
]:
|
||||
r = client.get(url)
|
||||
self.assertTrue(r.status_code == 200, "Failed to receive "
|
||||
"a dot dependency graph for group: %s"%group.acronym)
|
||||
self.assertGreater(len(r.content), 0, "Dot dependency graph for group "
|
||||
"%s has no content"%group.acronym)
|
||||
|
||||
def test_group_document_dependency_pdffile(self):
|
||||
make_test_data()
|
||||
for group in Group.objects.filter(Q(type="wg") | Q(type="rg")):
|
||||
client = Client(Accept='application/pdf')
|
||||
r = client.get(urlreverse("ietf.group.info.dependencies_pdf",
|
||||
kwargs=dict(acronym=group.acronym)))
|
||||
self.assertTrue(r.status_code == 200, "Failed to receive "
|
||||
"a pdf dependency graph for group: %s"%group.acronym)
|
||||
self.assertGreater(len(r.content), 0, "Pdf dependency graph for group "
|
||||
"%s has no content"%group.acronym)
|
||||
for url in [ urlreverse("ietf.group.info.dependencies_pdf",kwargs=dict(acronym=group.acronym)),
|
||||
urlreverse("ietf.group.info.dependencies_pdf",kwargs=dict(acronym=group.acronym,group_type=group.type_id)),
|
||||
]:
|
||||
r = client.get(url)
|
||||
self.assertTrue(r.status_code == 200, "Failed to receive "
|
||||
"a pdf dependency graph for group: %s"%group.acronym)
|
||||
self.assertGreater(len(r.content), 0, "Pdf dependency graph for group "
|
||||
"%s has no content"%group.acronym)
|
||||
|
||||
|
|
|
@ -10,11 +10,12 @@ import debug # pyflakes:ignore
|
|||
|
||||
from django.conf import settings
|
||||
from django.core.urlresolvers import reverse as urlreverse
|
||||
from django.core.urlresolvers import NoReverseMatch
|
||||
|
||||
from ietf.doc.models import Document, DocAlias, DocEvent, State
|
||||
from ietf.group.models import Group, GroupEvent, GroupMilestone, GroupStateTransitions, MilestoneGroupEvent
|
||||
from ietf.group.utils import save_group_in_history
|
||||
from ietf.name.models import DocTagName, GroupStateName
|
||||
from ietf.name.models import DocTagName, GroupStateName, GroupTypeName
|
||||
from ietf.person.models import Person, Email
|
||||
from ietf.utils.test_utils import TestCase
|
||||
from ietf.utils.mail import outbox
|
||||
|
@ -48,11 +49,37 @@ class GroupPagesTests(TestCase):
|
|||
url = urlreverse('ietf.group.info.active_groups', kwargs=dict(group_type="rg"))
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertTrue('Active Research Groups' in r.content)
|
||||
|
||||
url = urlreverse('ietf.group.info.active_groups', kwargs=dict(group_type="area"))
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertTrue("farfut" in r.content)
|
||||
self.assertTrue("Far Future (farfut)" in r.content)
|
||||
|
||||
url = urlreverse('ietf.group.info.active_groups', kwargs=dict(group_type="ag"))
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertTrue("Active Area Groups" in r.content)
|
||||
|
||||
url = urlreverse('ietf.group.info.active_groups', kwargs=dict(group_type="dir"))
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertTrue("Active Directorates" in r.content)
|
||||
|
||||
url = urlreverse('ietf.group.info.active_groups', kwargs=dict(group_type="team"))
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertTrue("Active Teams" in r.content)
|
||||
|
||||
url = urlreverse('ietf.group.info.active_groups', kwargs=dict())
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertTrue("Directorate" in r.content)
|
||||
self.assertTrue("AG" in r.content)
|
||||
|
||||
for slug in GroupTypeName.objects.exclude(slug__in=['wg','rg','ag','area','dir','team']).values_list('slug',flat=True):
|
||||
with self.assertRaises(NoReverseMatch):
|
||||
url=urlreverse('ietf.group.info.active_groups', kwargs=dict(group_type=slug))
|
||||
|
||||
def test_wg_summaries(self):
|
||||
draft = make_test_data()
|
||||
|
@ -195,14 +222,17 @@ class GroupPagesTests(TestCase):
|
|||
due=datetime.date.today() + datetime.timedelta(days=100))
|
||||
milestone.docs.add(draft)
|
||||
|
||||
url = group.about_url()
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertTrue(group.name in r.content)
|
||||
self.assertTrue(group.acronym in r.content)
|
||||
self.assertTrue("This is a charter." in r.content)
|
||||
self.assertTrue(milestone.desc in r.content)
|
||||
self.assertTrue(milestone.docs.all()[0].name in r.content)
|
||||
for url in [group.about_url(),
|
||||
urlreverse('ietf.group.info.group_about',kwargs=dict(acronym=group.acronym)),
|
||||
urlreverse('ietf.group.info.group_about',kwargs=dict(acronym=group.acronym,group_type=group.type_id)),
|
||||
]:
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertTrue(group.name in r.content)
|
||||
self.assertTrue(group.acronym in r.content)
|
||||
self.assertTrue("This is a charter." in r.content)
|
||||
self.assertTrue(milestone.desc in r.content)
|
||||
self.assertTrue(milestone.docs.all()[0].name in r.content)
|
||||
|
||||
def test_group_about(self):
|
||||
make_test_data()
|
||||
|
@ -214,12 +244,16 @@ class GroupPagesTests(TestCase):
|
|||
state_id="active",
|
||||
)
|
||||
|
||||
url = group.about_url()
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertTrue(group.name in r.content)
|
||||
self.assertTrue(group.acronym in r.content)
|
||||
self.assertTrue(group.description in r.content)
|
||||
for url in [group.about_url(),
|
||||
urlreverse('ietf.group.info.group_about',kwargs=dict(acronym=group.acronym)),
|
||||
urlreverse('ietf.group.info.group_about',kwargs=dict(acronym=group.acronym,group_type=group.type_id)),
|
||||
]:
|
||||
url = group.about_url()
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertTrue(group.name in r.content)
|
||||
self.assertTrue(group.acronym in r.content)
|
||||
self.assertTrue(group.description in r.content)
|
||||
|
||||
def test_materials(self):
|
||||
make_test_data()
|
||||
|
@ -235,11 +269,15 @@ class GroupPagesTests(TestCase):
|
|||
doc.set_state(State.objects.get(type="slides", slug="active"))
|
||||
DocAlias.objects.create(name=doc.name, document=doc)
|
||||
|
||||
url = urlreverse("group_materials", kwargs={ 'acronym': group.acronym })
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertTrue(doc.title in r.content)
|
||||
self.assertTrue(doc.name in r.content)
|
||||
for url in [ urlreverse("group_materials", kwargs={ 'acronym': group.acronym }),
|
||||
urlreverse("group_materials", kwargs={ 'acronym': group.acronym , 'group_type': group.type_id}),
|
||||
]:
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertTrue(doc.title in r.content)
|
||||
self.assertTrue(doc.name in r.content)
|
||||
|
||||
url = urlreverse("group_materials", kwargs={ 'acronym': group.acronym })
|
||||
|
||||
# try deleting the document and check it's gone
|
||||
doc.set_state(State.objects.get(type="slides", slug="deleted"))
|
||||
|
@ -475,6 +513,19 @@ class GroupEditTests(TestCase):
|
|||
self.assertEqual(group.groupurl_set.all()[0].name, "MARS site")
|
||||
self.assertTrue(os.path.exists(os.path.join(self.charter_dir, "%s-%s.txt" % (group.charter.canonical_name(), group.charter.rev))))
|
||||
|
||||
def test_initial_charter(self):
|
||||
make_test_data()
|
||||
group = Group.objects.get(acronym="mars")
|
||||
for url in [ urlreverse('ietf.group.edit.submit_initial_charter', kwargs={'acronym':group.acronym}),
|
||||
urlreverse('ietf.group.edit.submit_initial_charter', kwargs={'acronym':group.acronym,'group_type':group.type_id}),
|
||||
]:
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
r = self.client.get(url,follow=True)
|
||||
self.assertEqual(r.status_code,200)
|
||||
self.assertTrue(r.redirect_chain[0][0].endswith(urlreverse('charter_submit',kwargs={'name':group.charter.name,'option':'initcharter'})))
|
||||
self.client.logout()
|
||||
|
||||
|
||||
def test_conclude(self):
|
||||
make_test_data()
|
||||
|
||||
|
@ -998,11 +1049,13 @@ expand-ames-chairs@virtual.ietf.org mars_chair@ietf
|
|||
def tearDown(self):
|
||||
os.unlink(self.group_alias_file.name)
|
||||
|
||||
def testNothing(self):
|
||||
url = urlreverse('ietf.group.info.email_aliases', kwargs=dict(acronym="mars"))
|
||||
r = self.client.get(url)
|
||||
self.assertTrue(all([x in r.content for x in ['mars-ads@','mars-chairs@']]))
|
||||
self.assertFalse(any([x in r.content for x in ['ames-ads@','ames-chairs@']]))
|
||||
def testEmailAliases(self):
|
||||
|
||||
for testdict in [dict(acronym="mars"),dict(acronym="mars",group_type="wg")]:
|
||||
url = urlreverse('ietf.group.info.email_aliases', kwargs=testdict)
|
||||
r = self.client.get(url)
|
||||
self.assertTrue(all([x in r.content for x in ['mars-ads@','mars-chairs@']]))
|
||||
self.assertFalse(any([x in r.content for x in ['ames-ads@','ames-chairs@']]))
|
||||
|
||||
url = urlreverse('ietf.group.info.email_aliases', kwargs=dict())
|
||||
login_testing_unauthorized(self, "plain", url)
|
||||
|
|
|
@ -1,36 +1,18 @@
|
|||
# Copyright The IETF Trust 2007, All Rights Reserved
|
||||
|
||||
from django.conf.urls import patterns
|
||||
from django.conf.urls import patterns, include
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^$', 'ietf.group.info.active_groups'),
|
||||
(r'^groupmenu.json', 'ietf.group.ajax.group_menu_data', None, "group_menu_data"),
|
||||
(r'^(?P<acronym>[a-z0-9]+).json$', 'ietf.group.ajax.group_json'),
|
||||
(r'^chartering/$', 'ietf.group.info.chartering_groups'),
|
||||
(r'^chartering/create/(?P<group_type>(wg|rg))/$', 'ietf.group.edit.edit', {'action': "charter"}, "group_create"),
|
||||
(r'^concluded/$', 'ietf.group.info.concluded_groups'),
|
||||
(r'^email-aliases/$', 'ietf.group.info.email_aliases'),
|
||||
# FIXME: the things below are duplicated in urls_info.py while we
|
||||
# figure out whether to serve everything from /group/<acronym>,
|
||||
# need to unify these at some point
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/$', 'ietf.group.info.group_home', None, "group_home"),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/documents/$', 'ietf.group.info.group_documents', None, "group_docs"),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/charter/$', 'ietf.group.info.group_about', None, 'group_charter'),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/history/$', 'ietf.group.info.history'),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/deps/dot/$', 'ietf.group.info.dependencies_dot'),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/deps/pdf/$', 'ietf.group.info.dependencies_pdf'),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/init-charter/', 'ietf.group.edit.submit_initial_charter'),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/edit/$', 'ietf.group.edit.edit', {'action': "edit"}, "group_edit"),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/conclude/$', 'ietf.group.edit.conclude'),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/milestones/$', 'ietf.group.milestones.edit_milestones', {'milestone_set': "current"}, "group_edit_milestones"),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/milestones/charter/$', 'ietf.group.milestones.edit_milestones', {'milestone_set': "charter"}, "group_edit_charter_milestones"),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/milestones/charter/reset/$', 'ietf.group.milestones.reset_charter_milestones', None, "group_reset_charter_milestones"),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/workflow/$', 'ietf.group.edit.customize_workflow'),
|
||||
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/about/(?P<group_type>.)?$', 'ietf.group.info.group_about', None, 'group_about'),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/materials/$', 'ietf.group.info.materials', None, "group_materials"),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/materials/new/$', 'ietf.doc.views_material.choose_material_type'),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/materials/new/(?P<doc_type>[\w-]+)/$', 'ietf.doc.views_material.edit_material', { 'action': "new" }, "group_new_material"),
|
||||
(r'^(?P<acronym>[A-Za-z0-9._+-]+)/email-aliases/$', 'ietf.group.info.email_aliases'),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/$', 'ietf.group.info.group_home', None, "group_home"),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/', include('ietf.group.urls_info_details')),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# Copyright The IETF Trust 2008, All Rights Reserved
|
||||
|
||||
from django.conf.urls import patterns
|
||||
from django.conf.urls import patterns, include
|
||||
from django.views.generic import RedirectView
|
||||
|
||||
from ietf.group import info, edit, milestones
|
||||
from ietf.group import info, edit
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^$', info.active_groups),
|
||||
(r'^$', info.active_groups),
|
||||
(r'^summary.txt', RedirectView.as_view(url='/wg/1wg-summary.txt')),
|
||||
(r'^summary-by-area.txt', RedirectView.as_view(url='/wg/1wg-summary.txt')),
|
||||
(r'^summary-by-acronym.txt', RedirectView.as_view(url='/wg/1wg-summary-by-acronym.txt')),
|
||||
|
@ -19,19 +19,5 @@ urlpatterns = patterns('',
|
|||
(r'^bofs/$', info.bofs),
|
||||
(r'^email-aliases/$', 'ietf.group.info.email_aliases'),
|
||||
(r'^bofs/create/$', edit.edit, {'action': "create"}, "bof_create"),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/documents/txt/$', info.group_documents_txt),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/$', info.group_home, None, "group_home"),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/documents/$', info.group_documents, None, "group_docs"),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/charter/$', info.group_about, None, 'group_charter'),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/history/$', info.history),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/deps/dot/$', info.dependencies_dot),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/deps/pdf/$', info.dependencies_pdf),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/init-charter/', edit.submit_initial_charter),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/edit/$', edit.edit, {'action': "edit"}, "group_edit"),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/conclude/$', edit.conclude),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/milestones/$', milestones.edit_milestones, {'milestone_set': "current"}, "group_edit_milestones"),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/milestones/charter/$', milestones.edit_milestones, {'milestone_set': "charter"}, "group_edit_charter_milestones"),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/milestones/charter/reset/$', milestones.reset_charter_milestones, None, "group_reset_charter_milestones"),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/workflow/$', edit.customize_workflow),
|
||||
(r'^(?P<acronym>[A-Za-z0-9._+-]+)/email-aliases/$', 'ietf.group.info.email_aliases'),
|
||||
(r'^(?P<acronym>[a-zA-Z0-9-._]+)/', include('ietf.group.urls_info_details')),
|
||||
)
|
||||
|
|
23
ietf/group/urls_info_details.py
Normal file
23
ietf/group/urls_info_details.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
from django.conf.urls import patterns
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^$', 'ietf.group.info.group_home', None, "group_home"),
|
||||
(r'^documents/txt/$', 'ietf.group.info.group_documents_txt'),
|
||||
(r'^documents/$', 'ietf.group.info.group_documents', None, "group_docs"),
|
||||
(r'^charter/$', 'ietf.group.info.group_about', None, 'group_charter'),
|
||||
(r'^about/$', 'ietf.group.info.group_about', None, 'group_about'),
|
||||
(r'^history/$','ietf.group.info.history'),
|
||||
(r'^deps/dot/$', 'ietf.group.info.dependencies_dot'),
|
||||
(r'^deps/pdf/$', 'ietf.group.info.dependencies_pdf'),
|
||||
(r'^init-charter/', 'ietf.group.edit.submit_initial_charter'),
|
||||
(r'^edit/$', 'ietf.group.edit.edit', {'action': "edit"}, "group_edit"),
|
||||
(r'^conclude/$', 'ietf.group.edit.conclude'),
|
||||
(r'^milestones/$', 'ietf.group.milestones.edit_milestones', {'milestone_set': "current"}, "group_edit_milestones"),
|
||||
(r'^milestones/charter/$', 'ietf.group.milestones.edit_milestones', {'milestone_set': "charter"}, "group_edit_charter_milestones"),
|
||||
(r'^milestones/charter/reset/$', 'ietf.group.milestones.reset_charter_milestones', None, "group_reset_charter_milestones"),
|
||||
(r'^workflow/$', 'ietf.group.edit.customize_workflow'),
|
||||
(r'^materials/$', 'ietf.group.info.materials', None, "group_materials"),
|
||||
(r'^materials/new/$', 'ietf.doc.views_material.choose_material_type'),
|
||||
(r'^materials/new/(?P<doc_type>[\w-]+)/$', 'ietf.doc.views_material.edit_material', { 'action': "new" }, "group_new_material"),
|
||||
(r'^/email-aliases/$', 'ietf.group.info.email_aliases'),
|
||||
)
|
|
@ -1,5 +1,5 @@
|
|||
{# Copyright The IETF Trust 2015, All Rights Reserved #}{% load origin %}{% origin %}
|
||||
{% load ietf_filters community_tags wg_menu streams_menu %}
|
||||
{% load ietf_filters community_tags wg_menu streams_menu active_groups_menu %}
|
||||
|
||||
{% if flavor != "top" %}
|
||||
{% include "base/menu_user.html" %}
|
||||
|
@ -14,9 +14,9 @@
|
|||
<ul class="dropdown-menu" role="menu">
|
||||
{% endif %}
|
||||
|
||||
<li><a href="{% url "ietf.group.info.active_groups" group_type="area" %}">Active areas</a></li>
|
||||
<li><a href="{% url "ietf.group.info.active_groups" group_type="wg" %}">Active WGs</a></li>
|
||||
<li><a href="{% url "ietf.group.info.active_groups" group_type="rg" %}">Active RGs</a></li>
|
||||
<li class="dropdown-submenu group-menu"><a href="{% url "ietf.group.info.active_groups" %}">Other</a>{% active_groups_menu %} </li>
|
||||
|
||||
{% if flavor == "top" %}<li class="divider visible-lg-block"></li>{% endif %}
|
||||
<li {%if flavor == "top" %}class="dropdown-header visible-lg-block"{% else %}class="nav-header hidden-nojs"{% endif %}>By area/parent</li>
|
||||
|
|
8
ietf/templates/base/menu_active_groups.html
Normal file
8
ietf/templates/base/menu_active_groups.html
Normal file
|
@ -0,0 +1,8 @@
|
|||
{# Copyright The IETF Trust 2015, All Rights Reserved #}{% load origin %}{% origin %}
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
{% for p in parents %}
|
||||
<li>
|
||||
<a href="{{ p.menu_url }}">Active {{ p.name }}s</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
45
ietf/templates/group/active_ags.html
Normal file
45
ietf/templates/group/active_ags.html
Normal file
|
@ -0,0 +1,45 @@
|
|||
{% extends "base.html" %}
|
||||
{# Copyright The IETF Trust 2015, All Rights Reserved #}
|
||||
{% load origin %}
|
||||
|
||||
{% block title %}Active Area Groups{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% origin %}
|
||||
<h1>Active Area Groups</h1>
|
||||
<table class="table table-condensed table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Team</th>
|
||||
<th>Name</th>
|
||||
<th>AD</th>
|
||||
<th>Secretaries</th>
|
||||
<th>Chairs</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for group in groups %}
|
||||
<tr>
|
||||
<td><a href="{% url "ietf.group.info.group_home" acronym=group.acronym %}">{{ group.acronym }}</a></td>
|
||||
<td>{{ group.name }}</td>
|
||||
<td>
|
||||
{% for ad in group.ads %}
|
||||
<a href="mailto:{{ ad.email.address }}">{{ ad.person.plain_name }}</a>{% if not forloop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td>
|
||||
{% for secretary in group.secretaries %}
|
||||
<a href="mailto:{{ secretary.email.address }}">{{ secretary.person.plain_name }}</a>{% if not forloop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td>
|
||||
{% for chair in group.chairs %}
|
||||
<a href="mailto:{{ chair.email.address }}">{{ chair.person.plain_name }}</a>{% if not forloop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
|
@ -12,11 +12,11 @@
|
|||
<p>When changing the area structure, the IESG can decide which members are responsible for new and changed areas, including making one sitting AD responsible for multiple areas, but the IESG can only add new members through the <a href="https://www.ietf.org/nomcom/index.html">nomcom process</a>.</p>
|
||||
<p>The primary task of area management is handled by one or two Area Directors per area. An AD may be advised by one or more directorates, which are created, selected, chaired and if necessary disbanded by the AD. Directorates may be specific to an area, specific to a technology, or chartered in some other fashion.</p>
|
||||
<p>The ADs for an area are jointly responsible for making sure the WGs in the area are well coordinated, that there is coverage for the technologies needed in the area, and that the challenges most important to the Internet in that area are indeed being worked on.</p>
|
||||
<ul><li>A full list of active working groups, sorted by area, may be found at <a href="https://datatracker.ietf.org/wg/">https://datatracker.ietf.org/wg/</a>.</li></ul>
|
||||
<ul><li>A full list of active working groups, sorted by area, may be found at <a href="{% url 'ietf.group.info.active_groups' group_type='wg'%}">{% url 'ietf.group.info.active_groups' group_type='wg' %}</a>.</li></ul>
|
||||
<p>The IESG decides which areas working groups belong to. The charter of each area is listed below.</p>
|
||||
|
||||
{% for area in areas %}
|
||||
<h2>{{area.name}} ({{area.acronym}})</h2>
|
||||
<h2><a href="{%url 'ietf.group.info.active_groups' group_type='wg'%}#{{area.acronym}}">{{area.name}} ({{area.acronym}})</a></h2>
|
||||
<pre class="pasted">{{area.description}}</pre>
|
||||
{% endfor %}
|
||||
<p>For more information about the role of the IESG in areas and working groups, please see <a href="https://www.ietf.org/rfc/rfc3710.txt">RFC 3710 ("An IESG charter")</a>, section 6 and <a href="https://www.ietf.org/rfc/rfc2418.txt">RFC 2418 ("IETF Working Group Guidelines and Procedures")</a>.</p>
|
||||
|
|
46
ietf/templates/group/active_dirs.html
Normal file
46
ietf/templates/group/active_dirs.html
Normal file
|
@ -0,0 +1,46 @@
|
|||
{% extends "base.html" %}
|
||||
{# Copyright The IETF Trust 2015, All Rights Reserved #}
|
||||
{% load origin %}
|
||||
|
||||
{% block title %}Active Directorates{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
{% origin %}
|
||||
<h1>Active Directorates</h1>
|
||||
<table class="table table-condensed table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Team</th>
|
||||
<th>Name</th>
|
||||
<th>AD</th>
|
||||
<th>Secretaries</th>
|
||||
<th>Chairs</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for group in dirs %}
|
||||
<tr>
|
||||
<td><a href="{% url "ietf.group.info.group_home" acronym=group.acronym %}">{{ group.acronym }}</a></td>
|
||||
<td>{{ group.name }}</td>
|
||||
<td>
|
||||
{% for ad in group.ads %}
|
||||
<a href="mailto:{{ ad.email.address }}">{{ ad.person.plain_name }}</a>{% if not forloop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td>
|
||||
{% for secretary in group.secretaries %}
|
||||
<a href="mailto:{{ secretary.email.address }}">{{ secretary.person.plain_name }}</a>{% if not forloop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td>
|
||||
{% for chair in group.chairs %}
|
||||
<a href="mailto:{{ chair.email.address }}">{{ chair.person.plain_name }}</a>{% if not forloop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
27
ietf/templates/group/active_groups.html
Normal file
27
ietf/templates/group/active_groups.html
Normal file
|
@ -0,0 +1,27 @@
|
|||
{% extends "base.html" %}
|
||||
{# Copyright The IETF Trust 2015, All Rights Reserved #}
|
||||
{% load origin %}
|
||||
|
||||
{% block title %}Active Groups{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% origin %}
|
||||
<h1>Active Groups</h1>
|
||||
<table class="table table-condensed table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Type</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for typename in grouptypes %}
|
||||
<tr>
|
||||
<td><a href="{% url "ietf.group.info.active_groups" group_type=typename.slug%}">{{ typename.name }}</a></td>
|
||||
<td>{{ typename.desc }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
34
ietf/templates/group/active_teams.html
Normal file
34
ietf/templates/group/active_teams.html
Normal file
|
@ -0,0 +1,34 @@
|
|||
{% extends "base.html" %}
|
||||
{# Copyright The IETF Trust 2015, All Rights Reserved #}
|
||||
{% load origin %}
|
||||
|
||||
{% block title %}Active Teams{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
{% origin %}
|
||||
<h1>Active Teams</h1>
|
||||
<table class="table table-condensed table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Team</th>
|
||||
<th>Name</th>
|
||||
<th>Chairs</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for group in teams %}
|
||||
<tr>
|
||||
<td><a href="{% url "ietf.group.info.group_home" acronym=group.acronym %}">{{ group.acronym }}</a></td>
|
||||
<td>{{ group.name }}</td>
|
||||
<td>
|
||||
{% for chair in group.chairs %}
|
||||
<a href="mailto:{{ chair.email.address }}">{{ chair.person.plain_name }}</a>{% if not forloop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
|
@ -54,7 +54,7 @@ urlpatterns = patterns('',
|
|||
(r'^sync/', include('ietf.sync.urls')),
|
||||
(r'^stream/', include('ietf.group.urls_stream')),
|
||||
(r'^templates/', include('ietf.dbtemplate.urls')),
|
||||
(r'^(?P<group_type>(wg|rg|area))/', include('ietf.group.urls_info')),
|
||||
(r'^(?P<group_type>(wg|rg|ag|team|dir|area))/', include('ietf.group.urls_info')),
|
||||
|
||||
# Redirects
|
||||
(r'^(?P<path>public)/', include('ietf.redirects.urls')),
|
||||
|
|
Loading…
Reference in a new issue