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:
parent
3c8f5d3521
commit
947345ecf2
|
@ -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 %}
|
|
@ -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 »</a> |
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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'),
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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')),
|
||||
|
||||
)
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue