Main views for state change and state history. See #582

- Legacy-Id: 2811
This commit is contained in:
Emilio A. Sánchez López 2011-02-04 11:55:10 +00:00
parent 256dd73dd4
commit 7a2302d377
8 changed files with 225 additions and 29 deletions

View file

@ -4,12 +4,14 @@ from ietf.ietfworkflows.models import (AnnotationTag, WGWorkflow,
Stream)
from workflows.admin import StateInline
class AnnotationTagInline(admin.TabularInline):
model = AnnotationTag
class IETFWorkflowAdmin(admin.ModelAdmin):
inlines = [StateInline, AnnotationTagInline]
admin.site.register(WGWorkflow, IETFWorkflowAdmin)
admin.site.register(Stream, admin.ModelAdmin)

View file

@ -0,0 +1,55 @@
from django import forms
from ietf.ietfworkflows.utils import (get_workflow_for_draft,
get_state_for_draft)
class StreamDraftForm(forms.Form):
can_cancel = False
def __init__(self, *args, **kwargs):
self.draft = kwargs.pop('draft', None)
self.user = kwargs.pop('user', None)
self.message = {}
super(StreamDraftForm, self).__init__(*args, **kwargs)
def get_message(self):
return self.message
def set_message(self, msg_type, msg_value):
self.message = {'type': msg_type,
'value': msg_value,
}
class DraftStateForm(StreamDraftForm):
comment = forms.CharField(widget=forms.Textarea)
new_state = forms.ChoiceField()
weeks = forms.IntegerField(required=False)
def __init__(self, *args, **kwargs):
super(DraftStateForm, self).__init__(*args, **kwargs)
if self.is_bound:
for key, value in self.data.items():
if key.startswith('transition_'):
new_state = self.get_new_state(key)
if new_state:
self.data.update({'new_state': new_state.id})
self.workflow = get_workflow_for_draft(self.draft)
self.state = get_state_for_draft(self.draft)
self.fields['new_state'].choices = self.get_states()
def get_new_state(self, key):
transition_id = key.replace('transition_', '')
transition = self.get_transitions().filter(id=transition_id)
if transition:
return transition[0].destination
return None
def get_transitions(self):
return self.state.transitions.filter(workflow=self.workflow)
def get_states(self):
return [(i.pk, i.name) for i in self.workflow.get_states()]

View file

@ -20,9 +20,8 @@ class ObjectHistoryEntry(models.Model):
class Meta:
ordering = ('-date', )
def get_real_instance(self):
if hasattr(self, '_real_instance'):
if hasattr(self, '_real_instance'):
return self._real_instance
for i in ('objectworkflowhistoryentry', 'objectannotationtaghistoryentry', 'objectstreamhistoryentry'):
try:
@ -118,6 +117,13 @@ class WGWorkflow(Workflow):
else:
return self.selected_tags.all()
def get_states(self):
states = self.states.all()
if states.count():
return states
else:
return self.selected_states.all()
class Stream(models.Model):
name = models.CharField(_(u"Name"), max_length=100)
@ -133,7 +139,7 @@ class Stream(models.Model):
class StreamedID(models.Model):
draft = models.OneToOneField(InternetDraft)
stream = models.ForeignKey(Stream, blank=True, null=True)
content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content type"), related_name="streamed_id", blank=True, null=True)
content_id = models.PositiveIntegerField(_(u"Content id"), blank=True, null=True)
group = generic.GenericForeignKey(ct_field="content_type", fk_field="content_id")

View file

@ -12,7 +12,6 @@ register = template.Library()
@register.inclusion_tag('ietfworkflows/stream_state.html', takes_context=True)
def stream_state(context, doc):
request = context.get('request', None)
user = request and request.user
data = {}
stream = get_stream_from_wrapper(doc)
data.update({'stream': stream})

View file

@ -4,4 +4,7 @@ from django.conf.urls.defaults import patterns, url
urlpatterns = patterns('ietf.ietfworkflows.views',
url(r'^(?P<name>[^/]+)/history/$', 'stream_history', name='stream_history'),
url(r'^(?P<name>[^/]+)/edit/state/$', 'edit_state', name='edit_state'),
url(r'^(?P<name>[^/]+)/edit/tags/$', 'edit_tags', name='edit_tags'),
url(r'^(?P<name>[^/]+)/edit/stream/$', 'edit_stream', name='edit_stream'),
)

View file

@ -10,7 +10,7 @@ from workflows.models import State
from workflows.utils import (get_workflow_for_object, set_workflow_for_object,
get_state)
from ietf.ietfworkflows.streams import get_streamed_draft
from ietf.ietfworkflows.streams import get_streamed_draft, get_stream_from_draft
from ietf.ietfworkflows.models import (WGWorkflow, AnnotationTagObjectRelation,
AnnotationTag, ObjectAnnotationTagHistoryEntry,
ObjectHistoryEntry)
@ -96,9 +96,13 @@ def get_workflow_for_draft(draft):
return workflow
def get_workflow_history_for_draft(draft):
def get_workflow_history_for_draft(draft, entry_type=None):
ctype = ContentType.objects.get_for_model(draft)
history = ObjectHistoryEntry.objects.filter(content_type=ctype, content_id=draft.pk).\
filter_param = {'content_type': ctype,
'content_id': draft.pk}
if entry_type:
filter_param.update({'%s__isnull' % entry_type: False})
history = ObjectHistoryEntry.objects.filter(**filter_param).\
select_related('objectworkflowhistoryentry', 'objectannotationtaghistoryentry',
'objectstreamhistoryentry')
return history
@ -207,3 +211,14 @@ def update_tags(obj, comment, person, set_tags=[], reset_tags=[], extra_notify=[
comment=comment,
person=person)
notify_tag_entry(entry, extra_notify)
def get_full_info_for_draft(draft):
return dict(
streamed = get_streamed_draft(draft),
stream = get_stream_from_draft(draft),
workflow = get_workflow_for_draft(draft),
tags = [i.annotation_tag for i in get_annotation_tags_for_draft(draft)],
state = get_state_for_draft(draft),
shepherd = draft.shepherd,
)

View file

@ -1,37 +1,20 @@
from ietf.idtracker.models import IETFWG, InternetDraft, IESGLogin
from ietf.idtracker.models import InternetDraft
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext
from django.http import HttpResponseForbidden, Http404
from ietf.idrfc.views_search import SearchForm, search_query
from ietf.wgchairs.forms import (RemoveDelegateForm, add_form_factory,
workflow_form_factory, TransitionFormSet,
WriteUpEditForm)
from ietf.wgchairs.accounts import (can_manage_delegates_in_group, get_person_for_user,
can_manage_shepherds_in_group,
can_manage_workflow_in_group,
can_manage_shepherd_of_a_document,
can_manage_writeup_of_a_document,
can_manage_writeup_of_a_document_no_state,
)
from ietf.ietfworkflows.forms import DraftStateForm
from ietf.ietfworkflows.streams import (get_stream_from_draft,
get_streamed_draft)
from ietf.ietfworkflows.utils import (get_workflow_for_wg,
get_default_workflow_for_wg,
get_workflow_history_for_draft,
from ietf.ietfworkflows.utils import (get_workflow_history_for_draft,
get_workflow_for_draft,
get_state_by_name,
get_annotation_tags_for_draft,
get_state_for_draft, WAITING_WRITEUP,
FOLLOWUP_TAG)
get_state_for_draft)
REDUCED_HISTORY_LEN = 20
def stream_history(request, name):
user = request.user
person = get_person_for_user(user)
draft = get_object_or_404(InternetDraft, filename=name)
streamed = get_streamed_draft(draft)
stream = get_stream_from_draft(draft)
@ -58,3 +41,35 @@ def stream_history(request, name):
'history': history[:REDUCED_HISTORY_LEN],
},
context_instance=RequestContext(request))
def edit_state(request, name):
user = request.user
draft = get_object_or_404(InternetDraft, filename=name)
state = get_state_for_draft(draft)
stream = get_stream_from_draft(draft)
workflow = get_workflow_for_draft(draft)
history = get_workflow_history_for_draft(draft, 'objectworkflowhistoryentry')
tags = get_annotation_tags_for_draft(draft)
if request.method == 'POST':
form = DraftStateForm(user=user, draft=draft, data=request.POST)
else:
form = DraftStateForm(user=user, draft=draft)
return render_to_response('ietfworkflows/state_edit.html',
{'draft': draft,
'state': state,
'stream': stream,
'workflow': workflow,
'history': history,
'tags': tags,
'form': form,
},
context_instance=RequestContext(request))
def edit_tags(request, name):
pass
def edit_stream(request, name):
pass

View file

@ -0,0 +1,101 @@
{% extends "base.html" %}
{% load ietf_streams %}
{% block morecss %}
table.state-history p { margin: 0px; }
table.edit-form ul { padding: 0px; list-style-type: none; margin: 0px; margin-bottom: 2em; border-bottom: 1px dashed #cccccc; }
table.edit-form ul li, table.edit-form div.free-change { padding: 10px 2em; }
table.edit-form ul li.evenrow { background-color: #edf5ff; }
table.edit-form textarea { width: 95%; height: 120px; }
table.edit-form span.required { color: red; }
table.edit-form ul.errorlist { border-width: 0px; padding: 0px; margin: 0px;}
table.edit-form ul.errorlist li { color: red; margin: 0px; padding: 0px;}
table.edit-form div.field { margin-bottom: 1em; }
table.edit-form div.error { border: 1px solid red; background-color: #ffeebb; padding: 5px 10px; }
{% endblock morecss %}
{% block title %}Change state for {{ draft }}{% endblock %}
{% block content %}
<h1>Change state for {{ draft }}</h1>
<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%;">
{{ state.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 action="" method="post">
<table class="ietf-table edit-form" style="width: 100%;">
<tr>
<th>1. Input information about change</th>
<th>2. Select the new state</th>
</tr>
<tr><td style="width: 50%;">
<div class="field{% if form.errors.comment %} error{% endif %}">
{{ form.errors.comment }}
Comment: <span class="required">*</span><br />
<textarea name="comment">{{ form.data.comment }}</textarea>
</div>
<div class="field{% if form.errors.weeks %} error{% endif %}">
{{ form.errors.weeks }}
Estimated time in next status:<br />
<input type="text" name="weeks" value="{{ form.data.weeks }}" /> (in weeks)
</div>
</td><td style="padding: 0px; vertical-align: top;">
{% 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="free-change field{% if form.errors.new_state %} error{% endif %}">
{{ form.errors.new_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="State change" />
</div>
</td></tr>
</table>
</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 %}