Merged in personal/rjs/r6117-pubreq:
- Made Publication Request (for documents from IETF working groups) an explicit action rather than a side-effect. - Simplified the working group state edit form. - Added hints to the WG state edit form to use the document's main page to request publication. - If a document is moved into IESG processing directly by the secretariat or an AD (old processing path), set working group state accordingly. - Legacy-Id: 6120
This commit is contained in:
parent
2a2389d17f
commit
9dc13aa8f2
ietf
doc
ietfworkflows
templates
|
@ -328,6 +328,24 @@ class EditInfoTestCase(django.test.TestCase):
|
|||
self.assertEquals(events[-3].type, "started_iesg_process")
|
||||
self.assertEquals(len(outbox), mailbox_before)
|
||||
|
||||
# Redo, starting in publication requested to make sure WG state is also set
|
||||
draft.unset_state('draft-iesg')
|
||||
draft.set_state(State.objects.get(type='draft-stream-ietf',slug='writeupw'))
|
||||
draft.stream = StreamName.objects.get(slug='ietf')
|
||||
draft.save()
|
||||
r = self.client.post(url,
|
||||
dict(intended_std_level=str(draft.intended_std_level_id),
|
||||
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.assertEquals(r.status_code, 302)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEquals(draft.get_state_slug('draft-iesg'),'pub-req')
|
||||
self.assertEquals(draft.get_state_slug('draft-stream-ietf'),'sub-pub')
|
||||
|
||||
def test_edit_consensus(self):
|
||||
draft = make_test_data()
|
||||
|
||||
|
@ -867,6 +885,66 @@ class IndividualInfoFormsTestCase(django.test.TestCase):
|
|||
self.docname='draft-ietf-mars-test'
|
||||
self.doc = Document.objects.get(name=self.docname)
|
||||
|
||||
class SubmitToIesgTestCase(django.test.TestCase):
|
||||
fixtures = ['names']
|
||||
|
||||
def verify_permissions(self):
|
||||
|
||||
def verify_fail(remote_user):
|
||||
if remote_user:
|
||||
self.client.login(remote_user=remote_user)
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code,404)
|
||||
|
||||
def verify_can_see(remote_user):
|
||||
self.client.login(remote_user=remote_user)
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code,200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEquals(len(q('form input[name="confirm"]')),1)
|
||||
|
||||
url = urlreverse('doc_to_iesg', kwargs=dict(name=self.docname))
|
||||
|
||||
for username in [None,'plain','iana','iab chair']:
|
||||
verify_fail(username)
|
||||
|
||||
for username in ['marschairman','secretary','ad']:
|
||||
verify_can_see(username)
|
||||
|
||||
def cancel_submission(self):
|
||||
url = urlreverse('doc_to_iesg', kwargs=dict(name=self.docname))
|
||||
self.client.login(remote_user='marschairman')
|
||||
|
||||
r = self.client.post(url, dict(cancel="1"))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
doc = Document.objects.get(pk=self.doc.pk)
|
||||
self.assertTrue(doc.get_state('draft-iesg')==None)
|
||||
|
||||
def confirm_submission(self):
|
||||
url = urlreverse('doc_to_iesg', kwargs=dict(name=self.docname))
|
||||
self.client.login(remote_user='marschairman')
|
||||
|
||||
docevent_count_pre = self.doc.docevent_set.count()
|
||||
mailbox_before = len(outbox)
|
||||
|
||||
r = self.client.post(url, dict(confirm="1"))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
doc = Document.objects.get(pk=self.doc.pk)
|
||||
self.assertTrue(doc.get_state('draft-iesg').slug=='pub-req')
|
||||
self.assertTrue(doc.get_state('draft-stream-ietf').slug=='sub-pub')
|
||||
self.assertTrue(doc.ad!=None)
|
||||
self.assertTrue(doc.docevent_set.count() != docevent_count_pre)
|
||||
self.assertEquals(len(outbox), mailbox_before + 1)
|
||||
self.assertTrue("Publication has been requested" in outbox[-1]['Subject'])
|
||||
|
||||
def setUp(self):
|
||||
make_test_data()
|
||||
self.docname='draft-ietf-mars-test'
|
||||
self.doc = Document.objects.get(name=self.docname)
|
||||
self.doc.unset_state('draft-iesg')
|
||||
|
||||
class RequestPublicationTestCase(django.test.TestCase):
|
||||
fixtures = ['names']
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ urlpatterns = patterns('',
|
|||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/state/(?P<state_type>iana-action|iana-review)/$', views_draft.change_iana_state, name='doc_change_iana_state'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/info/$', views_draft.edit_info, name='doc_edit_info'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/requestresurrect/$', views_draft.request_resurrect, name='doc_request_resurrect'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/submit-to-iesg/$', views_draft.to_iesg, name='doc_to_iesg'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/resurrect/$', views_draft.resurrect, name='doc_resurrect'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/addcomment/$', views_doc.add_comment, name='doc_add_comment'),
|
||||
|
||||
|
|
|
@ -318,8 +318,11 @@ def document_main(request, name, rev=None):
|
|||
label += " (note that intended status is not set)"
|
||||
actions.append((label, urlreverse('doc_request_publication', kwargs=dict(name=doc.name))))
|
||||
|
||||
if doc.get_state_slug() != "expired" and doc.stream_id in ("ietf",) and can_edit and not iesg_state:
|
||||
actions.append(("Begin IESG Processing", urlreverse('doc_edit_info', kwargs=dict(name=doc.name)) + "?new=1"))
|
||||
if doc.get_state_slug() != "expired" and doc.stream_id in ("ietf",):
|
||||
if not iesg_state and can_edit:
|
||||
actions.append(("Begin IESG Processing", urlreverse('doc_edit_info', kwargs=dict(name=doc.name)) + "?new=1"))
|
||||
elif can_edit_stream_info and (not iesg_state or iesg_state.slug == 'watching'):
|
||||
actions.append(("Submit to IESG for Publication", urlreverse('doc_to_iesg', kwargs=dict(name=doc.name))))
|
||||
|
||||
return render_to_response("doc/document_draft.html",
|
||||
dict(doc=doc,
|
||||
|
|
|
@ -374,6 +374,105 @@ def get_initial_notify(doc):
|
|||
receivers.append("%s@%s" % (doc.name, settings.TOOLS_SERVER))
|
||||
return ", ".join(receivers)
|
||||
|
||||
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')
|
||||
|
||||
if doc.get_state_slug('draft') == "expired" or doc.get_state_slug('draft-iesg') == 'pub-req' :
|
||||
raise Http404()
|
||||
|
||||
if not is_authorized_in_doc_stream(request.user, doc):
|
||||
raise Http404()
|
||||
|
||||
target_state={
|
||||
'iesg' : State.objects.get(type='draft-iesg',slug='pub-req'),
|
||||
'wg' : State.objects.get(type='draft-stream-ietf',slug='sub-pub'),
|
||||
}
|
||||
|
||||
warn={}
|
||||
if not doc.intended_std_level:
|
||||
warn['intended_std_level'] = True
|
||||
if not doc.shepherd:
|
||||
warn['shepherd'] = True
|
||||
shepherd_writeup = doc.latest_event(WriteupDocEvent, type="changed_protocol_writeup")
|
||||
if not shepherd_writeup:
|
||||
warn['shepherd_writeup'] = True
|
||||
tags = doc.tags.filter(slug__in=get_tags_for_stream_id(doc.stream_id))
|
||||
if tags:
|
||||
warn['tags'] = True
|
||||
notify = doc.notify
|
||||
if not notify:
|
||||
notify = get_initial_notify(doc)
|
||||
ad = doc.ad or doc.group.ad
|
||||
|
||||
if request.method == 'POST':
|
||||
|
||||
if request.POST.get("confirm", ""):
|
||||
|
||||
save_document_in_history(doc)
|
||||
|
||||
login = request.user.get_profile()
|
||||
|
||||
changes = []
|
||||
|
||||
if not doc.get_state("draft-iesg"):
|
||||
|
||||
e = DocEvent()
|
||||
e.type = "started_iesg_process"
|
||||
e.by = login
|
||||
e.doc = doc
|
||||
e.desc = "IESG process started in state <b>%s</b>" % target_state['iesg'].name
|
||||
e.save()
|
||||
|
||||
if not doc.get_state('draft-iesg')==target_state['iesg']:
|
||||
doc.set_state(target_state['iesg'])
|
||||
changes.append("IESG state set to %s" % target_state['iesg'].name)
|
||||
if not doc.get_state('draft-ietf-stream')==target_state['wg']:
|
||||
doc.set_state(target_state['wg'])
|
||||
changes.append("Working group state set to %s" % target_state['wg'].name)
|
||||
|
||||
if not doc.ad == ad :
|
||||
doc.ad = ad
|
||||
changes.append("Responsible AD changed to %s" % doc.ad)
|
||||
|
||||
if not doc.notify == notify :
|
||||
doc.notify = notify
|
||||
changes.append("State Change Notice email list changed to %s" % doc.notify)
|
||||
|
||||
for c in changes:
|
||||
e = DocEvent(doc=doc, by=login)
|
||||
e.desc = c
|
||||
e.type = "changed_document"
|
||||
e.save()
|
||||
|
||||
# Is this still necessary? I remember Henrik planning to have the model take care of this.
|
||||
doc.time = datetime.datetime.now()
|
||||
|
||||
doc.save()
|
||||
|
||||
extra = {}
|
||||
extra['Cc'] = "%s-chairs@tools.ietf.org, iesg-secretary@ietf.org, %s" % (doc.group.acronym,doc.notify)
|
||||
send_mail(request=request,
|
||||
to = doc.ad.email_address(),
|
||||
frm = login.formatted_email(),
|
||||
subject = "Publication has been requested for %s-%s" % (doc.name,doc.rev),
|
||||
template = "doc/submit_to_iesg_email.txt",
|
||||
context = dict(doc=doc,login=login,url="%s%s"%(settings.IDTRACKER_BASE_URL,doc.get_absolute_url()),),
|
||||
extra = extra)
|
||||
|
||||
return HttpResponseRedirect(doc.get_absolute_url())
|
||||
|
||||
return render_to_response('doc/submit_to_iesg.html',
|
||||
dict(doc=doc,
|
||||
warn=warn,
|
||||
target_state=target_state,
|
||||
ad=ad,
|
||||
shepherd_writeup=shepherd_writeup,
|
||||
tags=tags,
|
||||
notify=notify,
|
||||
),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
@role_required('Area Director','Secretariat')
|
||||
def edit_info(request, name):
|
||||
"""Edit various Internet Draft attributes, notifying parties as
|
||||
|
@ -404,6 +503,18 @@ def edit_info(request, name):
|
|||
if new_document:
|
||||
doc.set_state(r['create_in_state'])
|
||||
|
||||
# Is setting the WG state here too much of a hidden side-effect?
|
||||
if r['create_in_state'].slug=='pub-req':
|
||||
if doc.stream and ( doc.stream.slug=='ietf' ) and doc.group and ( doc.group.type.name=='WG'):
|
||||
submitted_state = State.objects.get(type='draft-stream-ietf',slug='sub-pub')
|
||||
doc.set_state(submitted_state)
|
||||
e = DocEvent()
|
||||
e.type = "changed_document"
|
||||
e.by = login
|
||||
e.doc = doc
|
||||
e.desc = "Working group state set to %s" % submitted_state.name
|
||||
e.save()
|
||||
|
||||
# fix so Django doesn't barf in the diff below because these
|
||||
# fields can't be NULL
|
||||
doc.ad = r['ad']
|
||||
|
|
|
@ -156,9 +156,9 @@ class NoWorkflowStateForm(StreamDraftForm):
|
|||
|
||||
class DraftTagsStateForm(StreamDraftForm):
|
||||
|
||||
new_state = forms.ChoiceField(label='State')
|
||||
weeks = forms.IntegerField(label='Expected weeks in state',required=False)
|
||||
comment = forms.CharField(widget=forms.Textarea, required=False)
|
||||
new_state = forms.ChoiceField()
|
||||
weeks = forms.IntegerField(required=False)
|
||||
tags = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, required=False)
|
||||
|
||||
template = 'ietfworkflows/state_form.html'
|
||||
|
@ -167,6 +167,9 @@ class DraftTagsStateForm(StreamDraftForm):
|
|||
super(DraftTagsStateForm, self).__init__(*args, **kwargs)
|
||||
self.state = get_state_for_draft(self.draft)
|
||||
self.fields['new_state'].choices = self.get_states()
|
||||
self.fields['new_state'].initial = self.state.pk
|
||||
if self.draft.stream_id == 'ietf':
|
||||
self.fields['new_state'].help_text = "Only select 'Submitted to IESG for Publication' to correct errors. Use the document's main page to request publication."
|
||||
if self.is_bound:
|
||||
for key, value in self.data.items():
|
||||
if key.startswith('transition_'):
|
||||
|
|
|
@ -72,7 +72,6 @@ class EditStreamInfoTestCase(django.test.TestCase):
|
|||
unused = draft.group.unused_tags.values_list("slug", flat=True)
|
||||
for t in q("input[name=tags]"):
|
||||
self.assertTrue(t.attrib["value"] not in unused)
|
||||
self.assertEquals(len(q('form input[type=submit][name=only_tags]')), 1)
|
||||
|
||||
# set tags
|
||||
mailbox_before = len(outbox)
|
||||
|
@ -115,10 +114,26 @@ class EditStreamInfoTestCase(django.test.TestCase):
|
|||
self.assertTrue(t.attrib["value"] not in unused)
|
||||
self.assertEquals(len(q('select[name=new_state]')), 1)
|
||||
|
||||
# set state
|
||||
old_state = draft.get_state("draft-stream-%s" % draft.stream_id )
|
||||
new_state = State.objects.get(used=True, type="draft-stream-%s" % draft.stream_id, slug="parked")
|
||||
self.assertTrue(old_state!=new_state)
|
||||
mailbox_before = len(outbox)
|
||||
events_before = draft.docevent_set.count()
|
||||
|
||||
# First make sure cancel doesn't change anything
|
||||
r = self.client.post(url,
|
||||
dict(comment="some comment",
|
||||
weeks="10",
|
||||
tags=[x.pk for x in draft.tags.filter(slug__in=get_tags_for_stream_id(draft.stream_id))],
|
||||
new_state=new_state.pk,
|
||||
cancel="1",
|
||||
))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
draft = Document.objects.get(pk=draft.pk)
|
||||
self.assertEquals(draft.get_state("draft-stream-%s" % draft.stream_id), old_state)
|
||||
|
||||
# Set new state
|
||||
r = self.client.post(url,
|
||||
dict(comment="some comment",
|
||||
weeks="10",
|
||||
|
|
|
@ -70,12 +70,16 @@ def _edit_draft_stream(request, draft, form_class=DraftTagsStateForm):
|
|||
if request.method == 'POST':
|
||||
form = form_class(user=user, draft=draft, data=request.POST)
|
||||
form.request = request
|
||||
if request.POST.get("cancel",""):
|
||||
return HttpResponseRedirect(draft.get_absolute_url())
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
if form_class == NoWorkflowStateForm and settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
return HttpResponseRedirect(urlreverse('ietf.ietfworkflows.views.edit_state', kwargs={ 'name': draft.filename } ))
|
||||
|
||||
# This behavior surprises folks. Let's try running awhile without it.
|
||||
#if form_class == NoWorkflowStateForm and settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
# return HttpResponseRedirect(urlreverse('ietf.ietfworkflows.views.edit_state', kwargs={ 'name': draft.filename } ))
|
||||
|
||||
return HttpResponseRedirect('.')
|
||||
return HttpResponseRedirect(draft.get_absolute_url())
|
||||
else:
|
||||
form = form_class(user=user, draft=draft)
|
||||
form.request = request
|
||||
|
|
80
ietf/templates/doc/submit_to_iesg.html
Normal file
80
ietf/templates/doc/submit_to_iesg.html
Normal file
|
@ -0,0 +1,80 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}
|
||||
Publication Request for {{doc.name}}-{{doc.rev}}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Publication Request for {{doc.name}}-{{doc.rev}}</h1>
|
||||
|
||||
<div>
|
||||
Please verify the following information:
|
||||
</div>
|
||||
|
||||
<div style="margin-left:10px;margin-top:20px;margin-bottom:20px;">
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
<td>Intended Status Level:</td>
|
||||
<td>{% if warn.intended_std_level %}<img src="/images/warning.png"/>{% endif %}</td>
|
||||
<td>{{doc.intended_std_level}}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Responsible AD:</td>
|
||||
<td></td>
|
||||
<td>{{ad}}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Document Shepherd:</td>
|
||||
<td>{% if warn.shepherd %}<img src="/images/warning.png"/>{% endif %}</td>
|
||||
<td>{{doc.shepherd}}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Shepherd Write-Up Exists:</td>
|
||||
<td>{% if warn.shepherd_writeup %}<img src="/images/warning.png"/>{% endif %}</td>
|
||||
<td>{%if shepherd_writeup %}Yes{%else%}No{%endif%}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Also Notify:</td>
|
||||
<td></td>
|
||||
<td>{% if notify %}{{notify}}{%else%}(None){%endif%}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Annotation Tags:</td>
|
||||
<td>{% if warn.tags %}<img src="/images/warning.png"/>{% endif %}</td>
|
||||
<td>{% if not tags %}(None){%else%}{% for tag in tags %}{{ tag }}{% if not forloop.last%}, {%endif%}{% endfor %}{% endif %}</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{% if warn %}
|
||||
<div style="margin-top:20px; margin-bottom:20px;">
|
||||
<img src="/images/warning.png"/> indicates the document might not be ready for submission. Please check each instance carefully to see if changes need to be made to the document's state before submitting.
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
Upon submission:
|
||||
<ul>
|
||||
<li> the document will be placed into the IESG '{{target_state.iesg}}' state</li>
|
||||
<li> the document will be placed into the working group '{{target_state.wg}}' state</li>
|
||||
{% if not ad == doc.ad %}<li> the responsible AD will be set as above </li>{% endif %}
|
||||
{% if not notify == doc.notify %}<li> the document's state change notification list will be set as above </li>{% endif %}
|
||||
<li> an entry will be made noting the publication request in the document's history</li>
|
||||
<li> an email message will be sent to the working group chairs, the secretariat, and everyone listed above</li>
|
||||
</div>
|
||||
|
||||
<form action="" method="POST">
|
||||
<input type="submit" name="confirm" value="Request Publication"/>
|
||||
<input type="submit" name="cancel" value="Cancel"/>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
4
ietf/templates/doc/submit_to_iesg_email.txt
Normal file
4
ietf/templates/doc/submit_to_iesg_email.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
{{login}} has requested publication of {{doc.name}}-{{doc.rev}} as {{doc.intended_std_level}} on behalf of the {{doc.group.acronym|upper}} working group.
|
||||
|
||||
Please verify the document's state at {{url}}
|
||||
|
|
@ -17,6 +17,16 @@ table.edit-form-tags tr { vertical-align: top; }
|
|||
table.edit-form-tags textarea { height: 200px; }
|
||||
table.edit-form-tags ul { border-width: 0px; padding: 0px 2em; }
|
||||
table.edit-form-tags ul li { padding: 0px; }
|
||||
|
||||
#new-edit-form { clear:both; padding-top: 1em; }
|
||||
#new-edit-form th { padding-left:0; max-width: 8em;}
|
||||
#new-edit-form #id_comment { width: 30em; height: 5em; }
|
||||
#new-edit-form #id_weeks { width: 2em;}
|
||||
#new-edit-form ul {list-style-type: none; padding-left:0; margin-top:0; margin-bottom:0; }
|
||||
.rec-state-header { float:left; padding-left:2px; padding-right:.5em; }
|
||||
.rec-statelist {list-style-type: none; padding-left:0; margin-top:0; margin-bottom:0; }
|
||||
.rec-state { float:left; padding-right:.5em; }
|
||||
|
||||
{% endblock morecss %}
|
||||
|
||||
{% block title %}Change state for {{ draft }}{% endblock %}
|
||||
|
@ -24,12 +34,6 @@ table.edit-form-tags ul li { padding: 0px; }
|
|||
{% block content %}
|
||||
<h1>Change state for {{ draft }}</h1>
|
||||
|
||||
<div class="return-to-document">
|
||||
<p>
|
||||
<a href="{% url doc_view draft.filename %}">Return to document view</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{% if state and state.slug == "wg-doc" and not milestones %}
|
||||
<p>This document is not part of any milestone. You may wish to <a href="{% url wg_edit_milestones acronym=draft.group.acronym %}">add it to one</a>.</p>
|
||||
{% endif %}
|
||||
|
@ -42,42 +46,6 @@ submitted to IESG for publication, you may wish to
|
|||
milestone{{ milestones|pluralize }}</a>.</p>
|
||||
{% endif %}
|
||||
|
||||
<table class="ietf-table" style="width: 100%;">
|
||||
<tr>
|
||||
<th>Current stream</th>
|
||||
<th>Current state</th>
|
||||
<th>Annotation tags</th>
|
||||
</tr>
|
||||
<tr><td style="width: 25%;">
|
||||
{{ stream.name|default:"None" }}
|
||||
</td>
|
||||
<td style="width: 25%;">
|
||||
{{ state.name|default:"None" }}
|
||||
</td><td>
|
||||
<ul style="list-style-type: none; padding: 0px;">
|
||||
{% for tag in tags%}
|
||||
<li>{{ tag.annotation_tag }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</td></tr></table>
|
||||
<br />
|
||||
|
||||
{{ form }}
|
||||
|
||||
<br />
|
||||
<strong>State history</strong>
|
||||
<table class="ietf-table state-history" style="width: 100%">
|
||||
{% if history %}
|
||||
<tr><th>Date</th><th>Person</th><th>Change</th><th>Comment</th></tr>
|
||||
{% for baseentry in history %}
|
||||
{% with baseentry.get_real_instance as entry %}
|
||||
<tr class="{% cycle oddrow,evenrow %}"><td>{{ entry.date }}</td><td>{{ entry.person }}</td>
|
||||
<td>{{ entry.describe_change|safe }}</td><td>{{ entry.comment }}</td>
|
||||
</tr>
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr><td>There is no state history for this document.</td></th>
|
||||
{% endif %}
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,73 +1,32 @@
|
|||
<form action="" method="post">
|
||||
<table class="ietf-table edit-form" style="width: 100%;">
|
||||
<tr>
|
||||
<th>1. Input information about change</th>
|
||||
<th>2. Change annotation tags if needed</th>
|
||||
</tr>
|
||||
<tr style="vertical-align: top;"><td style="width: 50%;">
|
||||
<div class="field{% if form.comment.errors %} error{% endif %}">
|
||||
{{ form.comment.errors }}
|
||||
Comment: <br/>
|
||||
<textarea name="comment">{{ form.data.comment }}</textarea>
|
||||
</div>
|
||||
<div class="field{% if form.weeks.errors %} error{% endif %}">
|
||||
{{ form.weeks.errors }}
|
||||
Estimated time in next status:<br />
|
||||
<input type="text" name="weeks" value="{{ form.data.weeks }}" /> (in weeks)
|
||||
</div>
|
||||
</td><td>
|
||||
<div class="field">
|
||||
{{ form.tags }}
|
||||
</div>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
<br />
|
||||
|
||||
<table class="ietf-table edit-form edit-form-tags" style="width: 100%;">
|
||||
<tr>
|
||||
<th>3. Select one action</th>
|
||||
</tr>
|
||||
<tr><td>
|
||||
<div class="only-tags field">
|
||||
<ul>
|
||||
<li><input type="submit" name="only_tags" value="Update annotation tags" /> State remains unchanged: <strong>{{ form.state.name }}</strong></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% with form.get_transitions as transitions %}
|
||||
{% if transitions %}
|
||||
<ul>
|
||||
{% for transition in transitions %}
|
||||
<li class="{% cycle oddrow,evenrow %}">
|
||||
<input type="submit" name="transition_{{ transition.pk }}" value="{{ transition.name }}" />
|
||||
Changes state to: <strong>{{ transition.destination.name }}</strong>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endwith %}
|
||||
|
||||
<div class="rec-states">
|
||||
{% with form.get_next_states as next_states %}
|
||||
{% if next_states %}
|
||||
<ul>
|
||||
Jump to the next state:
|
||||
{% for state in next_states %}
|
||||
<input type="submit" name="new_state_{{ state.pk }}" value="{{ state.name }}" />
|
||||
<span class="rec-state-header">Recommended next state{{next_states|pluralize}}:</span>
|
||||
<ul class="rec-statelist">
|
||||
{% for state in next_states %}
|
||||
<li class="rec-state">'{{ state.name }}'{% if not forloop.last %}, {% endif %}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endwith %}
|
||||
</div>
|
||||
|
||||
<div class="free-change field{% if form.new_state.errors %} error{% endif %}">
|
||||
{{ form.new_state.errors }}
|
||||
Change to another state:
|
||||
<select name="new_state">
|
||||
{% for value, name in form.get_states %}
|
||||
<option value="{{ value }}">{{ name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input type="submit" name="change" value="Change state" />
|
||||
</div>
|
||||
</td></tr>
|
||||
<table id="new-edit-form">
|
||||
{% for field in form.visible_fields %}
|
||||
<tr>
|
||||
<th>{{ field.label_tag }}:</th>
|
||||
<td>{{ field }}
|
||||
{% if field.help_text %}<div class="help">{{ field.help_text }}</div>{% endif %}
|
||||
|
||||
{{ field.errors }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<div class="actions">
|
||||
<input type="submit" name="save" value="Save" />
|
||||
<input type="submit" name="cancel" value="Cancel" />
|
||||
</div>
|
||||
</form>
|
||||
|
|
Loading…
Reference in a new issue