ci: merge main to release
This commit is contained in:
commit
dfe06e8074
|
@ -8,7 +8,7 @@ const octokit = new Octokit({
|
|||
|
||||
const oldestDate = DateTime.utc().minus({ days: 7 })
|
||||
|
||||
for (const pkgName of ['datatracker-db', 'datatracker-db-pg']) {
|
||||
for (const pkgName of ['datatracker-db']) {
|
||||
let hasMore = true
|
||||
let currentPage = 1
|
||||
|
||||
|
|
|
@ -828,7 +828,7 @@ Man Expires September 22, 2015 [Page 3]
|
|||
stream_id=draft.stream_id, group_id=draft.group_id, abstract=draft.abstract,stream=draft.stream, rev=draft.rev,
|
||||
pages=draft.pages, intended_std_level_id=draft.intended_std_level_id,
|
||||
shepherd_id=draft.shepherd_id, ad_id=draft.ad_id, expires=draft.expires,
|
||||
notify=draft.notify, note=draft.note)
|
||||
notify=draft.notify)
|
||||
rel = RelatedDocument.objects.create(source=replacement,
|
||||
target=draft.docalias.get(name__startswith="draft"),
|
||||
relationship_id="replaces")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright The IETF Trust 2011-2020, All Rights Reserved
|
||||
# Copyright The IETF Trust 2011-2023, All Rights Reserved
|
||||
|
||||
|
||||
import datetime
|
||||
|
@ -817,6 +817,19 @@ class EditCharterTests(TestCase):
|
|||
self.assertEqual(group.groupmilestone_set.filter(state="active", desc=m1.desc).count(), 1)
|
||||
self.assertEqual(group.groupmilestone_set.filter(state="active", desc=m4.desc).count(), 1)
|
||||
|
||||
def test_approve_irtf(self):
|
||||
charter = CharterFactory(group__type_id='rg')
|
||||
url = urlreverse('ietf.doc.views_charter.approve', kwargs=dict(name=charter.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
empty_outbox()
|
||||
r = self.client.post(url, dict())
|
||||
self.assertEqual(r.status_code, 302)
|
||||
self.assertEqual(len(outbox), 2)
|
||||
self.assertTrue("IRTF" in outbox[1]['From'])
|
||||
self.assertTrue("irtf-announce" in outbox[1]['To'])
|
||||
self.assertTrue(charter.group.acronym in outbox[1]['Cc'])
|
||||
self.assertTrue("RG Action" in outbox[1]['Subject'])
|
||||
|
||||
def test_charter_with_milestones(self):
|
||||
charter = CharterFactory()
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright The IETF Trust 2012-2020, All Rights Reserved
|
||||
# Copyright The IETF Trust 2012-2023, All Rights Reserved
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
|
@ -13,8 +13,8 @@ from django.urls import reverse as urlreverse
|
|||
|
||||
import debug # pyflakes:ignore
|
||||
|
||||
from ietf.doc.factories import IndividualDraftFactory, ConflictReviewFactory
|
||||
from ietf.doc.models import Document, DocEvent, NewRevisionDocEvent, BallotPositionDocEvent, TelechatDocEvent, State
|
||||
from ietf.doc.factories import IndividualDraftFactory, ConflictReviewFactory, RgDraftFactory
|
||||
from ietf.doc.models import Document, DocEvent, NewRevisionDocEvent, BallotPositionDocEvent, TelechatDocEvent, State, DocTagName
|
||||
from ietf.doc.utils import create_ballot_if_not_open
|
||||
from ietf.doc.views_conflict_review import default_approval_text
|
||||
from ietf.group.models import Person
|
||||
|
@ -168,6 +168,21 @@ class ConflictReviewTests(TestCase):
|
|||
self.assertTrue(review_doc.active_ballot())
|
||||
self.assertEqual(review_doc.latest_event(BallotPositionDocEvent, type="changed_ballot_position").pos_id,'yes')
|
||||
|
||||
# try to change to an AD-forbidden state
|
||||
appr_noprob_sent_pk = str(State.objects.get(used=True, slug='appr-noprob-sent',type__slug='conflrev').pk)
|
||||
r = self.client.post(url,dict(review_state=appr_noprob_sent_pk,comment='xyzzy'))
|
||||
self.assertEqual(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertTrue(q('form .invalid-feedback'))
|
||||
|
||||
# try again as secretariat
|
||||
self.client.logout()
|
||||
login_testing_unauthorized(self, 'secretary', url)
|
||||
r = self.client.post(url,dict(review_state=appr_noprob_sent_pk,comment='xyzzy'))
|
||||
self.assertEqual(r.status_code, 302)
|
||||
review_doc = Document.objects.get(name='conflict-review-imaginary-irtf-submission')
|
||||
self.assertEqual(review_doc.get_state('conflrev').slug, 'appr-noprob-sent')
|
||||
|
||||
|
||||
def test_edit_notices(self):
|
||||
doc = Document.objects.get(name='conflict-review-imaginary-irtf-submission')
|
||||
|
@ -450,3 +465,65 @@ class ConflictReviewSubmitTests(TestCase):
|
|||
def setUp(self):
|
||||
super().setUp()
|
||||
ConflictReviewFactory(name='conflict-review-imaginary-irtf-submission',review_of=IndividualDraftFactory(name='draft-imaginary-irtf-submission',stream_id='irtf'),notify='notifyme@example.net')
|
||||
|
||||
class ConflictReviewIrtfStateTests(TestCase):
|
||||
|
||||
def start_review(self, role, kwargs=None):
|
||||
doc = RgDraftFactory()
|
||||
url = urlreverse('ietf.doc.views_conflict_review.start_review', kwargs=dict(name=doc.name))
|
||||
login_testing_unauthorized(self, role, url)
|
||||
|
||||
r = self.client.post(url, kwargs)
|
||||
self.assertEqual(r.status_code, 302)
|
||||
self.assertEqual(doc.get_state('draft-stream-irtf').slug, 'iesg-rev')
|
||||
|
||||
def test_start_review_as_secretary(self):
|
||||
ad_strpk = str(Person.objects.get(name='Areað Irector').pk)
|
||||
state_strpk = str(State.objects.get(used=True, slug='needshep', type__slug='conflrev').pk)
|
||||
self.start_review('secretary', kwargs=dict(ad=ad_strpk, create_in_state=state_strpk))
|
||||
|
||||
def test_start_review_as_stream_owner(self):
|
||||
self.start_review('irtf-chair')
|
||||
|
||||
def close_review(self, close_type, role):
|
||||
doc = RgDraftFactory()
|
||||
review = ConflictReviewFactory(review_of=doc)
|
||||
url = urlreverse('ietf.doc.views_conflict_review.change_state', kwargs=dict(name=review.name))
|
||||
login_testing_unauthorized(self, role, url)
|
||||
|
||||
strpk = str(State.objects.get(used=True, slug=close_type, type__slug='conflrev').pk)
|
||||
r = self.client.post(url, dict(review_state=strpk))
|
||||
self.assertEqual(r.status_code, 302)
|
||||
self.assertEqual(doc.get_state('draft-stream-irtf').slug, 'chair-w')
|
||||
self.assertIn(DocTagName.objects.get(pk='iesg-com'), doc.tags.all())
|
||||
|
||||
def test_close_review_reqnopub_as_secretary(self):
|
||||
self.close_review('appr-reqnopub-sent', 'secretary')
|
||||
|
||||
def test_close_review_noprob_as_secretary(self):
|
||||
self.close_review('appr-noprob-sent', 'secretary')
|
||||
|
||||
def test_close_review_withdraw_as_secretary(self):
|
||||
self.close_review('withdraw', 'secretary')
|
||||
|
||||
def test_close_review_dead_as_secretary(self):
|
||||
self.close_review('dead', 'secretary')
|
||||
|
||||
def test_close_review_withdraw_as_ad(self):
|
||||
self.close_review('withdraw', 'ad')
|
||||
|
||||
def test_close_review_dead_as_ad(self):
|
||||
self.close_review('dead', 'ad')
|
||||
|
||||
def test_approve_review(self):
|
||||
doc = RgDraftFactory()
|
||||
review = ConflictReviewFactory(review_of=doc)
|
||||
review.set_state(State.objects.get(used=True, slug='appr-noprob-pend', type='conflrev'))
|
||||
|
||||
url = urlreverse('ietf.doc.views_conflict_review.approve_conflict_review', kwargs=dict(name=review.name))
|
||||
login_testing_unauthorized(self, 'secretary', url)
|
||||
|
||||
r = self.client.post(url, dict(announcement_text=default_approval_text(review)))
|
||||
self.assertEqual(r.status_code, 302)
|
||||
self.assertEqual(doc.get_state('draft-stream-irtf').slug, 'chair-w')
|
||||
self.assertIn(DocTagName.objects.get(pk='iesg-com'), doc.tags.all())
|
||||
|
|
|
@ -98,7 +98,7 @@ class ChangeStateTests(TestCase):
|
|||
draft.action_holders.add(ad)
|
||||
|
||||
url = urlreverse('ietf.doc.views_draft.change_state', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
login_testing_unauthorized(self, "ad", url)
|
||||
|
||||
first_state = draft.get_state("draft-iesg")
|
||||
next_states = first_state.next_states.all()
|
||||
|
@ -154,6 +154,20 @@ class ChangeStateTests(TestCase):
|
|||
q = PyQuery(r.content)
|
||||
self.assertEqual(len(q('form [type=submit]:contains("%s")' % first_state.name)), 1)
|
||||
|
||||
# try to change to an AD-forbidden state
|
||||
r = self.client.post(url, dict(state=State.objects.get(used=True, type='draft-iesg', slug='ann').pk, comment='Test comment'))
|
||||
self.assertEqual(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertTrue(q('form .invalid-feedback'))
|
||||
|
||||
# try again as secretariat
|
||||
self.client.logout()
|
||||
login_testing_unauthorized(self, 'secretary', url)
|
||||
r = self.client.post(url, dict(state=State.objects.get(used=True, type='draft-iesg', slug='ann').pk, comment='Test comment'))
|
||||
self.assertEqual(r.status_code, 302)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEqual(draft.get_state_slug('draft-iesg'), 'ann')
|
||||
|
||||
def test_pull_from_rfc_queue(self):
|
||||
ad = Person.objects.get(user__username="ad")
|
||||
draft = WgDraftFactory(
|
||||
|
@ -362,16 +376,14 @@ class EditInfoTests(TestCase):
|
|||
stream=draft.stream_id,
|
||||
ad=str(new_ad.pk),
|
||||
notify="test@example.com",
|
||||
note="New note",
|
||||
telechat_date="",
|
||||
))
|
||||
self.assertEqual(r.status_code, 302)
|
||||
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEqual(draft.ad, new_ad)
|
||||
self.assertEqual(draft.note, "New note")
|
||||
self.assertTrue(not draft.latest_event(TelechatDocEvent, type="scheduled_for_telechat"))
|
||||
self.assertEqual(draft.docevent_set.count(), events_before + 3)
|
||||
self.assertEqual(draft.docevent_set.count(), events_before + 2)
|
||||
self.assertEqual(len(outbox), mailbox_before + 1)
|
||||
self.assertTrue(draft.name in outbox[-1]['Subject'])
|
||||
|
||||
|
@ -386,7 +398,6 @@ class EditInfoTests(TestCase):
|
|||
stream=draft.stream_id,
|
||||
ad=str(draft.ad_id),
|
||||
notify=draft.notify,
|
||||
note="",
|
||||
)
|
||||
|
||||
# get
|
||||
|
@ -489,7 +500,6 @@ class EditInfoTests(TestCase):
|
|||
ad=ad.pk,
|
||||
create_in_state=State.objects.get(used=True, type="draft-iesg", slug="watching").pk,
|
||||
notify="test@example.com",
|
||||
note="This is a note",
|
||||
telechat_date="",
|
||||
))
|
||||
self.assertEqual(r.status_code, 302)
|
||||
|
@ -497,12 +507,11 @@ class EditInfoTests(TestCase):
|
|||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEqual(draft.get_state_slug("draft-iesg"), "watching")
|
||||
self.assertEqual(draft.ad, ad)
|
||||
self.assertEqual(draft.note, "This is a note")
|
||||
self.assertTrue(not draft.latest_event(TelechatDocEvent, type="scheduled_for_telechat"))
|
||||
self.assertEqual(draft.docevent_set.count(), events_before + 5)
|
||||
self.assertEqual(draft.docevent_set.count(), events_before + 4)
|
||||
self.assertCountEqual(draft.action_holders.all(), [draft.ad])
|
||||
events = list(draft.docevent_set.order_by('time', 'id'))
|
||||
self.assertEqual(events[-5].type, "started_iesg_process")
|
||||
self.assertEqual(events[-4].type, "started_iesg_process")
|
||||
self.assertEqual(len(outbox), mailbox_before+1)
|
||||
self.assertTrue('IESG processing' in outbox[-1]['Subject'])
|
||||
self.assertTrue('draft-ietf-mars-test2@' in outbox[-1]['To'])
|
||||
|
@ -518,7 +527,6 @@ class EditInfoTests(TestCase):
|
|||
ad=ad.pk,
|
||||
create_in_state=State.objects.get(used=True, type="draft-iesg", slug="pub-req").pk,
|
||||
notify="test@example.com",
|
||||
note="This is a note",
|
||||
telechat_date="",
|
||||
))
|
||||
self.assertEqual(r.status_code, 302)
|
||||
|
@ -1043,23 +1051,6 @@ class IndividualInfoFormsTests(TestCase):
|
|||
doc = Document.objects.get(name=self.docname)
|
||||
self.assertEqual(doc.latest_event(TelechatDocEvent, "scheduled_for_telechat").telechat_date,None)
|
||||
|
||||
def test_doc_change_iesg_note(self):
|
||||
url = urlreverse('ietf.doc.views_draft.edit_iesg_note', kwargs=dict(name=self.docname))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# get
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code,200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEqual(len(q('[type=submit]:contains("Save")')),1)
|
||||
|
||||
# post
|
||||
r = self.client.post(url,dict(note='ZpyQFGmA\r\nZpyQFGmA'))
|
||||
self.assertEqual(r.status_code,302)
|
||||
doc = Document.objects.get(name=self.docname)
|
||||
self.assertEqual(doc.note,'ZpyQFGmA\nZpyQFGmA')
|
||||
self.assertTrue('ZpyQFGmA' in doc.latest_event(DocEvent,type='added_comment').desc)
|
||||
|
||||
def test_doc_change_ad(self):
|
||||
url = urlreverse('ietf.doc.views_draft.edit_ad', kwargs=dict(name=self.docname))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
|
|
@ -255,6 +255,7 @@ This test section has some text.
|
|||
statement.latest_event(NewRevisionDocEvent).rev, "00"
|
||||
)
|
||||
self.assertIsNotNone(statement.latest_event(type="published_statement"))
|
||||
self.assertIsNotNone(statement.history_set.last().latest_event(type="published_statement"))
|
||||
if postdict["statement_submission"] == "enter":
|
||||
self.assertEqual(statement.text_or_error(), "some stuff")
|
||||
else:
|
||||
|
|
|
@ -147,6 +147,21 @@ class StatusChangeTests(TestCase):
|
|||
self.assertTrue(doc.active_ballot())
|
||||
self.assertEqual(doc.latest_event(BallotPositionDocEvent, type="changed_ballot_position").pos_id,'yes')
|
||||
|
||||
# try to change to an AD-forbidden state
|
||||
appr_sent_pk = str(State.objects.get(used=True, slug='appr-sent',type__slug='statchg').pk)
|
||||
r = self.client.post(url, dict(new_state=appr_sent_pk, comment='xyzzy'))
|
||||
self.assertEqual(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertTrue(q('form .invalid-feedback'))
|
||||
|
||||
# try again as secretariat
|
||||
self.client.logout()
|
||||
login_testing_unauthorized(self, 'secretary', url)
|
||||
r = self.client.post(url, dict(new_state=appr_sent_pk, comment='xyzzy'))
|
||||
self.assertEqual(r.status_code, 302)
|
||||
doc = Document.objects.get(name='status-change-imaginary-mid-review')
|
||||
self.assertEqual(doc.get_state('statchg').slug, 'appr-sent')
|
||||
|
||||
def test_edit_notices(self):
|
||||
doc = Document.objects.get(name='status-change-imaginary-mid-review')
|
||||
url = urlreverse('ietf.doc.views_doc.edit_notify;status-change',kwargs=dict(name=doc.name))
|
||||
|
|
|
@ -134,7 +134,6 @@ urlpatterns = [
|
|||
url(r'^%(name)s/edit/suggested-replaces/$' % settings.URL_REGEXPS, views_draft.review_possibly_replaces),
|
||||
url(r'^%(name)s/edit/status/$' % settings.URL_REGEXPS, views_draft.change_intention),
|
||||
url(r'^%(name)s/edit/telechat/$' % settings.URL_REGEXPS, views_doc.telechat_date),
|
||||
url(r'^%(name)s/edit/iesgnote/$' % settings.URL_REGEXPS, views_draft.edit_iesg_note),
|
||||
url(r'^%(name)s/edit/ad/$' % settings.URL_REGEXPS, views_draft.edit_ad),
|
||||
url(r'^%(name)s/edit/authors/$' % settings.URL_REGEXPS, views_doc.edit_authors),
|
||||
url(r'^%(name)s/edit/consensus/$' % settings.URL_REGEXPS, views_draft.edit_consensus),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright The IETF Trust 2012-2020, All Rights Reserved
|
||||
# Copyright The IETF Trust 2012-2023, All Rights Reserved
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
|
@ -25,6 +25,7 @@ from ietf.doc.forms import AdForm
|
|||
from ietf.group.models import Role, Group
|
||||
from ietf.iesg.models import TelechatDate
|
||||
from ietf.ietfauth.utils import has_role, role_required, is_authorized_in_doc_stream
|
||||
from ietf.name.models import DocTagName
|
||||
from ietf.person.models import Person
|
||||
from ietf.utils import log
|
||||
from ietf.utils.mail import send_mail_preformatted
|
||||
|
@ -35,6 +36,12 @@ class ChangeStateForm(forms.Form):
|
|||
review_state = forms.ModelChoiceField(State.objects.filter(used=True, type="conflrev"), label="Conflict review state", empty_label=None, required=True)
|
||||
comment = forms.CharField(widget=forms.Textarea, help_text="Optional comment for the review history.", required=False, strip=False)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
user = kwargs.pop("user")
|
||||
super(ChangeStateForm, self).__init__(*args, **kwargs)
|
||||
if not has_role(user, "Secretariat"):
|
||||
self.fields["review_state"].queryset = self.fields["review_state"].queryset.exclude(slug__in=("appr-reqnopub-sent","appr-noprob-sent"))
|
||||
|
||||
@role_required("Area Director", "Secretariat")
|
||||
def change_state(request, name, option=None):
|
||||
"""Change state of an IESG review for IETF conflicts in other stream's documents, notifying parties as necessary
|
||||
|
@ -44,7 +51,7 @@ def change_state(request, name, option=None):
|
|||
login = request.user.person
|
||||
|
||||
if request.method == 'POST':
|
||||
form = ChangeStateForm(request.POST)
|
||||
form = ChangeStateForm(request.POST, user=request.user)
|
||||
if form.is_valid():
|
||||
clean = form.cleaned_data
|
||||
new_state = clean['review_state']
|
||||
|
@ -90,12 +97,16 @@ def change_state(request, name, option=None):
|
|||
review,
|
||||
ok_to_publish)
|
||||
|
||||
if new_state.slug in ["appr-reqnopub-sent", "appr-noprob-sent", "withdraw", "dead"]:
|
||||
doc = review.related_that_doc("conflrev")[0].document
|
||||
if doc.stream_id == "irtf":
|
||||
close_review_irtf_state(doc, login)
|
||||
|
||||
return redirect('ietf.doc.views_doc.document_main', name=review.name)
|
||||
else:
|
||||
s = review.get_state()
|
||||
init = dict(review_state=s.pk if s else None)
|
||||
form = ChangeStateForm(initial=init)
|
||||
form = ChangeStateForm(initial=init, user=request.user)
|
||||
|
||||
return render(request, 'doc/change_state.html',
|
||||
dict(form=form,
|
||||
|
@ -355,6 +366,10 @@ def approve_conflict_review(request, name):
|
|||
c.desc = "The following approval message was sent\n"+form.cleaned_data['announcement_text']
|
||||
c.save()
|
||||
|
||||
doc = review.related_that_doc("conflrev")[0].document
|
||||
if doc.stream_id == "irtf":
|
||||
close_review_irtf_state(doc, login)
|
||||
|
||||
return HttpResponseRedirect(review.get_absolute_url())
|
||||
|
||||
else:
|
||||
|
@ -488,6 +503,9 @@ def start_review_as_secretariat(request, name):
|
|||
|
||||
send_conflict_review_started_email(request, conflict_review)
|
||||
|
||||
if doc_to_review.stream_id == 'irtf':
|
||||
start_review_irtf_state(doc_to_review, login)
|
||||
|
||||
return HttpResponseRedirect(conflict_review.get_absolute_url())
|
||||
else:
|
||||
notify_addresses = build_notify_addresses(doc_to_review)
|
||||
|
@ -522,6 +540,9 @@ def start_review_as_stream_owner(request, name):
|
|||
|
||||
send_conflict_review_started_email(request, conflict_review)
|
||||
|
||||
if doc_to_review.stream_id == 'irtf':
|
||||
start_review_irtf_state(doc_to_review, login)
|
||||
|
||||
return HttpResponseRedirect(conflict_review.get_absolute_url())
|
||||
else:
|
||||
notify_addresses = build_notify_addresses(doc_to_review)
|
||||
|
@ -536,3 +557,26 @@ def start_review_as_stream_owner(request, name):
|
|||
'doc_to_review': doc_to_review,
|
||||
},
|
||||
)
|
||||
|
||||
def start_review_irtf_state(doc, by):
|
||||
prev_state = doc.get_state('draft-stream-irtf')
|
||||
new_state = State.objects.get(type_id='draft-stream-irtf', slug='iesg-rev')
|
||||
|
||||
if new_state != prev_state:
|
||||
doc.set_state(new_state)
|
||||
events = []
|
||||
events.append(add_state_change_event(doc, by, prev_state, new_state))
|
||||
doc.save_with_history(events)
|
||||
|
||||
def close_review_irtf_state(doc, by):
|
||||
prev_state = doc.get_state("draft-stream-irtf")
|
||||
new_state = State.objects.get(type_id="draft-stream-irtf", slug="chair-w")
|
||||
prev_tags = set(doc.tags.all())
|
||||
new_tags = set(DocTagName.objects.filter(pk="iesg-com"))
|
||||
|
||||
if new_state != prev_state:
|
||||
doc.set_state(new_state)
|
||||
doc.tags.clear()
|
||||
doc.tags.set(new_tags)
|
||||
events = [add_state_change_event(doc, by, prev_state, new_state, prev_tags, new_tags)]
|
||||
doc.save_with_history(events)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright The IETF Trust 2010-2020, All Rights Reserved
|
||||
# Copyright The IETF Trust 2010-2023, All Rights Reserved
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
|
@ -61,6 +61,12 @@ class ChangeStateForm(forms.Form):
|
|||
substate = forms.ModelChoiceField(DocTagName.objects.filter(slug__in=IESG_SUBSTATE_TAGS), required=False)
|
||||
comment = forms.CharField(widget=forms.Textarea, required=False, strip=False)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
user = kwargs.pop("user")
|
||||
super(ChangeStateForm, self).__init__(*args, **kwargs)
|
||||
if not has_role(user, "Secretariat"):
|
||||
self.fields["state"].queryset = self.fields["state"].queryset.exclude(slug="ann")
|
||||
|
||||
def clean(self):
|
||||
retclean = self.cleaned_data
|
||||
state = self.cleaned_data.get('state', '(None)')
|
||||
|
@ -94,7 +100,7 @@ def change_state(request, name):
|
|||
login = request.user.person
|
||||
|
||||
if request.method == 'POST':
|
||||
form = ChangeStateForm(request.POST)
|
||||
form = ChangeStateForm(request.POST, user=request.user)
|
||||
form.docname=name
|
||||
|
||||
if form.is_valid():
|
||||
|
@ -175,7 +181,8 @@ def change_state(request, name):
|
|||
state = doc.get_state("draft-iesg")
|
||||
t = doc.tags.filter(slug__in=IESG_SUBSTATE_TAGS)
|
||||
form = ChangeStateForm(initial=dict(state=state.pk if state else None,
|
||||
substate=t[0].pk if t else None))
|
||||
substate=t[0].pk if t else None),
|
||||
user=request.user)
|
||||
form.docname=name
|
||||
|
||||
state = doc.get_state("draft-iesg")
|
||||
|
@ -491,7 +498,6 @@ class EditInfoForm(forms.Form):
|
|||
help_text="Separate email addresses with commas.",
|
||||
required=False,
|
||||
)
|
||||
note = forms.CharField(widget=forms.Textarea, label="IESG note", required=False, strip=False)
|
||||
telechat_date = forms.TypedChoiceField(coerce=lambda x: datetime.datetime.strptime(x, '%Y-%m-%d').date(), empty_value=None, required=False, widget=forms.Select(attrs={'onchange':'make_bold()'}))
|
||||
returning_item = forms.BooleanField(required=False)
|
||||
|
||||
|
@ -515,9 +521,6 @@ class EditInfoForm(forms.Form):
|
|||
# returning item is rendered non-standard
|
||||
self.standard_fields = [x for x in self.visible_fields() if x.name not in ('returning_item',)]
|
||||
|
||||
def clean_note(self):
|
||||
return self.cleaned_data['note'].replace('\r', '').strip()
|
||||
|
||||
def to_iesg(request,name):
|
||||
""" Submit an IETF stream document to the IESG for publication """
|
||||
doc = get_object_or_404(Document, docalias__name=name, stream='ietf')
|
||||
|
@ -715,18 +718,6 @@ def edit_info(request, name):
|
|||
diff('ad', "Responsible AD")
|
||||
diff('notify', "State Change Notice email list")
|
||||
|
||||
if r['note'] != doc.note:
|
||||
if not r['note']:
|
||||
if doc.note:
|
||||
changes.append("Note field has been cleared")
|
||||
else:
|
||||
if doc.note:
|
||||
changes.append("Note changed to '%s'" % r['note'])
|
||||
else:
|
||||
changes.append("Note added '%s'" % r['note'])
|
||||
|
||||
doc.note = r['note']
|
||||
|
||||
if doc.group.type_id in ("individ", "area"):
|
||||
if not r["area"]:
|
||||
r["area"] = Group.objects.get(type="individ")
|
||||
|
@ -769,7 +760,6 @@ def edit_info(request, name):
|
|||
area=doc.group_id,
|
||||
ad=doc.ad_id,
|
||||
notify=doc.notify,
|
||||
note=doc.note,
|
||||
telechat_date=initial_telechat_date,
|
||||
returning_item=initial_returning_item,
|
||||
)
|
||||
|
@ -862,52 +852,6 @@ def restore_draft_file(request, draft):
|
|||
log.log(" Exception %s when attempting to move %s" % (ex, file))
|
||||
|
||||
|
||||
class IESGNoteForm(forms.Form):
|
||||
note = forms.CharField(widget=forms.Textarea, label="IESG note", required=False, strip=False)
|
||||
|
||||
def clean_note(self):
|
||||
# not munging the database content to use html line breaks --
|
||||
# that has caused a lot of pain in the past.
|
||||
return self.cleaned_data['note'].replace('\r', '').strip()
|
||||
|
||||
@role_required("Area Director", "Secretariat")
|
||||
def edit_iesg_note(request, name):
|
||||
doc = get_object_or_404(Document, type="draft", name=name)
|
||||
login = request.user.person
|
||||
|
||||
initial = dict(note=doc.note)
|
||||
|
||||
if request.method == "POST":
|
||||
form = IESGNoteForm(request.POST, initial=initial)
|
||||
|
||||
if form.is_valid():
|
||||
new_note = form.cleaned_data['note']
|
||||
if new_note != doc.note:
|
||||
if not new_note:
|
||||
if doc.note:
|
||||
log_message = "Note field has been cleared"
|
||||
else:
|
||||
if doc.note:
|
||||
log_message = "Note changed to '%s'" % new_note
|
||||
else:
|
||||
log_message = "Note added '%s'" % new_note
|
||||
|
||||
c = DocEvent(type="added_comment", doc=doc, rev=doc.rev, by=login)
|
||||
c.desc = log_message
|
||||
c.save()
|
||||
|
||||
doc.note = new_note
|
||||
doc.save_with_history([c])
|
||||
|
||||
return redirect('ietf.doc.views_doc.document_main', name=doc.name)
|
||||
else:
|
||||
form = IESGNoteForm(initial=initial)
|
||||
|
||||
return render(request, 'doc/draft/edit_iesg_note.html',
|
||||
dict(doc=doc,
|
||||
form=form,
|
||||
))
|
||||
|
||||
class ShepherdWriteupUploadForm(forms.Form):
|
||||
content = forms.CharField(widget=forms.Textarea, label="Shepherd writeup", help_text="Edit the shepherd writeup.", required=False, strip=False)
|
||||
txt = forms.FileField(label=".txt format", help_text="Or upload a .txt file.", required=False)
|
||||
|
|
|
@ -239,6 +239,7 @@ def new_statement(request):
|
|||
rev=statement.rev,
|
||||
by=request.user.person,
|
||||
desc="Statement published",
|
||||
time=statement.time,
|
||||
)
|
||||
statement.save_with_history([e1, e2])
|
||||
alias = DocAlias.objects.create(name=name)
|
||||
|
|
|
@ -42,6 +42,12 @@ class ChangeStateForm(forms.Form):
|
|||
new_state = forms.ModelChoiceField(State.objects.filter(type="statchg", used=True), label="Status Change Evaluation State", empty_label=None, required=True)
|
||||
comment = forms.CharField(widget=forms.Textarea, help_text="Optional comment for the review history.", required=False, strip=False)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
user = kwargs.pop("user")
|
||||
super(ChangeStateForm, self).__init__(*args, **kwargs)
|
||||
if not has_role(user, "Secretariat"):
|
||||
self.fields["new_state"].queryset = self.fields["new_state"].queryset.exclude(slug="appr-sent")
|
||||
|
||||
|
||||
@role_required("Area Director", "Secretariat")
|
||||
def change_state(request, name, option=None):
|
||||
|
@ -52,7 +58,7 @@ def change_state(request, name, option=None):
|
|||
login = request.user.person
|
||||
|
||||
if request.method == 'POST':
|
||||
form = ChangeStateForm(request.POST)
|
||||
form = ChangeStateForm(request.POST, user=request.user)
|
||||
if form.is_valid():
|
||||
clean = form.cleaned_data
|
||||
new_state = clean['new_state']
|
||||
|
@ -116,7 +122,7 @@ def change_state(request, name, option=None):
|
|||
type='statchg',
|
||||
label='Status Change Evaluation State',
|
||||
)
|
||||
form = ChangeStateForm(initial=init)
|
||||
form = ChangeStateForm(initial=init, user=request.user)
|
||||
|
||||
return render(request, 'doc/change_state.html',
|
||||
dict(form=form,
|
||||
|
|
|
@ -27,7 +27,7 @@ class GroupFactory(factory.django.DjangoModelFactory):
|
|||
django_get_or_create = ('acronym',)
|
||||
skip_postgeneration_save = True
|
||||
|
||||
name = factory.Faker('sentence',nb_words=6)
|
||||
name = factory.Faker('text', max_nb_chars=80)
|
||||
acronym = factory.Sequence(lambda n: 'acronym%d' %n)
|
||||
state_id = 'active'
|
||||
type_id = 'wg'
|
||||
|
|
|
@ -142,8 +142,6 @@ def agenda_json(request, date=None):
|
|||
'ad':doc.ad.name if doc.ad else None,
|
||||
}
|
||||
|
||||
if doc.note:
|
||||
docinfo['note'] = doc.note
|
||||
defer = doc.active_defer_event()
|
||||
if defer:
|
||||
docinfo['defer-by'] = defer.by.name
|
||||
|
|
|
@ -109,7 +109,9 @@ class DraftForm(forms.ModelForm):
|
|||
cleaned_data = super().clean()
|
||||
revisions = cleaned_data.get("revisions")
|
||||
document = cleaned_data.get("document")
|
||||
if not document.name.startswith("rfc"):
|
||||
if not document:
|
||||
self.add_error("document", "Identifying the Internet-Draft or RFC for this disclosure is required.")
|
||||
elif not document.name.startswith("rfc"):
|
||||
if revisions.strip() == "":
|
||||
self.add_error("revisions", "Revisions of this Internet-Draft for which this disclosure is relevant must be specified.")
|
||||
return cleaned_data
|
||||
|
|
26
ietf/mailtrigger/migrations/0003_ballot_approved_charter.py
Normal file
26
ietf/mailtrigger/migrations/0003_ballot_approved_charter.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright The IETF Trust 2023, All Rights Reserved
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
def forward(apps, schema_editor):
|
||||
MailTrigger = apps.get_model("mailtrigger", "MailTrigger")
|
||||
Recipient = apps.get_model("mailtrigger", "Recipient")
|
||||
mt = MailTrigger.objects.get(pk="ballot_approved_charter")
|
||||
mt.to.remove(mt.to.first())
|
||||
mt.to.add(Recipient.objects.get(slug="group_stream_announce"))
|
||||
|
||||
def reverse(apps, schema_editor):
|
||||
MailTrigger = apps.get_model("mailtrigger", "MailTrigger")
|
||||
Recipient = apps.get_model("mailtrigger", "Recipient")
|
||||
mt = MailTrigger.objects.get(pk="ballot_approved_charter")
|
||||
mt.to.remove(mt.to.first())
|
||||
mt.to.add(Recipient.objects.get(slug="ietf_announce"))
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("mailtrigger", "0002_slidesubmitter"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(forward, reverse)
|
||||
]
|
|
@ -3770,7 +3770,7 @@
|
|||
],
|
||||
"desc": "Recipients when a charter is approved",
|
||||
"to": [
|
||||
"ietf_announce"
|
||||
"group_stream_announce"
|
||||
]
|
||||
},
|
||||
"model": "mailtrigger.mailtrigger",
|
||||
|
|
|
@ -2419,6 +2419,7 @@ class rfc8713EligibilityTests(TestCase):
|
|||
self.eligible_people = list()
|
||||
self.ineligible_people = list()
|
||||
|
||||
# Section 4.14 qualification criteria
|
||||
for combo_len in range(0,6):
|
||||
for combo in combinations(meetings,combo_len):
|
||||
p = PersonFactory()
|
||||
|
@ -2429,6 +2430,18 @@ class rfc8713EligibilityTests(TestCase):
|
|||
else:
|
||||
self.eligible_people.append(p)
|
||||
|
||||
# Section 4.15 disqualification criteria
|
||||
def ineligible_person_with_role(**kwargs):
|
||||
p = RoleFactory(**kwargs).person
|
||||
for m in meetings:
|
||||
MeetingRegistrationFactory(person=p, meeting=m, attended=True)
|
||||
self.ineligible_people.append(p)
|
||||
for group in ['isocbot', 'ietf-trust', 'llc-board', 'iab']:
|
||||
for role in ['member', 'chair']:
|
||||
ineligible_person_with_role(group__acronym=group, name_id=role)
|
||||
ineligible_person_with_role(group__type_id='area', group__state_id='active',name_id='ad')
|
||||
ineligible_person_with_role(group=self.nomcom.group, name_id='chair')
|
||||
|
||||
# No-one is eligible for the other_nomcom
|
||||
self.other_nomcom = NomComFactory(group__acronym='nomcom2018',first_call_for_volunteers=datetime.date(2018,5,1))
|
||||
|
||||
|
|
|
@ -22,8 +22,8 @@ urlpatterns = [
|
|||
url(r'^(?P<year>\d{4})/private/view-feedback/nominee/(?P<nominee_id>\d+)$', views.view_feedback_nominee),
|
||||
url(r'^(?P<year>\d{4})/private/view-feedback/topic/(?P<topic_id>\d+)$', views.view_feedback_topic),
|
||||
url(r'^(?P<year>\d{4})/private/edit/nominee/(?P<nominee_id>\d+)$', views.edit_nominee),
|
||||
url(r'^(?P<year>\d{4})/private/merge-nominee/?$', views.private_merge_nominee),
|
||||
url(r'^(?P<year>\d{4})/private/merge-person/?$', views.private_merge_person),
|
||||
url(r'^(?P<year>\d{4})/private/merge-nominee/$', views.private_merge_nominee),
|
||||
url(r'^(?P<year>\d{4})/private/merge-person/$', views.private_merge_person),
|
||||
url(r'^(?P<year>\d{4})/private/send-reminder-mail/(?P<type>\w+)/$', views.send_reminder_mail),
|
||||
url(r'^(?P<year>\d{4})/private/extract-email-lists/$', views.extract_email_lists),
|
||||
url(r'^(?P<year>\d{4})/private/edit-members/$', views.edit_members),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright The IETF Trust 2012-2022, All Rights Reserved
|
||||
# Copyright The IETF Trust 2012-2023, All Rights Reserved
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
|
@ -66,8 +66,11 @@ DEFAULT_NOMCOM_TEMPLATES = [HOME_TEMPLATE,
|
|||
]
|
||||
|
||||
# See RFC8713 section 4.15
|
||||
# This potentially over-disqualifies past nomcom chairs if some
|
||||
# nomcom 2+ nomcoms ago is still in the active state
|
||||
DISQUALIFYING_ROLE_QUERY_EXPRESSION = ( Q(group__acronym__in=['isocbot', 'ietf-trust', 'llc-board', 'iab'], name_id__in=['member', 'chair'])
|
||||
| Q(group__type_id='area', group__state='active',name_id='ad')
|
||||
| Q(group__type_id='nomcom', group__state='active', name_id='chair')
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -77,7 +77,6 @@ def year_index(request, year):
|
|||
return render(request, 'nomcom/year_index.html',
|
||||
{'nomcom': nomcom,
|
||||
'year': year,
|
||||
'selected': 'index',
|
||||
'template': template})
|
||||
|
||||
def announcements(request):
|
||||
|
@ -182,8 +181,7 @@ def private_key(request, year):
|
|||
{'nomcom': nomcom,
|
||||
'year': year,
|
||||
'back_url': back_url,
|
||||
'form': form,
|
||||
'selected': 'private_key'})
|
||||
'form': form})
|
||||
|
||||
|
||||
@role_required("Nomcom")
|
||||
|
@ -283,7 +281,6 @@ def private_index(request, year):
|
|||
'positions': positions,
|
||||
'selected_state': selected_state,
|
||||
'selected_position': selected_position and int(selected_position) or None,
|
||||
'selected': 'index',
|
||||
'is_chair': is_chair,
|
||||
'mailto': mailto,
|
||||
})
|
||||
|
@ -308,13 +305,11 @@ def send_reminder_mail(request, year, type):
|
|||
interesting_state = 'pending'
|
||||
mail_path = nomcom_template_path + NOMINEE_ACCEPT_REMINDER_TEMPLATE
|
||||
reminder_description = 'accept (or decline) a nomination'
|
||||
selected_tab = 'send_accept_reminder'
|
||||
state_description = NomineePositionStateName.objects.get(slug=interesting_state).name
|
||||
elif type=='questionnaire':
|
||||
interesting_state = 'accepted'
|
||||
mail_path = nomcom_template_path + NOMINEE_QUESTIONNAIRE_REMINDER_TEMPLATE
|
||||
reminder_description = 'complete the questionnaire for a nominated position'
|
||||
selected_tab = 'send_questionnaire_reminder'
|
||||
state_description = NomineePositionStateName.objects.get(slug=interesting_state).name+' but no questionnaire has been received'
|
||||
else:
|
||||
raise Http404
|
||||
|
@ -349,7 +344,6 @@ def send_reminder_mail(request, year, type):
|
|||
'year': year,
|
||||
'nominees': annotated_nominees,
|
||||
'mail_template': mail_template,
|
||||
'selected': selected_tab,
|
||||
'reminder_description': reminder_description,
|
||||
'state_description': state_description,
|
||||
'is_chair_task' : True,
|
||||
|
@ -376,7 +370,6 @@ def private_merge_person(request, year):
|
|||
{'nomcom': nomcom,
|
||||
'year': year,
|
||||
'form': form,
|
||||
'selected': 'merge_person',
|
||||
'is_chair_task' : True,
|
||||
})
|
||||
|
||||
|
@ -401,7 +394,6 @@ def private_merge_nominee(request, year):
|
|||
{'nomcom': nomcom,
|
||||
'year': year,
|
||||
'form': form,
|
||||
'selected': 'merge_nominee',
|
||||
'is_chair_task' : True,
|
||||
})
|
||||
|
||||
|
@ -411,8 +403,7 @@ def requirements(request, year):
|
|||
return render(request, 'nomcom/requirements.html',
|
||||
{'nomcom': nomcom,
|
||||
'positions': positions,
|
||||
'year': year,
|
||||
'selected': 'requirements'})
|
||||
'year': year})
|
||||
|
||||
|
||||
def questionnaires(request, year):
|
||||
|
@ -421,8 +412,7 @@ def questionnaires(request, year):
|
|||
return render(request, 'nomcom/questionnaires.html',
|
||||
{'nomcom': nomcom,
|
||||
'positions': positions,
|
||||
'year': year,
|
||||
'selected': 'questionnaires'})
|
||||
'year': year})
|
||||
|
||||
|
||||
@login_required
|
||||
|
@ -456,15 +446,13 @@ def nominate(request, year, public, newperson):
|
|||
messages.warning(request, "This Nomcom is not yet accepting nominations")
|
||||
return render(request, template,
|
||||
{'nomcom': nomcom,
|
||||
'year': year,
|
||||
'selected': 'nominate'})
|
||||
'year': year})
|
||||
|
||||
if nomcom.group.state_id == 'conclude':
|
||||
messages.warning(request, "Nominations to this Nomcom are closed.")
|
||||
return render(request, template,
|
||||
{'nomcom': nomcom,
|
||||
'year': year,
|
||||
'selected': 'nominate'})
|
||||
'year': year})
|
||||
|
||||
if request.method == 'POST':
|
||||
if newperson:
|
||||
|
@ -488,8 +476,7 @@ def nominate(request, year, public, newperson):
|
|||
{'form': form,
|
||||
'nomcom': nomcom,
|
||||
'year': year,
|
||||
'positions': nomcom.position_set.filter(is_open=True),
|
||||
'selected': 'nominate'})
|
||||
'positions': nomcom.position_set.filter(is_open=True)})
|
||||
|
||||
@login_required
|
||||
def public_feedback(request, year):
|
||||
|
@ -553,7 +540,6 @@ def feedback(request, year, public):
|
|||
return render(request, 'nomcom/feedback.html', {
|
||||
'nomcom': nomcom,
|
||||
'year': year,
|
||||
'selected': 'feedback',
|
||||
'counts' : counts,
|
||||
'base_template': base_template
|
||||
})
|
||||
|
@ -564,7 +550,6 @@ def feedback(request, year, public):
|
|||
'form': None,
|
||||
'nomcom': nomcom,
|
||||
'year': year,
|
||||
'selected': 'feedback',
|
||||
'positions': positions,
|
||||
'topics': topics,
|
||||
'counts' : counts,
|
||||
|
@ -578,7 +563,6 @@ def feedback(request, year, public):
|
|||
'form': None,
|
||||
'nomcom': nomcom,
|
||||
'year': year,
|
||||
'selected': 'feedback',
|
||||
'positions': positions,
|
||||
'topics': topics,
|
||||
'counts' : counts,
|
||||
|
@ -625,7 +609,6 @@ def feedback(request, year, public):
|
|||
'year': year,
|
||||
'positions': positions,
|
||||
'topics': topics,
|
||||
'selected': 'feedback',
|
||||
'counts': counts,
|
||||
'topic_counts': topic_counts,
|
||||
'base_template': base_template
|
||||
|
@ -651,7 +634,6 @@ def private_feedback_email(request, year):
|
|||
return render(request, template,
|
||||
{'nomcom': nomcom,
|
||||
'year': year,
|
||||
'selected': 'feedback_email',
|
||||
'is_chair_task' : True,
|
||||
})
|
||||
|
||||
|
@ -671,8 +653,7 @@ def private_feedback_email(request, year):
|
|||
return render(request, template,
|
||||
{'form': form,
|
||||
'nomcom': nomcom,
|
||||
'year': year,
|
||||
'selected': 'feedback_email'})
|
||||
'year': year})
|
||||
|
||||
@role_required("Nomcom Chair", "Nomcom Advisor")
|
||||
def private_questionnaire(request, year):
|
||||
|
@ -694,7 +675,6 @@ def private_questionnaire(request, year):
|
|||
return render(request, template,
|
||||
{'nomcom': nomcom,
|
||||
'year': year,
|
||||
'selected': 'questionnaire',
|
||||
'is_chair_task' : True,
|
||||
})
|
||||
|
||||
|
@ -713,8 +693,7 @@ def private_questionnaire(request, year):
|
|||
{'form': form,
|
||||
'questionnaire_response': questionnaire_response,
|
||||
'nomcom': nomcom,
|
||||
'year': year,
|
||||
'selected': 'questionnaire'})
|
||||
'year': year})
|
||||
|
||||
|
||||
def process_nomination_status(request, year, nominee_position_id, state, date, hash):
|
||||
|
@ -768,7 +747,6 @@ def process_nomination_status(request, year, nominee_position_id, state, date, h
|
|||
'nominee_position': nominee_position,
|
||||
'state': state,
|
||||
'need_confirmation': need_confirmation,
|
||||
'selected': 'feedback',
|
||||
'form': form })
|
||||
|
||||
@role_required("Nomcom")
|
||||
|
@ -833,7 +811,6 @@ def view_feedback(request, year):
|
|||
|
||||
return render(request, 'nomcom/view_feedback.html',
|
||||
{'year': year,
|
||||
'selected': 'view_feedback',
|
||||
'nominees': nominees,
|
||||
'nominee_feedback_types': nominee_feedback_types,
|
||||
'independent_feedback_types': independent_feedback_types,
|
||||
|
@ -930,7 +907,6 @@ def view_feedback_pending(request, year):
|
|||
form.set_nomcom(nomcom, request.user)
|
||||
return render(request, 'nomcom/view_feedback_pending.html',
|
||||
{'year': year,
|
||||
'selected': 'feedback_pending',
|
||||
'formset': formset,
|
||||
'extra_step': extra_step,
|
||||
'extra_ids': extra_ids,
|
||||
|
@ -1093,7 +1069,6 @@ def edit_nominee(request, year, nominee_id):
|
|||
|
||||
return render(request, 'nomcom/edit_nominee.html',
|
||||
{'year': year,
|
||||
'selected': 'index',
|
||||
'nominee': nominee,
|
||||
'form': form,
|
||||
'nomcom': nomcom,
|
||||
|
@ -1131,7 +1106,6 @@ def edit_nomcom(request, year):
|
|||
'formset': formset,
|
||||
'nomcom': nomcom,
|
||||
'year': year,
|
||||
'selected': 'edit_nomcom',
|
||||
'is_chair_task' : True,
|
||||
})
|
||||
|
||||
|
@ -1145,7 +1119,6 @@ def list_templates(request, year):
|
|||
return render(request, 'nomcom/list_templates.html',
|
||||
{'template_list': template_list,
|
||||
'year': year,
|
||||
'selected': 'edit_templates',
|
||||
'nomcom': nomcom,
|
||||
'is_chair_task' : True,
|
||||
})
|
||||
|
@ -1218,7 +1191,6 @@ def list_positions(request, year):
|
|||
return render(request, 'nomcom/list_positions.html',
|
||||
{'positions': positions,
|
||||
'year': year,
|
||||
'selected': 'edit_positions',
|
||||
'nomcom': nomcom,
|
||||
'is_chair_task' : True,
|
||||
})
|
||||
|
@ -1285,7 +1257,6 @@ def list_topics(request, year):
|
|||
return render(request, 'nomcom/list_topics.html',
|
||||
{'topics': topics,
|
||||
'year': year,
|
||||
'selected': 'edit_topics',
|
||||
'nomcom': nomcom,
|
||||
'is_chair_task' : True,
|
||||
})
|
||||
|
@ -1367,8 +1338,7 @@ def edit_members(request, year):
|
|||
return render(request, 'nomcom/new_edit_members.html',
|
||||
{'nomcom' : nomcom,
|
||||
'year' : year,
|
||||
'form': form,
|
||||
})
|
||||
'form': form})
|
||||
|
||||
@role_required("Nomcom Chair", "Nomcom Advisor")
|
||||
def extract_email_lists(request, year):
|
||||
|
@ -1388,8 +1358,7 @@ def extract_email_lists(request, year):
|
|||
'pending': pending,
|
||||
'accepted': accepted,
|
||||
'noresp': noresp,
|
||||
'bypos': bypos,
|
||||
})
|
||||
'bypos': bypos})
|
||||
|
||||
@login_required
|
||||
def volunteer(request):
|
||||
|
|
|
@ -165,7 +165,8 @@ class SessionRequestTestCase(TestCase):
|
|||
self.assertContains(r, 'Schedule the sessions on subsequent days')
|
||||
self.assertContains(r, 'Thursday early afternoon, Thursday late afternoon')
|
||||
self.assertContains(r, group2.acronym)
|
||||
self.assertContains(r, 'Second session with: {} {}'.format(group3.acronym, group4.acronym))
|
||||
# The sessions can be in any order in the HTML, deal with that
|
||||
self.assertRegex(r.content.decode(), r'Second session with: ({} {}|{} {})'.format(group3.acronym, group4.acronym, group4.acronym, group3.acronym))
|
||||
|
||||
# check that a notification was sent
|
||||
self.assertEqual(len(outbox), 1)
|
||||
|
|
|
@ -57,7 +57,7 @@ $(document)
|
|||
var text = $(this)
|
||||
.text();
|
||||
// insert some <wbr> at strategic places
|
||||
var newtext = text.replace(/([@._])/g, "$1<wbr>");
|
||||
var newtext = text.replace(/([@._+])/g, "$1<wbr>");
|
||||
if (newtext === text) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
import * as List from "list.js";
|
||||
|
||||
var dummy = new List();
|
||||
import {
|
||||
default as List
|
||||
} from "list.js";
|
||||
|
||||
function text_sort(a, b, options) {
|
||||
|
||||
function prep(e, options) {
|
||||
return $($.parseHTML(e.values()[options.valueName]))
|
||||
.text()
|
||||
.trim()
|
||||
.replaceAll(/\s+/g, ' ');
|
||||
}
|
||||
|
||||
// sort by text content
|
||||
return dummy.utils.naturalSort.caseInsensitive($($.parseHTML(a.values()[options.valueName]))
|
||||
.text()
|
||||
.trim()
|
||||
.replaceAll(/\s+/g, ' '), $($.parseHTML(b.values()[options.valueName]))
|
||||
.text()
|
||||
.trim()
|
||||
.replaceAll(/\s+/g, ' '));
|
||||
return prep(a, options).localeCompare(prep(b, options), "en", {
|
||||
sensitivity: "base",
|
||||
ignorePunctuation: true
|
||||
});
|
||||
}
|
||||
|
||||
function replace_with_internal(table, internal_table, i) {
|
||||
|
@ -204,12 +209,12 @@ $(document)
|
|||
}
|
||||
|
||||
let newlist = new List(hook, pagination ? {
|
||||
valueNames: fields,
|
||||
pagination: pagination,
|
||||
page: items_per_page
|
||||
} : {
|
||||
valueNames: fields
|
||||
});
|
||||
valueNames: fields,
|
||||
pagination: pagination,
|
||||
page: items_per_page
|
||||
} : {
|
||||
valueNames: fields
|
||||
});
|
||||
// override search module with a patched version
|
||||
// see https://github.com/javve/list.js/issues/699
|
||||
// TODO: check if this is still needed if list.js ever sees an update
|
||||
|
@ -220,7 +225,7 @@ $(document)
|
|||
if (enable_search) {
|
||||
reset_search.on("click", function () {
|
||||
search_field.val("");
|
||||
$.each(list_instance, (i, e) => {
|
||||
$.each(list_instance, (_, e) => {
|
||||
e.search();
|
||||
});
|
||||
});
|
||||
|
@ -229,7 +234,7 @@ $(document)
|
|||
if (event.key == "Escape") {
|
||||
reset_search.trigger("click");
|
||||
} else {
|
||||
$.each(list_instance, (i, e) => {
|
||||
$.each(list_instance, (_, e) => {
|
||||
e.search($(this)
|
||||
.val());
|
||||
});
|
||||
|
@ -242,16 +247,19 @@ $(document)
|
|||
.on("click", function () {
|
||||
var order = $(this)
|
||||
.hasClass("asc") ? "desc" : "asc";
|
||||
$.each(list_instance, (i, e) => {
|
||||
$.each(list_instance, (_, e) => {
|
||||
e.sort($(this)
|
||||
.attr("data-sort"), { order: order, sortFunction: text_sort });
|
||||
.attr("data-sort"), {
|
||||
order: order,
|
||||
sortFunction: text_sort
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$.each(list_instance, (i, e) => {
|
||||
e.on("sortComplete", function () {
|
||||
replace_with_internal(table, internal_table, i);
|
||||
$(table).find("[data-bs-original-title]").tooltip();
|
||||
$(table).find("[data-bs-original-title]").tooltip();
|
||||
if (i == list_instance.length - 1) {
|
||||
$(table)
|
||||
.find("thead:first tr")
|
||||
|
@ -287,8 +295,11 @@ $(document)
|
|||
if (presort_col) {
|
||||
const order = presort_col.attr("data-default-sort");
|
||||
if (order === "asc" || order === "desc") {
|
||||
$.each(list_instance, (i, e) => {
|
||||
e.sort(presort_col.attr("data-sort"), { order: order, sortFunction: text_sort });
|
||||
$.each(list_instance, (_, e) => {
|
||||
e.sort(presort_col.attr("data-sort"), {
|
||||
order: order,
|
||||
sortFunction: text_sort
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ function filter_calendar_events(filter_params, event_list) {
|
|||
}
|
||||
|
||||
// format a moment in a tz
|
||||
var moment_formats = { time: 'HH:mm', date: 'YYYY-MM-DD', datetime: 'YYYY-MM-DD HH:mm' };
|
||||
var moment_formats = { time: 'HH:mm', date: 'YYYY-MM-DD', datetime: 'YYYY-MM-DD HH:mm' , timezone: 'z'};
|
||||
|
||||
function format_moment(t_moment, tz, fmt_type) {
|
||||
return t_moment.tz(tz)
|
||||
|
@ -43,6 +43,9 @@ function format_moment(t_moment, tz, fmt_type) {
|
|||
|
||||
function make_display_events(event_data, tz) {
|
||||
var calendarEl = document.getElementById('calendar');
|
||||
if (!calendarEl) {
|
||||
return;
|
||||
}
|
||||
var glue = calendarEl.clientWidth > 720 ? ' ' : '\n';
|
||||
return $.map(event_data, function (src_event) {
|
||||
var title;
|
||||
|
@ -83,6 +86,9 @@ function update_calendar(tz, filter_params) {
|
|||
* filtered events.
|
||||
*/
|
||||
var calendarEl = document.getElementById('calendar');
|
||||
if (!calendarEl) {
|
||||
return;
|
||||
}
|
||||
event_calendar = new FullCalendar(calendarEl, {
|
||||
plugins: [dayGridPlugin, bootstrap5Plugin],
|
||||
initialView: 'dayGridMonth',
|
||||
|
@ -136,7 +142,7 @@ function format_session_time(session_elt, tz) {
|
|||
.attr('data-start-utc'));
|
||||
var end = moment.utc($(session_elt)
|
||||
.attr('data-end-utc'));
|
||||
return format_moment(start, tz, 'datetime') + '-' + format_moment(end, tz, 'time');
|
||||
return format_moment(start, tz, 'datetime') + '-' + format_moment(end, tz, 'time') + ' ' + format_moment(start, tz, 'timezone');
|
||||
}
|
||||
|
||||
function format_meeting_time(meeting_elt, tz) {
|
||||
|
|
|
@ -355,7 +355,6 @@ class SubmitTests(BaseSubmitTestCase):
|
|||
ad=draft.ad,
|
||||
expires=timezone.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE),
|
||||
notify="aliens@example.mars",
|
||||
note="",
|
||||
)
|
||||
sug_replaced_draft.set_state(State.objects.get(used=True, type="draft", slug="active"))
|
||||
sug_replaced_alias = DocAlias.objects.create(name=sug_replaced_draft.name)
|
||||
|
@ -1413,7 +1412,6 @@ class SubmitTests(BaseSubmitTestCase):
|
|||
"submitter-name": "Some Random Test Person",
|
||||
"submitter-email": "random@example.com",
|
||||
"replaces": [str(draft.docalias.first().pk)],
|
||||
"edit-note": "no comments",
|
||||
"authors-0-name": "Person 1",
|
||||
"authors-0-email": "person1@example.com",
|
||||
"authors-1-name": "Person 2",
|
||||
|
@ -1429,7 +1427,6 @@ class SubmitTests(BaseSubmitTestCase):
|
|||
self.assertEqual(submission.document_date, document_date)
|
||||
self.assertEqual(submission.abstract, "some abstract")
|
||||
self.assertEqual(submission.pages, 123)
|
||||
self.assertEqual(submission.note, "no comments")
|
||||
self.assertEqual(submission.submitter, "Some Random Test Person <random@example.com>")
|
||||
self.assertEqual(submission.replaces, draft.docalias.first().name)
|
||||
self.assertEqual(submission.state_id, "manual")
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
{% csrf_token %}
|
||||
{% bootstrap_form ballot_writeup_form %}
|
||||
<div class="form-text my-3">
|
||||
Technical summary, Working Group summary, document quality, personnel, IRTF note, IESG note, IANA note. This text will be appended to all announcements and messages to the IRTF or RFC Editor.
|
||||
Technical summary, Working Group summary, document quality, personnel, IANA note. This text will be appended to all announcements and messages to the IRTF or RFC Editor.
|
||||
{% if ballot_issue_danger %}
|
||||
<p class="text-danger">
|
||||
This document has not completed IETF Last Call. Please do not issue the ballot early without good reason.
|
||||
|
@ -36,4 +36,4 @@
|
|||
Back
|
||||
</a>
|
||||
</form>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
|
@ -1,4 +1,4 @@
|
|||
{% load ietf_filters %}{% autoescape off %}From: The IESG <iesg-secretary@ietf.org>
|
||||
{% load ietf_filters %}{% autoescape off %}From: {% if group.type_id == "rg" %}The IRTF <irtf-chair@irtf.org>{% else %}The IESG <iesg-secretary@ietf.org>{% endif %}
|
||||
To: {{ to }}{% if cc %}
|
||||
Cc: {{ cc }} {% endif %}
|
||||
Subject: {{ group.type.name }} Action: {{ action_type }} {{ group.name }} ({{ group.acronym }})
|
||||
|
|
|
@ -36,14 +36,6 @@ RFC Editor Note
|
|||
|
||||
(Insert RFC Editor Note here or remove section)
|
||||
|
||||
IRTF Note
|
||||
|
||||
(Insert IRTF Note here or remove section)
|
||||
|
||||
IESG Note
|
||||
|
||||
(Insert IESG Note here or remove section)
|
||||
|
||||
IANA Note
|
||||
|
||||
(Insert IANA Note here or remove section)
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<form class="mt-3" method="post">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form ballot_writeup_form %}
|
||||
<div class="form-text mb-3">Working group summary, personnel, IAB note, IESG note, IANA note.</div>
|
||||
<div class="form-text mb-3">Working group summary, personnel, IANA note.</div>
|
||||
<button type="submit"
|
||||
class="btn btn-primary"
|
||||
name="save_ballot_writeup"
|
||||
|
|
|
@ -408,32 +408,19 @@
|
|||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% if iesg_state.slug != 'idexists' %}
|
||||
{% if doc.note or can_edit %}
|
||||
<tr>
|
||||
<td></td>
|
||||
<th scope="row">
|
||||
IESG note
|
||||
</th>
|
||||
<td class="edit">
|
||||
{% if can_edit and not snapshot %}
|
||||
<a class="btn btn-primary btn-sm"
|
||||
href="{% url 'ietf.doc.views_draft.edit_iesg_note' name=doc.name %}">
|
||||
Edit
|
||||
</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if doc.note %}
|
||||
{{ doc.note|linebreaksbr }}
|
||||
{% else %}
|
||||
<span class="text-body-secondary">
|
||||
(None)
|
||||
</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if iesg_state.slug != 'idexists' and doc.note %}
|
||||
<tr>
|
||||
<td></td>
|
||||
<th scope="row">
|
||||
IESG note
|
||||
</th>
|
||||
<td class="edit">
|
||||
{# IESG Notes are historic and read-only now #}
|
||||
</td>
|
||||
<td>
|
||||
{{ doc.notedoc.note|urlize_ietf_docs|linkify|linebreaksbr }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td></td>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
{# Copyright The IETF Trust 2015, All Rights Reserved #}
|
||||
{% load origin %}
|
||||
{% load static %}
|
||||
{% load ietf_filters textfilters %}
|
||||
{% load ietf_filters textfilters tz %}
|
||||
{% block title %}{{ doc.title|default:"Untitled" }}{% endblock %}
|
||||
{% block content %}
|
||||
{% origin %}
|
||||
|
@ -29,6 +29,24 @@
|
|||
{% if snapshot %}<span class="badge rounded-pill text-bg-warning">Snapshot</span>{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% if doc.meeting_related %}
|
||||
<tr>
|
||||
<th scope="row">
|
||||
Date and time
|
||||
</th>
|
||||
<td></td>
|
||||
<td>
|
||||
{% with session=doc.get_related_session %}
|
||||
{% with timeslot=session.official_timeslotassignment.timeslot %}
|
||||
{% if session.meeting %}
|
||||
<span class="session-time date me-3" data-start-utc="{{ timeslot.time|utc|date:'Y-m-d H:i' }}" data-end-utc="{{ timeslot.end_time|utc|date:'Y-m-d H:i' }}"></span>
|
||||
{% include "meeting/tz-display.html" with meeting_timezone=session.meeting.time_zone id_suffix="" minimal=True only %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<th scope="row">Title</th>
|
||||
<td class="edit">
|
||||
|
@ -97,7 +115,21 @@
|
|||
{% if presentations %}
|
||||
{% for pres in presentations %}
|
||||
{{ pres.session.short_name }} at {{ pres.session.meeting }}
|
||||
{% if pres.rev != doc.rev %}(version -{{ pres.rev }}){% endif %}{% if not forloop.last %},{% endif %}
|
||||
{% if pres.rev != doc.rev %}(version -{{ pres.rev }}){% endif %}
|
||||
<br>
|
||||
<b>Remote instructions:</b>
|
||||
{% if pres.session.agenda_note|first_url|conference_url %}
|
||||
<a href="{{ pres.session.agenda_note|first_url }}" title="Online conference">
|
||||
<i class="bi bi-beople"></i>
|
||||
</a>
|
||||
{% elif pres.session.remote_instructions|first_url|conference_url %}
|
||||
<a href="{{ pres.session.remote_instructions|first_url }}"
|
||||
title="Online conference">
|
||||
<i class="bi bi-people"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
{{ pres.session.remote_instructions|linkify }}
|
||||
{% if not forloop.last %}<br>{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<span class="text-body-secondary">(None)</span>
|
||||
|
@ -142,4 +174,16 @@
|
|||
{% block js %}
|
||||
<script src="{% static 'ietf/js/d3.js' %}"></script>
|
||||
<script src="{% static 'ietf/js/document_timeline.js' %}"></script>
|
||||
{% if doc.meeting_related %}
|
||||
<script src="{% static 'ietf/js/moment.js' %}"></script>
|
||||
<script src="{% static 'ietf/js/upcoming.js' %}"></script>
|
||||
<script src="{% static 'ietf/js/timezone.js' %}"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
// Init with best guess at local timezone.
|
||||
ietf_timezone.set_tz_change_callback(timezone_changed);
|
||||
ietf_timezone.initialize('local');
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -1,19 +0,0 @@
|
|||
{% extends "base.html" %}
|
||||
{# Copyright The IETF Trust 2015, All Rights Reserved #}
|
||||
{% load origin %}
|
||||
{% load django_bootstrap5 %}
|
||||
{% block title %}Edit IESG note for {{ doc.name }}{% endblock %}
|
||||
{% block content %}
|
||||
{% origin %}
|
||||
<h1>
|
||||
Edit IESG note
|
||||
<br>
|
||||
<small class="text-body-secondary">{{ doc.name }}</small>
|
||||
</h1>
|
||||
<form class="mt-3" method="post">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form form %}
|
||||
<button type="submit" class="btn btn-primary">Save</button>
|
||||
<a class="btn btn-secondary float-end" href="{{ doc.get_absolute_url }}">Back</a>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -33,13 +33,6 @@ Personnel
|
|||
Who is the Document Shepherd for this document? Who is the
|
||||
Responsible Area Director?
|
||||
{% endif %}
|
||||
{% if doc.stream.slug == "irtf" %}IRTF Note
|
||||
|
||||
(Insert IRTF Note here or remove section)
|
||||
{% elif doc.stream.slug == "ietf" %}IESG Note
|
||||
|
||||
(Insert IESG Note here or remove section)
|
||||
{% endif %}
|
||||
IANA Note
|
||||
{% if iana %}
|
||||
{% filter wordwrap:"76"|indent:2 %}{{ iana }}{% endfilter %}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
<h1>{{ group_type | upper }} {{ role }} photos</h1>
|
||||
{% regroup roles|dictsort:"last_initial" by last_initial as alphabet_blocks %}
|
||||
{% for letter in alphabet_blocks %}
|
||||
<!-- [html-validate-disable-next valid-id -- Unicode IDs are OK in HTML5] -->
|
||||
<h2 class="mt-4" {% if letter.grouper|slugify %}id="{{ letter.grouper }}"{% endif %}>{{ letter.grouper }}</h2>
|
||||
{% regroup letter.list by person as person_groups %}
|
||||
{# keep in sync with group_photos.html #}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
{% load origin tz %}
|
||||
{% origin %}
|
||||
{% for s in sessions %}
|
||||
{% timezone s.meeting.time_zone %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if s.meeting.type.slug == 'ietf' %}
|
||||
|
@ -12,9 +11,11 @@
|
|||
</td>
|
||||
<td>
|
||||
{% if s.current_status == "sched" %}
|
||||
{{ s.time|date:"Y-m-d" }}
|
||||
{% with timeslot=s.official_timeslotassignment.timeslot %}
|
||||
<span class="session-time date me-3" data-start-utc="{{ timeslot.time|utc|date:'Y-m-d H:i' }}" data-end-utc="{{ timeslot.end_time|utc|date:'Y-m-d H:i' }}"></span>
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
<i>{{ s.current_status_name }}</i>
|
||||
<div class="badge rounded-pill text-bg-secondary">{{ s.current_status_name }}</div>
|
||||
{% endif %}
|
||||
{% if show_request and s.meeting.type_id == 'ietf' %}
|
||||
{% if can_edit %}
|
||||
|
@ -28,9 +29,6 @@
|
|||
<td>
|
||||
{% if s.name %}{{ s.name }}{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if s.current_status == "sched" %}{{ s.time|date:"D" }}{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if show_ical and s.current_status == "sched" %}
|
||||
{% if s.meeting.type_id == 'ietf' %}
|
||||
|
@ -78,5 +76,4 @@
|
|||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endtimezone %}
|
||||
{% endfor %}
|
|
@ -1,6 +1,5 @@
|
|||
{% extends "group/group_base.html" %}
|
||||
{# Copyright The IETF Trust 2015-2022, All Rights Reserved #}
|
||||
{% load origin %}
|
||||
{% load origin static %}
|
||||
{% block title %}
|
||||
Meetings
|
||||
{% if group %}for {{ group.acronym }}{% endif %}
|
||||
|
@ -19,15 +18,15 @@
|
|||
{% endblock %}
|
||||
{% block group_content %}
|
||||
{% origin %}
|
||||
{% include "meeting/tz-display.html" with meeting_timezone=None id_suffix="" minimal=False only %}
|
||||
{% if in_progress %}
|
||||
<h2 class="mt-3" id="inprogressmeets">Meetings in progress</h2>
|
||||
<h2 class="mt-5" id="inprogressmeets">Meetings in progress</h2>
|
||||
{% with sessions=in_progress show_request=True show_ical=True can_edit_materials=can_edit %}
|
||||
<table class="table table-sm table-striped tablesorter">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" data-sort="meeting">Meeting</th>
|
||||
<th scope="col" data-sort="date">Date</th>
|
||||
<th scope="col"></th>
|
||||
<th class="col-3" scope="col" data-sort="meeting">Meeting</th>
|
||||
<th class="col-3" scope="col" data-sort="date">Date</th>
|
||||
<th scope="col"></th>
|
||||
<th scope="col">Materials</th>
|
||||
</tr>
|
||||
|
@ -39,7 +38,7 @@
|
|||
{% endwith %}
|
||||
{% endif %}
|
||||
{% if future %}
|
||||
<h2 class="mt-3" id="futuremeets">
|
||||
<h2 class="mt-5" id="futuremeets">
|
||||
Future Meetings
|
||||
<a class="float-end"
|
||||
aria-label="icalendar entry for all scheduled future {{ group.acronym }} meetings"
|
||||
|
@ -51,9 +50,8 @@
|
|||
<table class="table table-sm table-striped tablesorter">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" data-sort="meeting">Meeting</th>
|
||||
<th scope="col" data-sort="date">Date</th>
|
||||
<th scope="col"></th>
|
||||
<th class="col-3" scope="col" data-sort="meeting">Meeting</th>
|
||||
<th class="col-3" scope="col" data-sort="date">Date</th>
|
||||
<th scope="col"></th>
|
||||
<th scope="col">Materials</th>
|
||||
</tr>
|
||||
|
@ -66,13 +64,12 @@
|
|||
</table>
|
||||
{% endif %}
|
||||
{% if past or recent %}
|
||||
<h2 class="mt-3" id="pastmeets">Past Meetings (within the last four years)</h2>
|
||||
<h2 class="mt-5" id="pastmeets">Past Meetings (within the last four years)</h2>
|
||||
<table class="table table-sm table-striped tablesorter">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" data-sort="meeting">Meeting</th>
|
||||
<th scope="col" data-sort="date">Date</th>
|
||||
<th scope="col"></th>
|
||||
<th class="col-3" scope="col" data-sort="meeting">Meeting</th>
|
||||
<th class="col-3" scope="col" data-sort="date">Date</th>
|
||||
<th scope="col"></th>
|
||||
<th scope="col">Materials</th>
|
||||
</tr>
|
||||
|
@ -100,13 +97,12 @@
|
|||
older_sessions value, this block will need to be adjusted.
|
||||
{% endcomment %}
|
||||
{% if far_past %}
|
||||
<h2 class="mt-3" id="farpastmeets">Meetings more than four years ago</h2>
|
||||
<h2 class="mt-5" id="farpastmeets">Meetings more than four years ago</h2>
|
||||
<table class="table table-sm table-striped tablesorter">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" data-sort="meeting">Meeting</th>
|
||||
<th scope="col" data-sort="date">Date</th>
|
||||
<th scope="col"></th>
|
||||
<th class="col-3" scope="col" data-sort="meeting">Meeting</th>
|
||||
<th class="col-3" scope="col" data-sort="date">Date</th>
|
||||
<th scope="col"></th>
|
||||
<th scope="col">Materials</th>
|
||||
</tr>
|
||||
|
@ -160,3 +156,16 @@
|
|||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block js %}
|
||||
<script src="{% static 'ietf/js/list.js' %}"></script>
|
||||
<script src="{% static 'ietf/js/moment.js' %}"></script>
|
||||
<script src="{% static 'ietf/js/upcoming.js' %}"></script>
|
||||
<script src="{% static 'ietf/js/timezone.js' %}"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
// Init with best guess at local timezone.
|
||||
ietf_timezone.set_tz_change_callback(timezone_changed);
|
||||
ietf_timezone.initialize('local');
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -1,7 +1,7 @@
|
|||
{# Copyright The IETF Trust 2015, All Rights Reserved #}
|
||||
{% load origin %}
|
||||
{% origin %}
|
||||
{% load ietf_filters ballot_icon person_filters %}
|
||||
{% load ietf_filters ballot_icon person_filters textfilters %}
|
||||
<div class="card mb-3">
|
||||
<div class="position-absolute top-0 end-0 m-3">{% ballot_icon doc %}</div>
|
||||
<div class="card-body">
|
||||
|
@ -27,7 +27,7 @@
|
|||
{% if conflictdoc.note %}
|
||||
<div class="row">
|
||||
<div class="col-3 text-end fw-bold">Note</div>
|
||||
<div class="col">{{ conflictdoc.note|linebreaksbr }}</div>
|
||||
<div class="col">{{ conflictdoc.note|urlize_ietf_docs|linkify|linebreaksbr }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
|
|
|
@ -3,6 +3,5 @@
|
|||
{% filter wordwrap:"68"|indent|indent %}{{ doc.title }}{% endfilter %}
|
||||
{{ conflictdoc.canonical_name }}-{{ conflictdoc.rev }}
|
||||
{% filter wordwrap:"66"|indent:"4" %}{{ conflictdoc.title }} ({{ conflictdoc.stream }}: {{ conflictdoc.intended_std_level }}){% endfilter %}
|
||||
{% if conflictdoc.note %}{# note: note is not escaped #} {% filter wordwrap:"64"|indent:"6" %}Note: {{ conflictdoc.note|striptags }}{% endfilter %}
|
||||
{% endif %} Token: {{ doc.ad }}
|
||||
Token: {{ doc.ad }}
|
||||
{% with doc.active_defer_event as defer %}{% if defer %} Was deferred by {{defer.by}} on {{defer.time|date:"Y-m-d"}}{% endif %}{% endwith %}{% endwith %}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
{% load ietf_filters %}{% with doc.rfc_number as rfc_number %}
|
||||
o {{doc.canonical_name}}{% if not rfc_number %}-{{doc.rev}}{% endif %}{% endwith %}{%if doc.has_rfc_editor_note %} (Has RFC Editor Note){% endif %}{% if doc.stream %} - {{ doc.stream }} stream{% endif %}
|
||||
{% filter wordwrap:"68"|indent|indent %}{{ doc.title }} ({{ doc.intended_std_level }}){% endfilter %}
|
||||
{% if doc.note %}{# note: note is not escaped #} {% filter wordwrap:"68"|indent|indent %}Note: {{ doc.note|striptags }}{% endfilter %}
|
||||
{% endif %} Token: {{ doc.ad }}{% if doc.iana_review_state %}
|
||||
Token: {{ doc.ad }}{% if doc.iana_review_state %}
|
||||
IANA Review: {{ doc.iana_review_state }}{% endif %}{% if doc.consensus %}
|
||||
Consensus: {{ doc.consensus }}{% endif %}{% if doc.lastcall_expires %}
|
||||
Last call expires: {{ doc.lastcall_expires|date:"Y-m-d" }}{% endif %}{% if doc.review_assignments %}
|
||||
|
|
|
@ -93,7 +93,7 @@ Parts Copyright (c) 2009 The IETF Trust, all rights reserved.
|
|||
|
||||
<p>If APPROVED with caveats - The Secretariat will send a working
|
||||
group submission, Protocol Action Announcement that includes the
|
||||
[RFC Editor Note, IESG Note, etc.] to be drafted by [Name that
|
||||
[RFC Editor Note, etc.] to be drafted by [Name that
|
||||
AD].</p>
|
||||
{% endif %}
|
||||
|
||||
|
@ -103,7 +103,7 @@ Parts Copyright (c) 2009 The IETF Trust, all rights reserved.
|
|||
|
||||
<p>If APPROVED with caveats - The Secretariat will send an
|
||||
individual submission, Protocol Action Announcement that includes
|
||||
the [RFC Editor Note, IESG Note, etc.] to be drafted by [Name that
|
||||
the [RFC Editor Note, etc.] to be drafted by [Name that
|
||||
AD].</p>
|
||||
{% endif %}
|
||||
|
||||
|
@ -113,7 +113,7 @@ Parts Copyright (c) 2009 The IETF Trust, all rights reserved.
|
|||
|
||||
<p>If APPROVED with caveats - The Secretariat will send the
|
||||
associated status change Protocol Action Announcements that includes the
|
||||
[RFC Editor Note, IESG Note, etc.] to be drafted by [Name that
|
||||
[RFC Editor Note, etc.] to be drafted by [Name that
|
||||
AD].</p>
|
||||
{% endif %}
|
||||
|
||||
|
@ -123,7 +123,7 @@ Parts Copyright (c) 2009 The IETF Trust, all rights reserved.
|
|||
|
||||
<p>If APPROVED with caveats - The Secretariat will send a working
|
||||
group submission Document Action announcement that includes the [RFC
|
||||
Ed. Note, IESG, note, etc.] from [Name that AD].</p>
|
||||
Ed. Note, etc.] from [Name that AD].</p>
|
||||
{% endif %}
|
||||
|
||||
{% if num|startswith:"3.2.1" or num|startswith:"3.2.2" %}
|
||||
|
@ -132,7 +132,7 @@ Parts Copyright (c) 2009 The IETF Trust, all rights reserved.
|
|||
|
||||
<p>If APPROVED with caveats - The Secretariat will send an
|
||||
individual submission Document Action announcement that includes the
|
||||
[RFC Ed. Note, IESG, note, etc.] from [Name that AD].</p>
|
||||
[RFC Ed. Note, etc.] from [Name that AD].</p>
|
||||
{% endif %}
|
||||
|
||||
{% if num|startswith:"3.3.1" or num|startswith:"3.3.2" %}
|
||||
|
@ -141,13 +141,12 @@ Parts Copyright (c) 2009 The IETF Trust, all rights reserved.
|
|||
|
||||
<p>If APPROVED with caveats - The Secretariat will send the associated
|
||||
status change Document Action announcements that includes the [RFC
|
||||
Ed. Note, IESG, note, etc.] from [Name that AD].</p>
|
||||
Ed. Note, etc.] from [Name that AD].</p>
|
||||
{% endif %}
|
||||
|
||||
{% if num|startswith:"3.4.1" or num|startswith:"3.4.2" %}
|
||||
<p>If APPROVED - The Secretariat will send a standard no problem
|
||||
message to the RFC Editor. [Name of AD] will you supply the text for
|
||||
the IESG Note?</p>
|
||||
message to the RFC Editor.</p>
|
||||
|
||||
<p>If APPROVED with caveats - The Secretariat will send a standard
|
||||
no problem message to the RFC Editor that includes the note drafted
|
||||
|
|
|
@ -57,6 +57,17 @@
|
|||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block js %}
|
||||
<script src="{% static 'ietf/js/list.js' %}"></script>
|
||||
<script src="{% static 'ietf/js/moment.js' %}"></script>
|
||||
<script src="{% static 'ietf/js/upcoming.js' %}"></script>
|
||||
<script src="{% static 'ietf/js/timezone.js' %}"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
// Init with best guess at local timezone.
|
||||
ietf_timezone.set_tz_change_callback(timezone_changed);
|
||||
ietf_timezone.initialize('local');
|
||||
});
|
||||
</script>
|
||||
{% if can_manage_materials %}
|
||||
<script src="{% static 'ietf/js/sortable.js' %}"></script>
|
||||
<script>
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
{% if sessions|length > 1 %}Session {{ forloop.counter }} :{% endif %}
|
||||
{% for time in session.times %}
|
||||
{% if not forloop.first %},{% endif %}
|
||||
{{ time|timezone:session.meeting.time_zone|dateformat:"l Y-m-d H:i T" }}
|
||||
{% if time.tzinfo.zone != "UTC" %}<span class="small">({{ time|utc|dateformat:"H:i T" }})</span>{% endif %}
|
||||
<span class="session-time date me-3" data-start-utc="{{ timeslot.time|utc|date:'Y-m-d H:i' }}" data-end-utc="{{ timeslot.end_time|utc|date:'Y-m-d H:i' }}"></span>
|
||||
{% include "meeting/tz-display.html" with meeting_timezone=session.meeting.time_zone id_suffix=session.pk minimal=True only %}
|
||||
{% endfor %}
|
||||
{% if session.cancelled %}
|
||||
<small class="badge rounded-pill text-bg-warning">Cancelled</small>
|
||||
|
|
|
@ -12,8 +12,8 @@ As long as id_suffix is different, should allow for as many copies of the widget
|
|||
{% load origin %}
|
||||
{% origin %}
|
||||
{% firstof id_suffix "" as suffix %}
|
||||
<div class="tz-display flex-fill {% if minimal %}btn-group btn-group-sm my-2{% else %}input-group my-3{% endif %} flex-wrap">
|
||||
{% if not minimal %}<label class="input-group-text border-primary bg-white fw-bold">Time zone:</label>{% endif %}
|
||||
<span class="tz-display flex-fill {% if minimal %}btn-group btn-group-sm my-2{% else %}input-group my-3{% endif %} flex-wrap">
|
||||
{% if not minimal %}<label class="input-group-text border-primary bg-transparent fw-bold">Time zone:</label>{% endif %}
|
||||
{% if meeting_timezone is not None %}
|
||||
<input type="radio"
|
||||
name="tzradio{{ suffix }}"
|
||||
|
@ -46,4 +46,4 @@ As long as id_suffix is different, should allow for as many copies of the widget
|
|||
</option>
|
||||
</select>
|
||||
{% endif %}
|
||||
</div>
|
||||
</span>
|
|
@ -4,9 +4,6 @@
|
|||
{% load django_bootstrap5 textfilters person_filters %}
|
||||
{% load static %}
|
||||
{% block subtitle %}- Eligible People{% endblock %}
|
||||
{% block pagehead %}
|
||||
<link rel="stylesheet" href="{% static "ietf/css/list.css" %}">
|
||||
{% endblock %}
|
||||
{% block nomcom_content %}
|
||||
{% origin %}
|
||||
<h2>Eligible People for {{ nomcom.group }}</h2>
|
||||
|
@ -41,7 +38,4 @@
|
|||
{% endif %}
|
||||
</table>
|
||||
}
|
||||
{% endblock %}
|
||||
{% block js %}
|
||||
<script src="{% static "ietf/js/list.js" %}"></script>
|
||||
{% endblock %}
|
|
@ -24,23 +24,24 @@
|
|||
<thead>
|
||||
<tr>
|
||||
{% if nomcom.group.state_id == 'active' %}
|
||||
<th scope="colgroup" colspan="3">
|
||||
<i class="bi bi-check"></i>
|
||||
<th scope="col">
|
||||
✓
|
||||
</th>
|
||||
<th scope="col"></th>
|
||||
{% endif %}
|
||||
<th scope="col" data-sort="position">
|
||||
Position
|
||||
</th>
|
||||
<th scope="col" data-sort="iesg">
|
||||
<th class="text-center" scope="col" data-sort="iesg">
|
||||
IESG
|
||||
</th>
|
||||
<th scope="col" data-sort="open">
|
||||
<th class="text-center" scope="col" data-sort="open">
|
||||
Open
|
||||
</th>
|
||||
<th scope="col" data-sort="accept_nom">
|
||||
<th class="text-center" scope="col" data-sort="accept_nom">
|
||||
Accepting Nominations
|
||||
</th>
|
||||
<th scope="col" data-sort="accept_fb">
|
||||
<th class="text-center" scope="col" data-sort="accept_fb">
|
||||
Accepting Feedback
|
||||
</th>
|
||||
</tr>
|
||||
|
@ -58,13 +59,11 @@
|
|||
aria-label="position.name"
|
||||
name="selected">
|
||||
</td>
|
||||
<td class="edit">
|
||||
<td class="text-nowrap">
|
||||
<a class="btn btn-primary btn-sm"
|
||||
href="{% url 'ietf.nomcom.views.edit_position' year position.id %}">
|
||||
Edit
|
||||
</a>
|
||||
</td>
|
||||
<td class="remove">
|
||||
<a class="btn btn-danger btn-sm"
|
||||
href="{% url 'ietf.nomcom.views.remove_position' year position.id %}">
|
||||
Remove
|
||||
|
@ -74,16 +73,16 @@
|
|||
<td>
|
||||
{{ position.name }}
|
||||
</td>
|
||||
<td>
|
||||
<td class="text-center">
|
||||
{{ position.is_iesg_position|yesno:"✓," }}
|
||||
</td>
|
||||
<td>
|
||||
<td class="text-center">
|
||||
{{ position.is_open|yesno:"✓," }}
|
||||
</td>
|
||||
<td>
|
||||
<td class="text-center">
|
||||
{{ position.accepting_nominations|yesno:"✓," }}
|
||||
</td>
|
||||
<td>
|
||||
<td class="text-center">
|
||||
{{ position.accepting_feedback|yesno:"✓," }}
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -117,7 +116,7 @@
|
|||
<option value="unset_accept_nom">
|
||||
Is Accepting Nominations: No
|
||||
</option>
|
||||
<option value="set_accept_bf">
|
||||
<option value="set_accept_fb">
|
||||
Is Accepting Feedback: Yes
|
||||
</option>
|
||||
<option value="unset_accept_fb">
|
||||
|
@ -135,7 +134,4 @@
|
|||
There are no positions defined.
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block js %}
|
||||
<script src="{% static "ietf/js/list.js" %}"></script>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
|
@ -1,14 +1,18 @@
|
|||
{% extends "base.html" %}
|
||||
{# Copyright The IETF Trust 2015, All Rights Reserved #}
|
||||
{% load origin %}
|
||||
{% load origin static %}
|
||||
{% load nomcom_tags %}
|
||||
{% load ietf_filters %}
|
||||
{% block pagehead %}
|
||||
<link rel="stylesheet" href="{% static "ietf/css/list.css" %}">
|
||||
{% endblock %}
|
||||
{% block title %}
|
||||
NomCom {{ year }} Private
|
||||
{% block subtitle %}{% endblock %}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
{% origin %}
|
||||
{% with selected=request.path|split:'/'|slice:'4:-1'|join:'-' %}
|
||||
<h1>
|
||||
NomCom {{ year }}
|
||||
{% if nomcom.group.state_id == 'conclude' %}<span class="badge rounded-pill text-bg-info">Concluded</span>{% endif %}
|
||||
|
@ -19,129 +23,140 @@
|
|||
</h1>
|
||||
<ul class="nav nav-tabs my-3">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if selected == "index" %}active{% endif %}"
|
||||
<a class="nav-link {% if selected == '' %}active{% endif %}"
|
||||
href="{% url "ietf.nomcom.views.private_index" year %}">
|
||||
Nominees
|
||||
</a>
|
||||
</li>
|
||||
{% if nomcom|has_publickey %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if selected == "nominate" %}active{% endif %}"
|
||||
<a class="nav-link {% if selected == 'nominate' %}active{% endif %}"
|
||||
href="{% url 'ietf.nomcom.views.private_nominate' year %}">
|
||||
Nominate
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if selected == "feedback" %}active{% endif %}"
|
||||
{% endif %}
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle {% if selected in 'feedback,view-feedback'|split:',' %}active{% endif %}" data-bs-toggle="dropdown" href="#">Feedback</a>
|
||||
<ul class="dropdown-menu mt-n1" role="menu">
|
||||
{% if nomcom|has_publickey %}
|
||||
<li>
|
||||
<a class="dropdown-item {% if selected == 'feedback' %}active{% endif %}"
|
||||
href="{% url 'ietf.nomcom.views.private_feedback' year %}">
|
||||
Enter feedback
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if selected == "view_feedback" %}active{% endif %}"
|
||||
href="{% url 'ietf.nomcom.views.view_feedback' year %}">
|
||||
View feedback
|
||||
</a>
|
||||
{% endif %}
|
||||
<li>
|
||||
<a class="dropdown-item {% if selected == 'view-feedback' %}active{% endif %}"
|
||||
href="{% url 'ietf.nomcom.views.view_feedback' year %}">
|
||||
View feedback
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if selected == "private_key" %}active{% endif %}"
|
||||
<a class="nav-link {% if selected == 'key' %}active{% endif %}"
|
||||
href="{% url 'ietf.nomcom.views.private_key' year %}">
|
||||
Private key
|
||||
</a>
|
||||
</li>
|
||||
{% if user|is_chair_or_advisor:year %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if selected == "feedback_pending" %}active{% endif %}"
|
||||
<a class="nav-link {% if selected == 'view-feedback-pending' %}active{% endif %}"
|
||||
href="{% url 'ietf.nomcom.views.view_feedback_pending' year %}">
|
||||
Pending emails
|
||||
{% if nomcom.pending_email_count %}<span class="badge rounded-pill text-bg-primary">{{ nomcom.pending_email_count }}</span>{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#">Chair/Advisor Tasks</a>
|
||||
<a class="nav-link dropdown-toggle {% if selected in 'feedback-email,questionnaire-response,extract-email-lists,send-reminder-mail-accept,send-reminder-mail-questionnaire,merge-person,merge-nominee,edit-nomcom,chair-templates,chair-position,chair-topic,edit-members,help'|split:',' %}active{% endif %}" data-bs-toggle="dropdown" href="#">Chair/advisor tasks</a>
|
||||
<ul class="dropdown-menu mt-n1" role="menu">
|
||||
{% if nomcom.group.state_id == 'active' %}
|
||||
<li role="presentation" class="dropdown-header">Feedback Management</li>
|
||||
<li class="dropdown-item">
|
||||
<a href="{% url 'ietf.nomcom.views.private_feedback_email' year %}">Enter email feedback</a>
|
||||
<li>
|
||||
<a class="dropdown-item {% if selected == 'feedback-email' %}active{% endif %}" href="{% url 'ietf.nomcom.views.private_feedback_email' year %}">Enter email feedback</a>
|
||||
</li>
|
||||
<li class="dropdown-item">
|
||||
<a href="{% url 'ietf.nomcom.views.private_questionnaire' year %}">Enter questionnaire response</a>
|
||||
<li>
|
||||
<a class="dropdown-item {% if selected == 'questionnaire-response' %}active{% endif %}" href="{% url 'ietf.nomcom.views.private_questionnaire' year %}">Enter questionnaire response</a>
|
||||
</li>
|
||||
<li class="dropdown-item">
|
||||
<a href="{% url 'ietf.nomcom.views.extract_email_lists' year %}">Extract email lists</a>
|
||||
<li>
|
||||
<a class="dropdown-item {% if selected == 'extract-email-lists' %}active{% endif %}" href="{% url 'ietf.nomcom.views.extract_email_lists' year %}">Extract email lists</a>
|
||||
</li>
|
||||
<li class="dropdown-item">
|
||||
<a href="{% url 'ietf.nomcom.views.send_reminder_mail' year "accept" %}">Send accept reminder</a>
|
||||
<li>
|
||||
<a class="dropdown-item {% if selected == 'send-reminder-mail-accept' %}active{% endif %}" href="{% url 'ietf.nomcom.views.send_reminder_mail' year "accept" %}">Send accept reminder</a>
|
||||
</li>
|
||||
<li class="dropdown-item">
|
||||
<a href="{% url 'ietf.nomcom.views.send_reminder_mail' year "questionnaire" %}">Send questionnaire reminder</a>
|
||||
<li>
|
||||
<a class="dropdown-item {% if selected == 'send-reminder-mail-questionnaire' %}active{% endif %}" href="{% url 'ietf.nomcom.views.send_reminder_mail' year "questionnaire" %}">Send questionnaire reminder</a>
|
||||
</li>
|
||||
<li class="dropdown-item">
|
||||
<a href="{% url "ietf.nomcom.views.private_merge_person" year %}">Request person record merge</a>
|
||||
<li>
|
||||
<a class="dropdown-item {% if selected == 'merge-person' %}active{% endif %}" href="{% url "ietf.nomcom.views.private_merge_person" year %}">Request person record merge</a>
|
||||
</li>
|
||||
<li class="dropdown-item">
|
||||
<a href="{% url "ietf.nomcom.views.private_merge_nominee" year %}">Merge nominee records</a>
|
||||
<li>
|
||||
<a class="dropdown-item {% if selected == 'merge-nominee' %}active{% endif %}" href="{% url "ietf.nomcom.views.private_merge_nominee" year %}">Merge nominee records</a>
|
||||
</li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
{% endif %}
|
||||
<li role="presentation" class="dropdown-header">NomCom configuration</li>
|
||||
<li class="dropdown-item">
|
||||
<a href="{% url 'ietf.nomcom.views.edit_nomcom' year %}">Edit settings</a>
|
||||
<li>
|
||||
<a class="dropdown-item {% if selected == 'edit-nomcom' %}active{% endif %}" href="{% url 'ietf.nomcom.views.edit_nomcom' year %}">Edit settings</a>
|
||||
</li>
|
||||
<li class="dropdown-item">
|
||||
<a href="{% url 'ietf.nomcom.views.list_templates' year %}">Edit pages</a>
|
||||
<li>
|
||||
<a class="dropdown-item {% if selected == 'chair-templates' %}active{% endif %}" href="{% url 'ietf.nomcom.views.list_templates' year %}">Edit pages</a>
|
||||
</li>
|
||||
<li class="dropdown-item">
|
||||
<a href="{% url 'ietf.nomcom.views.list_positions' year %}">Edit positions</a>
|
||||
<li>
|
||||
<a class="dropdown-item {% if selected == 'chair-position' %}active{% endif %}" href="{% url 'ietf.nomcom.views.list_positions' year %}">Edit positions</a>
|
||||
</li>
|
||||
<li class="dropdown-item">
|
||||
<a href="{% url 'ietf.nomcom.views.list_topics' year %}">Edit topics</a>
|
||||
<li>
|
||||
<a class="dropdown-item {% if selected == 'chair-topic' %}active{% endif %}" href="{% url 'ietf.nomcom.views.list_topics' year %}">Edit topics</a>
|
||||
</li>
|
||||
{% if nomcom.group.state_id == 'active' %}
|
||||
<li class="dropdown-item">
|
||||
<a href="{% url 'ietf.nomcom.views.edit_members' year %}">Edit members</a>
|
||||
<li>
|
||||
<a class="dropdown-item {% if selected == 'edit-members' %}active{% endif %}" href="{% url 'ietf.nomcom.views.edit_members' year %}">Edit members</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="dropdown-item">
|
||||
<a href="{% url 'ietf.nomcom.views.configuration_help' year %}">Configuration help</a>
|
||||
<li>
|
||||
<a class="dropdown-item {% if selected == 'help' %}active{% endif %}" href="{% url 'ietf.nomcom.views.configuration_help' year %}">Configuration help</a>
|
||||
</li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li role="presentation" class="dropdown-header">Other tools</li>
|
||||
<li class="dropdown-item">
|
||||
<a href="{% url 'ietf.secr.announcement.views.main' %}">Announcement tool</a>
|
||||
</li>
|
||||
<li class="dropdown-item">
|
||||
<a href="https://www.ietf.org/registration/nomcom_chair/nomcomstaff.py">Secretariat private eligibility checker</a>
|
||||
</li>
|
||||
<li class="dropdown-item">
|
||||
<a href="https://www.ietf.org/registration/nomcom.py">Secretariat public eligibility checker</a>
|
||||
<li>
|
||||
<a class="dropdown-item" href="{% url 'ietf.secr.announcement.views.main' %}">Announcement tool</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if user|is_chair_or_advisor:year or user|has_role:"Secretariat" %}
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#">
|
||||
<a class="nav-link dropdown-toggle {% if selected in 'chair-eligible,chair-volunteers'|split:',' %}active{% endif %}" data-bs-toggle="dropdown" href="#">
|
||||
Volunteers
|
||||
</a>
|
||||
<ul class="dropdown-menu mt-n1" role="menu">
|
||||
<li class="dropdown-item">
|
||||
<a href="{% url 'ietf.nomcom.views.private_eligible' year %}">
|
||||
<li>
|
||||
<a class="dropdown-item {% if selected == 'chair-eligible' %}active{% endif %}" href="{% url 'ietf.nomcom.views.private_eligible' year %}">
|
||||
View eligible
|
||||
</a>
|
||||
</li>
|
||||
<li class="dropdown-item">
|
||||
<a href="{% url 'ietf.nomcom.views.private_volunteers' year %}">
|
||||
<li>
|
||||
<a class="dropdown-item {% if selected == 'chair-volunteers' %}active{% endif %}" href="{% url 'ietf.nomcom.views.private_volunteers' year %}">
|
||||
View volunteers
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link"
|
||||
href="/nomcom/{{ nomcom.year }}">
|
||||
Public pages »
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
{% block nomcom_content %}{% endblock %}
|
||||
{% endwith %}
|
||||
{% endblock %}
|
||||
{% block js %}
|
||||
<script src="{% static "ietf/js/list.js" %}"></script>
|
||||
<script>
|
||||
// Javascript to enable link to tab
|
||||
var url=document.location.toString();
|
||||
|
|
|
@ -1,21 +1,25 @@
|
|||
{% extends "base.html" %}
|
||||
{# Copyright The IETF Trust 2015, All Rights Reserved #}
|
||||
{% load origin %}
|
||||
{% load origin static %}
|
||||
{% load nomcom_tags %}
|
||||
{% load ietf_filters %}
|
||||
{% block pagehead %}
|
||||
<link rel="stylesheet" href="{% static "ietf/css/list.css" %}">
|
||||
{% endblock %}
|
||||
{% block title %}
|
||||
NomCom {{ year }}
|
||||
{% block subtitle %}{% endblock %}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
{% origin %}
|
||||
{% with selected=request.path|split:'/'|slice:'3:-1'|join:'-' %}
|
||||
<h1>
|
||||
NomCom {{ year }}
|
||||
{% if nomcom.group.state_id == 'conclude' %}<span class="badge rounded-pill text-bg-info">Concluded</span>{% endif %}
|
||||
</h1>
|
||||
<ul class="nav nav-tabs my-3">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if selected == "index" %}active{% endif %}"
|
||||
<a class="nav-link {% if selected == '' %}active{% endif %}"
|
||||
href="{% url 'ietf.nomcom.views.year_index' year %}">
|
||||
Home
|
||||
</a>
|
||||
|
@ -35,7 +39,7 @@
|
|||
</li>
|
||||
{% endif %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if selected == "requirements" %}active{% endif %}"
|
||||
<a class="nav-link {% if selected == "expertise" %}active{% endif %}"
|
||||
href="{% url 'ietf.nomcom.views.requirements' year %}">
|
||||
Desired expertise
|
||||
</a>
|
||||
|
@ -48,14 +52,14 @@
|
|||
</li>
|
||||
{% if user|is_chair_or_advisor:year or user|has_role:"Secretariat" %}
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#">Volunteers</a>
|
||||
<a class="nav-link dropdown-toggle {% if selected in 'eligible,volunteers'|split:',' %}active{% endif %}" data-bs-toggle="dropdown" href="#">Volunteers</a>
|
||||
<ul class="dropdown-menu mt-n1" role="menu">
|
||||
<li class="nav-item">
|
||||
<a class="dropdown-item"
|
||||
<a class="dropdown-item {% if selected == 'eligible' %}active{% endif %}"
|
||||
href="{% url 'ietf.nomcom.views.public_eligible' year %}">View eligible</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="dropdown-item"
|
||||
<a class="dropdown-item {% if selected == 'volunteers' %}active{% endif %}"
|
||||
href="{% url 'ietf.nomcom.views.public_volunteers' year %}">View volunteers</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -63,8 +67,10 @@
|
|||
{% endif %}
|
||||
</ul>
|
||||
{% block nomcom_content %}{% endblock %}
|
||||
{% endwith %}
|
||||
{% endblock %}
|
||||
{% block js %}
|
||||
<script src="{% static "ietf/js/list.js" %}"></script>
|
||||
<script>
|
||||
$(document)
|
||||
.ready(function () {
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
{# Copyright The IETF Trust 2015-2020, All Rights Reserved #}
|
||||
{% load origin static %}
|
||||
{% block subtitle %}- Administration{% endblock %}
|
||||
{% block pagehead %}
|
||||
<link rel="stylesheet" href="{% static "ietf/css/list.css" %}">
|
||||
{% endblock %}
|
||||
{% block nomcom_content %}
|
||||
{% origin %}
|
||||
<h2 class="mt-3">Nomination status</h2>
|
||||
|
@ -251,7 +248,4 @@
|
|||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block js %}
|
||||
<script src="{% static "ietf/js/list.js" %}"></script>
|
||||
{% endblock %}
|
|
@ -3,9 +3,6 @@
|
|||
{% load origin static %}
|
||||
{% load nomcom_tags %}
|
||||
{% block subtitle %}- View feedback{% endblock %}
|
||||
{% block pagehead %}
|
||||
<link rel="stylesheet" href="{% static "ietf/css/list.css" %}">
|
||||
{% endblock %}
|
||||
{% block nomcom_content %}
|
||||
{% origin %}
|
||||
<h2 class="mt-3">Feedback related to nominees</h2>
|
||||
|
@ -113,7 +110,4 @@
|
|||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block js %}
|
||||
<script src="{% static "ietf/js/list.js" %}"></script>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
|
@ -1,12 +1,9 @@
|
|||
{% extends public|yesno:"nomcom/nomcom_public_base.html,nomcom/nomcom_private_base.html" %}
|
||||
{# Copyright The IETF Trust 2021, All Rights Reserved #}
|
||||
{% load origin %}
|
||||
{% load django_bootstrap5 textfilters person_filters %}
|
||||
{% load django_bootstrap5 textfilters person_filters ietf_filters%}
|
||||
{% load static %}
|
||||
{% block subtitle %}- Volunteers{% endblock %}
|
||||
{% block pagehead %}
|
||||
<link rel="stylesheet" href="{% static "ietf/css/list.css" %}">
|
||||
{% endblock %}
|
||||
{% block nomcom_content %}
|
||||
{% origin %}
|
||||
<h2>Volunteers for {{ nomcom.group }}</h2>
|
||||
|
@ -34,7 +31,7 @@
|
|||
{% for v in eligibility_group.list %}
|
||||
<tr>
|
||||
<td>{{ forloop.counter }}</td>
|
||||
<td>{{ v.person.last_name }}</td>
|
||||
<td>{{ v.person.last_name|split:'+'|join:'+<wbr>' }}</td>
|
||||
<td>{{ v.person.first_name }}</td>
|
||||
<td>{{ v.person.ascii_name }}</td>
|
||||
<td>{% person_link v.person %}</td>
|
||||
|
@ -46,7 +43,4 @@
|
|||
</tbody>
|
||||
</table>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
{% block js %}
|
||||
<script src="{% static "ietf/js/list.js" %}"></script>
|
||||
{% endblock %}
|
|
@ -21,7 +21,6 @@
|
|||
</p>
|
||||
<ul>
|
||||
<li>Only XML-only uploads are supported, not text or combined.</li>
|
||||
<li>Document replacement information cannot be supplied.</li>
|
||||
<li>
|
||||
The server expects <code>multipart/form-data</code>, supported by <code>curl</code> but <b>not</b> by <code>wget</code>.
|
||||
</li>
|
||||
|
|
|
@ -306,7 +306,6 @@ def make_test_data():
|
|||
ad=ad,
|
||||
expires=timezone.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE),
|
||||
notify="aliens@example.mars",
|
||||
note="",
|
||||
)
|
||||
|
||||
draft.set_state(State.objects.get(used=True, type="draft", slug="active"))
|
||||
|
|
|
@ -719,8 +719,11 @@ class IetfTestRunner(DiscoverRunner):
|
|||
parser.add_argument('--validate-html-harder',
|
||||
action='store_true', dest="validate_html_harder", default=False,
|
||||
help='Validate all generated HTML with additional validators (slow)')
|
||||
parser.add_argument('--rerun-until-failure',
|
||||
action='store_true', dest='rerun', default=False,
|
||||
help='Run the indicated tests in a loop until a failure occurs. ' )
|
||||
|
||||
def __init__(self, ignore_lower_coverage=False, skip_coverage=False, save_version_coverage=None, html_report=None, permit_mixed_migrations=None, show_logging=None, validate_html=None, validate_html_harder=None, **kwargs):
|
||||
def __init__(self, ignore_lower_coverage=False, skip_coverage=False, save_version_coverage=None, html_report=None, permit_mixed_migrations=None, show_logging=None, validate_html=None, validate_html_harder=None, rerun=None, **kwargs):
|
||||
#
|
||||
self.ignore_lower_coverage = ignore_lower_coverage
|
||||
self.check_coverage = not skip_coverage
|
||||
|
@ -728,6 +731,8 @@ class IetfTestRunner(DiscoverRunner):
|
|||
self.html_report = html_report
|
||||
self.permit_mixed_migrations = permit_mixed_migrations
|
||||
self.show_logging = show_logging
|
||||
self.rerun = rerun
|
||||
self.test_labels = None
|
||||
global validation_settings
|
||||
validation_settings["validate_html"] = self if validate_html else None
|
||||
validation_settings["validate_html_harder"] = self if validate_html and validate_html_harder else None
|
||||
|
@ -1108,6 +1113,13 @@ class IetfTestRunner(DiscoverRunner):
|
|||
]
|
||||
return tests
|
||||
|
||||
def run_suite(self, suite, **kwargs):
|
||||
failures = super(IetfTestRunner, self).run_suite(suite, **kwargs)
|
||||
while self.rerun and not failures.errors and not failures.failures:
|
||||
suite = self.build_suite(self.test_labels)
|
||||
failures = super(IetfTestRunner, self).run_suite(suite, **kwargs)
|
||||
return failures
|
||||
|
||||
def run_tests(self, test_labels, extra_tests=None, **kwargs):
|
||||
# Tests that involve switching back and forth between the real
|
||||
# database and the test database are way too dangerous to run
|
||||
|
@ -1129,6 +1141,7 @@ class IetfTestRunner(DiscoverRunner):
|
|||
|
||||
self.test_apps, self.test_paths = self.get_test_paths(test_labels)
|
||||
|
||||
self.test_labels = test_labels # these are used in our run_suite() and not available to it otherwise
|
||||
failures = super(IetfTestRunner, self).run_tests(test_labels, extra_tests=extra_tests, **kwargs)
|
||||
|
||||
if self.check_coverage:
|
||||
|
|
Loading…
Reference in a new issue