Remove link to now obsolete shepherd pages, move manage workflow to

wginfo, fix a couple of oddities on the workflow page
 - Legacy-Id: 6136
This commit is contained in:
Ole Laursen 2013-09-10 16:18:14 +00:00
parent 3c8f5d3521
commit 947345ecf2
8 changed files with 105 additions and 173 deletions

View file

@ -1,13 +1,6 @@
{% extends "wginfo/wg_base.html" %}
{% extends "base.html" %}
{% block wg_titledetail %}Manage Workflow{% endblock %}
{% block pagehead %}
{{ block.super }}
<script type="text/javascript" src="/js/lib/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="/js/yui/yui-20100305.js"></script>
<script type="text/javascript" src="/js/base.js"></script>
{% endblock pagehead %}
{% block title %}Customize Workflow for {{ group.acronym }} {{ group.type.name }}{% endblock %}
{% block morecss %}
{{ block.super }}
@ -53,13 +46,20 @@
}
{% endblock %}
{% block wg_content %}
<div class="wg-workflow-management">
<h2>Edit workflow</h2>
{% block content %}
{% load ietf_filters %}
<p>Below you can customize the draft states and tags used in the {{ wg.acronym }} WG. Note that some states are mandatory for WG operation and cannot be deactivated.</p>
<div class="group-customize-workflow">
<h1>Customize Workflow for {{ group.acronym }} {{ group.type.name }}</h1>
<p>Below you can customize the draft states and tags used in the
<a href="{% url group_charter group.acronym %}">{{ group.acronym }} {{ group.type.name }}</a>. Note that some states are
mandatory for group operation and cannot be deactivated.</p>
<p>You can see the default Working Group I-D State Diagram
in <a href="http://tools.ietf.org/html/rfc6174#section-4.1">Section 4.1 of RFC6174</a>.</p>
<p>You can see the default Working Group I-D State Diagram in <a href="http://tools.ietf.org/html/rfc6174#section-4.1">Section 4.1 of RFC6174</a>.</p>
<h3>States</h3>
@ -90,11 +90,7 @@
{% endif %}
</td>
<td>
<div>
<span>{{ state.name }} {% if not state.used %} (not used in {{ wg.acronym }}){% endif %}</span>
<a class="toggler" title="Click to show description of state" href="">+</a>
</div>
<div class="toggled">{{ state.desc|safe|linebreaks }}</div>
{{ state.name }} {% if not state.used %} (not used in {{ group.acronym }}){% endif %} {{ state|statehelp }}
</td>
<td>
<div>
@ -142,11 +138,14 @@
<input type="hidden" name="action" value="settagactive" />
</form>
</td>
<td><span>{{ tag.name }} {% if not tag.used %} (not used in {{ wg.acronym }}){% endif %}</span></td>
<td><span>{{ tag.name }} {% if not tag.used %} (not used in {{ group.acronym }}){% endif %}</span></td>
</tr>
{% endfor %}
</table>
{% endblock content %}
{% block js %}
<script type="text/javascript">
//<![CDATA[
jQuery('.state-table .toggler').click(function(e) {
@ -164,5 +163,4 @@ jQuery('.state-table .toggler').click(function(e) {
});
//]]>
</script>
{% endblock %}

View file

@ -32,7 +32,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% endcomment %}
{% load ietf_filters wgchairs_tags %}
{% load ietf_filters %}
{% block title %}{{ group.name }} ({{ group.acronym }}) - {% block group_subtitle %}{% endblock %}{% endblock %}
{% block morecss %}
@ -73,18 +73,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<a {% if selected == "documents" %}class="selected"{% else %}href="{% url ietf.wginfo.views.group_documents acronym=group.acronym %}"{% endif %}>Documents</a> |
<a {% if selected == "charter" %}class="selected"{% else %}href="{% url ietf.wginfo.views.group_charter acronym=group.acronym %}"{% endif %}>Charter</a> |
{% if can_manage_workflow %}
<a {% if selected == "manage_workflow" %}class="selected"{% else %}href="{% url manage_workflow group.acronym %}"{% endif %}>Manage workflow</a> |
{% endif %}
{% if can_manage_delegates %}
<a {% if selected == "manage_delegates" %}class="selected"{% else %}href="{% url manage_delegates group.acronym %}"{% endif %}>Manage delegations</a> |
{% endif %}
{% if can_manage_shepherds %}
<a {% if selected == "manage_shepherds" %}class="selected"{% else %}href="{% url manage_shepherds group.acronym %}"{% endif %}>Manage shepherds</a> |
{% endif %}
<a {% if selected == "history" %}class="selected"{% else %}href="{% url ietf.wginfo.views.history acronym=group.acronym %}"{% endif %}>History</a> |
{% if group.list_archive|startswith:"http:" or group.list_archive|startswith:"https:" or group.list_archive|startswith:"ftp:" %}
<a href="{{ group.list_archive }}">List Archive &raquo;</a> |

View file

@ -130,7 +130,7 @@ is occasionally incorrect.</span>
{% if user|has_role:"Area Director,Secretariat" %}
<div style="margin: 2px; margin-top: 2em;">
{% for name, url in actions %}
<a class="button" href="{{ url }}">{{ name }}</a>
<a href="{{ url }}">{{ name }}</a> {% if not forloop.last %} | {% endif %}
{% endfor %}
</div>
{% endif %}

View file

@ -3,7 +3,5 @@
from django.conf.urls.defaults import patterns, url
urlpatterns = patterns('ietf.wgchairs.views',
url(r'^workflows/$', 'manage_workflow', name='manage_workflow'),
url(r'^delegates/$', 'manage_delegates', name='manage_delegates'),
url(r'^shepherds/$', 'wg_shepherd_documents', name='manage_shepherds'),
)

View file

@ -51,133 +51,6 @@ def manage_delegates(request, acronym):
}, RequestContext(request))
def manage_workflow(request, acronym):
wg = get_object_or_404(IETFWG, group_acronym__acronym=acronym, group_type=1)
user = request.user
if not can_manage_workflow_in_group(user, wg):
return HttpResponseForbidden("You don't have permission to access this view")
workflow = get_workflow_for_wg(wg)
default_workflow = get_default_workflow_for_wg()
formset = None
if request.method == 'POST':
form = workflow_form_factory(request, wg=wg, user=user)
if form.is_valid():
form.save()
elif isinstance(form, TransitionFormSet):
formset = form
tags = workflow.selected_tags.all()
default_tags = default_workflow.annotation_tags.all()
states = workflow.selected_states.all().order_by('statedescription__order')
default_states = default_workflow.states.all().order_by('statedescription__order')
for i in default_states:
if states.filter(name=i.name).count() == 1:
i.used = True
if i.name in REQUIRED_STATES:
i.freeze = True
for i in default_tags:
if tags.filter(name=i.name).count() == 1:
i.used = True
if not formset:
formset = TransitionFormSet(queryset=workflow.transitions.all(), user=user, wg=wg)
return render_to_response('wgchairs/manage_workflow.html',
{'wg': wg,
'workflow': workflow,
'default_workflow': default_workflow,
'states': states,
'tags': tags,
'default_states': default_states,
'default_tags': default_tags,
'formset': formset,
'selected': 'manage_workflow',
}, RequestContext(request))
def manage_workflowREDESIGN(request, acronym):
from ietf.doc.models import State
from ietf.group.models import GroupStateTransitions
MANDATORY_STATES = ('c-adopt', 'wg-doc', 'sub-pub')
wg = get_object_or_404(IETFWG, group_acronym__acronym=acronym, group_type=1)
user = request.user
if not can_manage_workflow_in_group(user, wg):
return HttpResponseForbidden("You don't have permission to access this view")
if request.method == 'POST':
action = request.POST.get("action")
if action == "setstateactive":
active = request.POST.get("active") == "1"
try:
state = State.objects.exclude(slug__in=MANDATORY_STATES).get(pk=request.POST.get("state"))
except State.DoesNotExist:
return HttpResponse("Invalid state %s" % request.POST.get("state"))
if active:
wg.unused_states.remove(state)
else:
wg.unused_states.add(state)
if action == "setnextstates":
try:
state = State.objects.get(pk=request.POST.get("state"))
except State.DoesNotExist:
return HttpResponse("Invalid state %s" % request.POST.get("state"))
next_states = State.objects.filter(used=True, type='draft-stream-ietf', pk__in=request.POST.getlist("next_states"))
unused = wg.unused_states.all()
if set(next_states.exclude(pk__in=unused)) == set(state.next_states.exclude(pk__in=unused)):
# just use the default
wg.groupstatetransitions_set.filter(state=state).delete()
else:
transitions, _ = GroupStateTransitions.objects.get_or_create(group=wg, state=state)
transitions.next_states = next_states
if action == "settagactive":
active = request.POST.get("active") == "1"
try:
tag = DocTagName.objects.get(pk=request.POST.get("tag"))
except DocTagName.DoesNotExist:
return HttpResponse("Invalid tag %s" % request.POST.get("tag"))
if active:
wg.unused_tags.remove(tag)
else:
wg.unused_tags.add(tag)
# put some info for the template on tags and states
unused_tags = wg.unused_tags.all().values_list('slug', flat=True)
tags = DocTagName.objects.filter(slug__in=get_tags_for_stream_id("ietf"))
for t in tags:
t.used = t.slug not in unused_tags
unused_states = wg.unused_states.all().values_list('slug', flat=True)
states = State.objects.filter(used=True, type="draft-stream-ietf")
transitions = dict((o.state, o) for o in wg.groupstatetransitions_set.all())
for s in states:
s.used = s.slug not in unused_states
s.mandatory = s.slug in MANDATORY_STATES
default_n = s.next_states.all()
if s in transitions:
n = transitions[s].next_states.all()
else:
n = default_n
s.next_states_checkboxes = [(x in n, x in default_n, x) for x in states]
s.used_next_states = [x for x in n if x.slug not in unused_states]
return render_to_response('wgchairs/manage_workflowREDESIGN.html',
{'wg': wg,
'states': states,
'tags': tags,
'selected': 'manage_workflow',
}, RequestContext(request))
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
manage_workflow = manage_workflowREDESIGN
def wg_shepherd_documents(request, acronym):
wg = get_object_or_404(IETFWG, group_acronym__acronym=acronym, group_type=1)
user = request.user

View file

@ -20,7 +20,7 @@ from ietf.group.models import *
from ietf.group.utils import save_group_in_history
from ietf.wgcharter.mails import email_secretariat
from ietf.person.forms import EmailsField
from ietf.doc.utils import get_tags_for_stream_id
class WGForm(forms.Form):
name = forms.CharField(max_length=255, label="WG Name", required=True)
@ -320,3 +320,81 @@ def conclude(request, acronym):
dict(form=form,
wg=wg),
context_instance=RequestContext(request))
def customize_workflow(request, acronym):
MANDATORY_STATES = ('c-adopt', 'wg-doc', 'sub-pub')
group = get_object_or_404(Group, acronym=acronym, type="wg")
if not request.user.is_authenticated() or not (has_role(request.user, "Secretariat") or group.role_set.filter(name="chair", person__user=request.user)):
return HttpResponseForbidden("You don't have permission to access this view")
if request.method == 'POST':
action = request.POST.get("action")
if action == "setstateactive":
active = request.POST.get("active") == "1"
try:
state = State.objects.exclude(slug__in=MANDATORY_STATES).get(pk=request.POST.get("state"))
except State.DoesNotExist:
return HttpResponse("Invalid state %s" % request.POST.get("state"))
if active:
group.unused_states.remove(state)
else:
group.unused_states.add(state)
if action == "setnextstates":
try:
state = State.objects.get(pk=request.POST.get("state"))
except State.DoesNotExist:
return HttpResponse("Invalid state %s" % request.POST.get("state"))
next_states = State.objects.filter(used=True, type='draft-stream-ietf', pk__in=request.POST.getlist("next_states"))
unused = group.unused_states.all()
if set(next_states.exclude(pk__in=unused)) == set(state.next_states.exclude(pk__in=unused)):
# just use the default
group.groupstatetransitions_set.filter(state=state).delete()
else:
transitions, _ = GroupStateTransitions.objects.get_or_create(group=group, state=state)
transitions.next_states = next_states
if action == "settagactive":
active = request.POST.get("active") == "1"
try:
tag = DocTagName.objects.get(pk=request.POST.get("tag"))
except DocTagName.DoesNotExist:
return HttpResponse("Invalid tag %s" % request.POST.get("tag"))
if active:
group.unused_tags.remove(tag)
else:
group.unused_tags.add(tag)
# put some info for the template on tags and states
unused_tags = group.unused_tags.all().values_list('slug', flat=True)
tags = DocTagName.objects.filter(slug__in=get_tags_for_stream_id("ietf"))
for t in tags:
t.used = t.slug not in unused_tags
unused_states = group.unused_states.all().values_list('slug', flat=True)
states = State.objects.filter(used=True, type="draft-stream-ietf")
transitions = dict((o.state, o) for o in group.groupstatetransitions_set.all())
for s in states:
s.used = s.slug not in unused_states
s.mandatory = s.slug in MANDATORY_STATES
default_n = s.next_states.all()
if s in transitions:
n = transitions[s].next_states.all()
else:
n = default_n
s.next_states_checkboxes = [(x in n, x in default_n, x) for x in states]
s.used_next_states = [x for x in n if x.slug not in unused_states]
return render_to_response('wginfo/customize_workflow.html', {
'group': group,
'states': states,
'tags': tags,
}, RequestContext(request))

View file

@ -29,6 +29,6 @@ urlpatterns = patterns('',
(r'^(?P<acronym>[a-zA-Z0-9-]+)/milestones/charter/$', milestones.edit_milestones, {'milestone_set': "charter"}, "wg_edit_charter_milestones"),
(r'^(?P<acronym>[a-zA-Z0-9-]+)/milestones/charter/reset/$', milestones.reset_charter_milestones, None, "wg_reset_charter_milestones"),
(r'^(?P<acronym>[a-zA-Z0-9-]+)/ajax/searchdocs/$', milestones.ajax_search_docs, None, "wg_ajax_search_docs"),
(r'^(?P<acronym>[a-zA-Z0-9-]+)/workflow/$', edit.customize_workflow),
(r'^(?P<acronym>[^/]+)/management/', include('ietf.wgchairs.urls')),
)

View file

@ -49,10 +49,6 @@ from ietf.person.models import Email
from ietf.group.utils import get_charter_text
from ietf.doc.templatetags.ietf_filters import clean_whitespace
from ietf.wgchairs.accounts import (can_manage_workflow_in_group,
can_manage_delegates_in_group,
can_manage_shepherds_in_group)
def fill_in_charter_info(group, include_drafts=False):
group.areadirector = group.ad.role_email("ad", group.parent) if group.ad else None
@ -179,9 +175,6 @@ def construct_group_menu_context(request, group, selected, others):
d = {
"group": group,
"selected": selected,
"can_manage_delegates": can_manage_delegates_in_group(request.user, group),
"can_manage_workflow": can_manage_workflow_in_group(request.user, group),
"can_manage_shepherds": can_manage_shepherds_in_group(request.user, group),
}
d.update(others)
@ -274,6 +267,10 @@ def group_charter(request, acronym):
is_chair = request.user.is_authenticated() and group.role_set.filter(name="chair", person__user=request.user)
if is_chair or has_role(request.user, "Secretariat"):
actions.append((u"Manage delegates", urlreverse("manage_delegates", kwargs=dict(acronym=group.acronym))))
actions.append((u"Customize workflow", urlreverse("ietf.wginfo.edit.customize_workflow", kwargs=dict(acronym=group.acronym))))
return render_to_response('wginfo/group_charter.html',
construct_group_menu_context(request, group, "charter", {
"actions": actions,