feat: remove "AD is watching" state (#7960)

* feat: remove "AD is watching" state

* chore: update names.json

* refactor: use idexists state, not dead

* fix: remove guidance to use watching state

* chore: remove references to 'watching' state

* feat: remove create_in_state from edit_info view

* test: update test

* style: Black + move class closer to use

* refactor: remove lint

* fix: restore missing admonition

---------

Co-authored-by: Robert Sparks <rjsparks@nostrum.com>
This commit is contained in:
Jennifer Richards 2024-09-24 14:13:12 -03:00 committed by GitHub
parent 5ea4cc13bb
commit fbcfa19add
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 311 additions and 146 deletions

View file

@ -34,8 +34,8 @@ def expirable_drafts(queryset=None):
# Populate this first time through (but after django has been set up)
if nonexpirable_states is None:
# all IESG states except I-D Exists, AD Watching, and Dead block expiry
nonexpirable_states = list(State.objects.filter(used=True, type="draft-iesg").exclude(slug__in=("idexists","watching", "dead")))
# all IESG states except I-D Exists and Dead block expiry
nonexpirable_states = list(State.objects.filter(used=True, type="draft-iesg").exclude(slug__in=("idexists", "dead")))
# sent to RFC Editor and RFC Published block expiry (the latter
# shouldn't be possible for an active draft, though)
nonexpirable_states += list(State.objects.filter(used=True, type__in=("draft-stream-iab", "draft-stream-irtf", "draft-stream-ise"), slug__in=("rfc-edit", "pub")))

View file

@ -0,0 +1,121 @@
# Copyright The IETF Trust 2024, All Rights Reserved
from django.db import migrations
def get_helper(DocHistory, RelatedDocument, RelatedDocHistory, DocumentAuthor, DocHistoryAuthor):
"""Dependency injection wrapper"""
def save_document_in_history(doc):
"""Save a snapshot of document and related objects in the database.
Local copy of ietf.doc.utils.save_document_in_history() to avoid depending on the
code base in a migration.
"""
def get_model_fields_as_dict(obj):
return dict((field.name, getattr(obj, field.name))
for field in obj._meta.fields
if field is not obj._meta.pk)
# copy fields
fields = get_model_fields_as_dict(doc)
fields["doc"] = doc
fields["name"] = doc.name
dochist = DocHistory(**fields)
dochist.save()
# copy many to many
for field in doc._meta.many_to_many:
if field.remote_field.through and field.remote_field.through._meta.auto_created:
hist_field = getattr(dochist, field.name)
hist_field.clear()
hist_field.set(getattr(doc, field.name).all())
# copy remaining tricky many to many
def transfer_fields(obj, HistModel):
mfields = get_model_fields_as_dict(item)
# map doc -> dochist
for k, v in mfields.items():
if v == doc:
mfields[k] = dochist
HistModel.objects.create(**mfields)
for item in RelatedDocument.objects.filter(source=doc):
transfer_fields(item, RelatedDocHistory)
for item in DocumentAuthor.objects.filter(document=doc):
transfer_fields(item, DocHistoryAuthor)
return dochist
return save_document_in_history
def forward(apps, schema_editor):
"""Mark watching draft-iesg state unused after removing it from Documents"""
StateDocEvent = apps.get_model("doc", "StateDocEvent")
Document = apps.get_model("doc", "Document")
State = apps.get_model("doc", "State")
StateType = apps.get_model("doc", "StateType")
Person = apps.get_model("person", "Person")
save_document_in_history = get_helper(
DocHistory=apps.get_model("doc", "DocHistory"),
RelatedDocument=apps.get_model("doc", "RelatedDocument"),
RelatedDocHistory=apps.get_model("doc", "RelatedDocHistory"),
DocumentAuthor=apps.get_model("doc", "DocumentAuthor"),
DocHistoryAuthor=apps.get_model("doc", "DocHistoryAuthor"),
)
draft_iesg_state_type = StateType.objects.get(slug="draft-iesg")
idexists_state = State.objects.get(type=draft_iesg_state_type, slug="idexists")
watching_state = State.objects.get(type=draft_iesg_state_type, slug="watching")
system_person = Person.objects.get(name="(System)")
# Remove state from documents that currently have it
for doc in Document.objects.filter(states=watching_state):
assert doc.type_id == "draft"
doc.states.remove(watching_state)
doc.states.add(idexists_state)
e = StateDocEvent.objects.create(
type="changed_state",
by=system_person,
doc=doc,
rev=doc.rev,
desc=f"{draft_iesg_state_type.label} changed to <b>{idexists_state.name}</b> from {watching_state.name}",
state_type=draft_iesg_state_type,
state=idexists_state,
)
doc.time = e.time
doc.save()
save_document_in_history(doc)
assert not Document.objects.filter(states=watching_state).exists()
# Mark state as unused
watching_state.used = False
watching_state.save()
def reverse(apps, schema_editor):
"""Mark watching draft-iesg state as used
Does not try to re-apply the state to Documents modified by the forward migration. This
could be done in theory, but would either require dangerous history rewriting or add a
lot of history junk.
"""
State = apps.get_model("doc", "State")
StateType = apps.get_model("doc", "StateType")
State.objects.filter(
type=StateType.objects.get(slug="draft-iesg"), slug="watching"
).update(used=True)
class Migration(migrations.Migration):
dependencies = [
("doc", "0023_bofreqspamstate"),
]
operations = [migrations.RunPython(forward, reverse)]

View file

@ -184,7 +184,7 @@ def state_age_colored(doc):
if not iesg_state:
return ""
if iesg_state in ["dead", "watching", "pub", "idexists"]:
if iesg_state in ["dead", "pub", "idexists"]:
return ""
try:
state_datetime = (

View file

@ -559,7 +559,7 @@ class BallotWriteupsTests(TestCase):
q = PyQuery(r.content)
self.assertFalse(q('[class=text-danger]:contains("not completed IETF Last Call")'))
for state_slug in ["lc", "watching", "ad-eval"]:
for state_slug in ["lc", "ad-eval"]:
draft.set_state(State.objects.get(type="draft-iesg",slug=state_slug))
r = self.client.get(url)
self.assertEqual(r.status_code, 200)

View file

@ -26,7 +26,7 @@ from ietf.doc.models import ( Document, DocReminder, DocEvent,
WriteupDocEvent, DocRelationshipName, IanaExpertDocEvent )
from ietf.doc.utils import get_tags_for_stream_id, create_ballot_if_not_open
from ietf.doc.views_draft import AdoptDraftForm
from ietf.name.models import StreamName, DocTagName, RoleName
from ietf.name.models import DocTagName, RoleName
from ietf.group.factories import GroupFactory, RoleFactory
from ietf.group.models import Group, Role
from ietf.person.factories import PersonFactory, EmailFactory
@ -471,69 +471,61 @@ class EditInfoTests(TestCase):
self.assertIn("may not leave enough time", get_payload_text(outbox[-1]))
def test_start_iesg_process_on_draft(self):
draft = WgDraftFactory(
name="draft-ietf-mars-test2",
group__acronym='mars',
group__acronym="mars",
intended_std_level_id="ps",
authors=[Person.objects.get(user__username='ad')],
)
url = urlreverse('ietf.doc.views_draft.edit_info', kwargs=dict(name=draft.name))
authors=[Person.objects.get(user__username="ad")],
)
url = urlreverse("ietf.doc.views_draft.edit_info", kwargs=dict(name=draft.name))
login_testing_unauthorized(self, "secretary", url)
# normal get
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
q = PyQuery(r.content)
self.assertEqual(len(q('form select[name=intended_std_level]')), 1)
self.assertEqual("", q('form textarea[name=notify]')[0].value.strip())
self.assertEqual(len(q("form select[name=intended_std_level]")), 1)
self.assertEqual("", q("form textarea[name=notify]")[0].value.strip())
# add
events_before = draft.docevent_set.count()
events_before = list(draft.docevent_set.values_list("id", flat=True))
mailbox_before = len(outbox)
ad = Person.objects.get(name="Areað Irector")
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="watching").pk,
notify="test@example.com",
telechat_date="",
))
r = self.client.post(
url,
dict(
intended_std_level=str(draft.intended_std_level_id),
ad=ad.pk,
notify="test@example.com",
telechat_date="",
),
)
self.assertEqual(r.status_code, 302)
draft = Document.objects.get(name=draft.name)
self.assertEqual(draft.get_state_slug("draft-iesg"), "watching")
self.assertEqual(draft.get_state_slug("draft-iesg"), "pub-req")
self.assertEqual(draft.get_state_slug("draft-stream-ietf"), "sub-pub")
self.assertEqual(draft.ad, ad)
self.assertTrue(not draft.latest_event(TelechatDocEvent, type="scheduled_for_telechat"))
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[-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'])
# Redo, starting in publication requested to make sure WG state is also set
draft.set_state(State.objects.get(type_id='draft-iesg', slug='idexists'))
draft.set_state(State.objects.get(type='draft-stream-ietf',slug='writeupw'))
draft.stream = StreamName.objects.get(slug='ietf')
draft.action_holders.clear()
draft.save_with_history([DocEvent.objects.create(doc=draft, rev=draft.rev, type="changed_stream", by=Person.objects.get(user__username="secretary"), desc="Test")])
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",
telechat_date="",
))
self.assertEqual(r.status_code, 302)
draft = Document.objects.get(name=draft.name)
self.assertEqual(draft.get_state_slug('draft-iesg'),'pub-req')
self.assertEqual(draft.get_state_slug('draft-stream-ietf'),'sub-pub')
self.assertTrue(
not draft.latest_event(TelechatDocEvent, type="scheduled_for_telechat")
)
# check that the expected events were created (don't insist on ordering)
self.assertCountEqual(
draft.docevent_set.exclude(id__in=events_before).values_list("type", flat=True),
[
"changed_action_holders", # action holders set to AD
"changed_document", # WG state set to sub-pub
"changed_document", # AD set
"changed_document", # state change notice email set
"started_iesg_process", # IESG state is now pub-req
],
)
self.assertCountEqual(draft.action_holders.all(), [draft.ad])
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"])
def test_edit_consensus(self):
draft = WgDraftFactory()
@ -750,10 +742,6 @@ class ExpireIDsTests(DraftFileMixin, TestCase):
self.assertEqual(len(list(get_expired_drafts())), 1)
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="watching"))
self.assertEqual(len(list(get_expired_drafts())), 1)
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="iesg-eva"))
self.assertEqual(len(list(get_expired_drafts())), 0)

View file

@ -641,7 +641,7 @@ def ballot_writeupnotes(request, name):
existing.save()
if "issue_ballot" in request.POST and not ballot_already_approved:
if prev_state.slug in ['watching', 'writeupw', 'goaheadw']:
if prev_state.slug in ['writeupw', 'goaheadw']:
new_state = State.objects.get(used=True, type="draft-iesg", slug='iesg-eva')
prev_tags = doc.tags.filter(slug__in=IESG_SUBSTATE_TAGS)
doc.set_state(new_state)
@ -708,7 +708,7 @@ def ballot_writeupnotes(request, name):
back_url=doc.get_absolute_url(),
ballot_issued=bool(doc.latest_event(type="sent_ballot_announcement")),
warn_lc = not doc.docevent_set.filter(lastcalldocevent__expires__date__lt=date_today(DEADLINE_TZINFO)).exists(),
warn_unexpected_state= prev_state if bool(prev_state.slug in ['watching', 'ad-eval', 'lc']) else None,
warn_unexpected_state= prev_state if bool(prev_state.slug in ['ad-eval', 'lc']) else None,
ballot_writeup_form=form,
need_intended_status=need_intended_status,
))

View file

@ -587,7 +587,7 @@ def document_main(request, name, rev=None, document_html=False):
if doc.get_state_slug() not in ["rfc", "expired"] and doc.stream_id in ("ietf",) and not snapshot:
if iesg_state_slug == 'idexists' and can_edit:
actions.append(("Begin IESG Processing", urlreverse('ietf.doc.views_draft.edit_info', kwargs=dict(name=doc.name)) + "?new=1"))
elif can_edit_stream_info and (iesg_state_slug in ('idexists','watching')):
elif can_edit_stream_info and (iesg_state_slug == 'idexists'):
actions.append(("Submit to IESG for Publication", urlreverse('ietf.doc.views_draft.to_iesg', kwargs=dict(name=doc.name))))
if request.user.is_authenticated and hasattr(request.user, "person"):

View file

@ -487,40 +487,6 @@ def change_intention(request, name):
doc=doc,
))
class EditInfoForm(forms.Form):
intended_std_level = forms.ModelChoiceField(IntendedStdLevelName.objects.filter(used=True), empty_label="(None)", required=True, label="Intended RFC status")
area = forms.ModelChoiceField(Group.objects.filter(type="area", state="active"), empty_label="(None - individual submission)", required=False, label="Assigned to area")
ad = forms.ModelChoiceField(Person.objects.filter(role__name="ad", role__group__state="active",role__group__type='area').order_by('name'), label="Responsible AD", empty_label="(None)", required=True)
create_in_state = forms.ModelChoiceField(State.objects.filter(used=True, type="draft-iesg", slug__in=("pub-req", "watching")), empty_label=None, required=False)
notify = forms.CharField(
widget=forms.Textarea,
max_length=1023,
label="Notice emails",
help_text="Separate email addresses with commas.",
required=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)
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
# if previous AD is now ex-AD, append that person to the list
ad_pk = self.initial.get('ad')
choices = self.fields['ad'].choices
if ad_pk and ad_pk not in [pk for pk, name in choices]:
self.fields['ad'].choices = list(choices) + [("", "-------"), (ad_pk, Person.objects.get(pk=ad_pk).plain_name())]
# telechat choices
dates = [d.date for d in TelechatDate.objects.active().order_by('date')]
init = kwargs['initial']['telechat_date']
if init and init not in dates:
dates.insert(0, init)
self.fields['telechat_date'].choices = [("", "(not on agenda)")] + [(d, d.strftime("%Y-%m-%d")) for d in dates]
# returning item is rendered non-standard
self.standard_fields = [x for x in self.visible_fields() if x.name not in ('returning_item',)]
def to_iesg(request,name):
""" Submit an IETF stream document to the IESG for publication """
@ -619,7 +585,71 @@ def to_iesg(request,name):
notify=notify,
))
@role_required('Area Director','Secretariat')
class EditInfoForm(forms.Form):
intended_std_level = forms.ModelChoiceField(
IntendedStdLevelName.objects.filter(used=True),
empty_label="(None)",
required=True,
label="Intended RFC status",
)
area = forms.ModelChoiceField(
Group.objects.filter(type="area", state="active"),
empty_label="(None - individual submission)",
required=False,
label="Assigned to area",
)
ad = forms.ModelChoiceField(
Person.objects.filter(
role__name="ad", role__group__state="active", role__group__type="area"
).order_by("name"),
label="Responsible AD",
empty_label="(None)",
required=True,
)
notify = forms.CharField(
widget=forms.Textarea,
max_length=1023,
label="Notice emails",
help_text="Separate email addresses with commas.",
required=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)
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
# if previous AD is now ex-AD, append that person to the list
ad_pk = self.initial.get("ad")
choices = self.fields["ad"].choices
if ad_pk and ad_pk not in [pk for pk, name in choices]:
self.fields["ad"].choices = list(choices) + [
("", "-------"),
(ad_pk, Person.objects.get(pk=ad_pk).plain_name()),
]
# telechat choices
dates = [d.date for d in TelechatDate.objects.active().order_by("date")]
init = kwargs["initial"]["telechat_date"]
if init and init not in dates:
dates.insert(0, init)
self.fields["telechat_date"].choices = [("", "(not on agenda)")] + [
(d, d.strftime("%Y-%m-%d")) for d in dates
]
# returning item is rendered non-standard
self.standard_fields = [
x for x in self.visible_fields() if x.name not in ("returning_item",)
]
@role_required("Area Director", "Secretariat")
def edit_info(request, name):
"""Edit various Internet-Draft attributes, notifying parties as
necessary and logging changes as document events."""
@ -628,7 +658,8 @@ def edit_info(request, name):
raise Http404
new_document = False
if doc.get_state_slug("draft-iesg") == "idexists": # FIXME: should probably receive "new document" as argument to view instead of this
# FIXME: should probably receive "new document" as argument to view instead of this
if doc.get_state_slug("draft-iesg") == "idexists":
new_document = True
doc.notify = get_initial_notify(doc)
@ -636,34 +667,45 @@ def edit_info(request, name):
initial_telechat_date = e.telechat_date if e else None
initial_returning_item = bool(e and e.returning_item)
if request.method == 'POST':
form = EditInfoForm(request.POST,
initial=dict(ad=doc.ad_id,
telechat_date=initial_telechat_date))
if request.method == "POST":
form = EditInfoForm(
request.POST,
initial=dict(ad=doc.ad_id, telechat_date=initial_telechat_date),
)
if form.is_valid():
by = request.user.person
pubreq_state = State.objects.get(type="draft-iesg", slug="pub-req")
r = form.cleaned_data
events = []
if new_document:
doc.set_state(r['create_in_state'])
doc.set_state(pubreq_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_id == '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 = by
e.doc = doc
e.rev = doc.rev
e.desc = "Working group state set to %s" % submitted_state.name
e.save()
events.append(e)
if (
doc.stream
and doc.stream.slug == "ietf"
and doc.group
and doc.group.type_id == "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 = by
e.doc = doc
e.rev = doc.rev
e.desc = "Working group state set to %s" % submitted_state.name
e.save()
events.append(e)
replaces = Document.objects.filter(targets_related__source=doc, targets_related__relationship="replaces")
replaces = Document.objects.filter(
targets_related__source=doc,
targets_related__relationship="replaces",
)
if replaces:
# this should perhaps be somewhere else, e.g. the
# place where the replace relationship is established?
@ -672,7 +714,10 @@ def edit_info(request, name):
e.by = Person.objects.get(name="(System)")
e.doc = doc
e.rev = doc.rev
e.desc = "Earlier history may be found in the Comment Log for <a href=\"%s\">%s</a>" % (replaces[0], replaces[0].get_absolute_url())
e.desc = (
'Earlier history may be found in the Comment Log for <a href="%s">%s</a>'
% (replaces[0], replaces[0].get_absolute_url())
)
e.save()
events.append(e)
@ -681,7 +726,10 @@ def edit_info(request, name):
e.by = by
e.doc = doc
e.rev = doc.rev
e.desc = "Document is now in IESG state <b>%s</b>" % doc.get_state("draft-iesg").name
e.desc = (
"Document is now in IESG state <b>%s</b>"
% doc.get_state("draft-iesg").name
)
e.save()
events.append(e)
@ -691,9 +739,9 @@ def edit_info(request, name):
entry = "%(attr)s changed to <b>%(new)s</b> from <b>%(old)s</b>"
if new_document:
entry = "%(attr)s changed to <b>%(new)s</b>"
return entry % dict(attr=attr, new=new, old=old)
def diff(attr, name):
v = getattr(doc, attr)
if r[attr] != v:
@ -701,9 +749,9 @@ def edit_info(request, name):
setattr(doc, attr, r[attr])
# update the attributes, keeping track of what we're doing
diff('intended_std_level', "Intended Status")
diff('ad', "Responsible AD")
diff('notify', "State Change Notice email list")
diff("intended_std_level", "Intended Status")
diff("ad", "Responsible AD")
diff("notify", "State Change Notice email list")
if doc.group.type_id in ("individ", "area"):
if not r["area"]:
@ -717,12 +765,16 @@ def edit_info(request, name):
doc.group = r["area"]
for c in changes:
events.append(DocEvent.objects.create(doc=doc, rev=doc.rev, by=by, desc=c, type="changed_document"))
events.append(
DocEvent.objects.create(
doc=doc, rev=doc.rev, by=by, desc=c, type="changed_document"
)
)
# Todo - chase this
e = update_telechat(request, doc, by,
r['telechat_date'], r['returning_item'])
e = update_telechat(
request, doc, by, r["telechat_date"], r["returning_item"]
)
if e:
events.append(e)
@ -730,40 +782,44 @@ def edit_info(request, name):
if new_document:
# If we created a new doc, update the action holders as though it
# started in idexists and moved to its create_in_state. Do this
# started in idexists and moved to pub-req. Do this
# after the doc has been updated so, e.g., doc.ad is set.
update_action_holders(
doc,
State.objects.get(type='draft-iesg', slug='idexists'),
r['create_in_state']
State.objects.get(type="draft-iesg", slug="idexists"),
pubreq_state,
)
if changes:
email_iesg_processing_document(request, doc, changes)
return HttpResponseRedirect(doc.get_absolute_url())
else:
init = dict(intended_std_level=doc.intended_std_level_id,
area=doc.group_id,
ad=doc.ad_id,
notify=doc.notify,
telechat_date=initial_telechat_date,
returning_item=initial_returning_item,
)
init = dict(
intended_std_level=doc.intended_std_level_id,
area=doc.group_id,
ad=doc.ad_id,
notify=doc.notify,
telechat_date=initial_telechat_date,
returning_item=initial_returning_item,
)
form = EditInfoForm(initial=init)
# optionally filter out some fields
if not new_document:
form.standard_fields = [x for x in form.standard_fields if x.name != "create_in_state"]
if doc.group.type_id not in ("individ", "area"):
form.standard_fields = [x for x in form.standard_fields if x.name != "area"]
return render(request, 'doc/draft/edit_info.html',
dict(doc=doc,
form=form,
user=request.user,
ballot_issued=doc.latest_event(type="sent_ballot_announcement")))
return render(
request,
"doc/draft/edit_info.html",
dict(
doc=doc,
form=form,
user=request.user,
ballot_issued=doc.latest_event(type="sent_ballot_announcement"),
),
)
@role_required('Area Director','Secretariat')
def request_resurrect(request, name):

View file

@ -757,7 +757,7 @@ def drafts_in_last_call(request):
})
def drafts_in_iesg_process(request):
states = State.objects.filter(type="draft-iesg").exclude(slug__in=('idexists', 'pub', 'dead', 'watching', 'rfcqueue'))
states = State.objects.filter(type="draft-iesg").exclude(slug__in=('idexists', 'pub', 'dead', 'rfcqueue'))
title = "Documents in IESG process"
grouped_docs = []

View file

@ -731,7 +731,7 @@ def dependencies(request, acronym, group_type=None):
{
"id": x.became_rfc().name if x.became_rfc() else x.name,
"rfc": x.type_id == "rfc" or x.became_rfc() is not None,
"post-wg": x.get_state_slug("draft-iesg") not in ["idexists", "watching", "dead"],
"post-wg": x.get_state_slug("draft-iesg") not in ["idexists", "dead"],
"expired": x.get_state_slug("draft") == "expired",
"replaced": x.get_state_slug("draft") == "repl",
"group": x.group.acronym if x.group and x.group.acronym != "none" else "",

View file

@ -51,7 +51,7 @@ def all_id_txt():
res.append(f1 + "\t" + f2 + "\t" + f3 + "\t" + f4)
inactive_states = ["idexists", "pub", "watching", "dead"]
inactive_states = ["idexists", "pub", "dead"]
excludes = list(State.objects.filter(type="draft", slug__in=["rfc","repl"]))
includes = list(State.objects.filter(type="draft-iesg").exclude(slug__in=inactive_states))

View file

@ -312,7 +312,7 @@
"order": 42,
"slug": "watching",
"type": "draft-iesg",
"used": true
"used": false
},
"model": "doc.state",
"pk": 11

View file

@ -12,9 +12,9 @@
</h1>
{% if state.slug == "dead" %}
<p class="alert alert-warning my-3">
This document is in IESG state "Dead". It is unusual to change
this to anything other than "AD is watching", and this should
never be used as a replacement for Begin IESG Processing.
This document is in IESG state "Dead". It is unusual to change this to
anything other than "I-D Exists" and this should never be used as a
replacement for Begin IESG Processing.
</p>
{% endif %}
<a class="btn btn-info my-3"