Reworked the pages that manage all the possible schedules for a meeting. Removed a lot of custom javascript. Fixes #1921. Commit ready for merge.

- Legacy-Id: 11137
This commit is contained in:
Robert Sparks 2016-04-27 20:46:02 +00:00
parent 62d3ac8fe7
commit f34ae9c612
12 changed files with 239 additions and 570 deletions

View file

@ -11,13 +11,13 @@ from django.conf import settings
from pyquery import PyQuery
from ietf.doc.models import Document
from ietf.meeting.models import Session, TimeSlot
from ietf.meeting.models import Session, TimeSlot, Meeting
from ietf.meeting.test_data import make_meeting_test_data
from ietf.utils.test_utils import TestCase, login_testing_unauthorized, unicontent
from ietf.person.factories import PersonFactory
from ietf.group.factories import GroupFactory
from ietf.meeting.factories import SessionFactory, SessionPresentationFactory
from ietf.meeting.factories import SessionFactory, SessionPresentationFactory, ScheduleFactory, MeetingFactory
from ietf.doc.factories import DocumentFactory
class MeetingTests(TestCase):
@ -401,3 +401,48 @@ class SessionDetailsTests(TestCase):
q = PyQuery(r.content)
self.assertEqual(1,len(q(".alert-warning:contains('may affect published proceedings')")))
class EditScheduleListTests(TestCase):
def setUp(self):
self.mtg = MeetingFactory(type_id='ietf')
ScheduleFactory(meeting=self.mtg,name='Empty-Schedule')
def test_list_agendas(self):
url = urlreverse('ietf.meeting.views.list_agendas',kwargs={'num':self.mtg.number})
login_testing_unauthorized(self,"secretary",url)
r = self.client.get(url)
self.assertTrue(r.status_code, 200)
def test_delete_schedule(self):
url = urlreverse('ietf.meeting.views.delete_schedule',
kwargs={'num':self.mtg.number,
'owner':self.mtg.agenda.owner.email_address(),
'name':self.mtg.agenda.name,
})
login_testing_unauthorized(self,"secretary",url)
r = self.client.get(url)
self.assertTrue(r.status_code, 403)
r = self.client.post(url,{'save':1})
self.assertTrue(r.status_code, 403)
self.assertEqual(self.mtg.schedule_set.count(),2)
self.mtg.agenda=None
self.mtg.save()
r = self.client.get(url)
self.assertTrue(r.status_code, 200)
r = self.client.post(url,{'save':1})
self.assertTrue(r.status_code, 302)
self.assertEqual(self.mtg.schedule_set.count(),1)
def test_make_schedule_official(self):
schedule = self.mtg.schedule_set.exclude(id=self.mtg.agenda.id).first()
url = urlreverse('ietf.meeting.views.make_schedule_official',
kwargs={'num':self.mtg.number,
'owner':schedule.owner.email_address(),
'name':schedule.name,
})
login_testing_unauthorized(self,"secretary",url)
r = self.client.get(url)
self.assertTrue(r.status_code, 200)
r = self.client.post(url,{'save':1})
self.assertTrue(r.status_code, 302)
mtg = Meeting.objects.get(number=self.mtg.number)
self.assertEqual(mtg.agenda,schedule)

View file

@ -12,18 +12,22 @@ safe_for_all_meeting_types = [
]
type_ietf_only_patterns = [
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P<name>[A-Za-z0-9-:_]+)/edit$', views.edit_agenda),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P<name>[A-Za-z0-9-:_]+)/details$', views.edit_agenda_properties),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P<name>[A-Za-z0-9-:_]+).(?P<ext>.html)?/?$', views.agenda),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P<name>[A-Za-z0-9-:_]+)/permissions$', ajax.agenda_permission_api),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P<name>[A-Za-z0-9-:_]+)/session/(?P<assignment_id>\d+).json$', ajax.assignment_json),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P<name>[A-Za-z0-9-:_]+)/sessions.json$', ajax.assignments_json),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P<name>[A-Za-z0-9-:_]+).json$', ajax.agenda_infourl),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9-._]+)/(?P<name>[A-Za-z0-9-:_]+)/edit$', views.edit_agenda),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9-._]+)/(?P<name>[A-Za-z0-9-:_]+)/details$', views.edit_agenda_properties),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9-._]+)/(?P<name>[A-Za-z0-9-:_]+)/delete$', views.delete_schedule),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9-._]+)/(?P<name>[A-Za-z0-9-:_]+)/make_official$', views.make_schedule_official),
# The following view is broken?
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9-._]+)/(?P<name>[A-Za-z0-9-:_]+).(?P<ext>.html)?/?$', views.agenda),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9-._]+)/(?P<name>[A-Za-z0-9-:_]+)/permissions$', ajax.agenda_permission_api),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9-._]+)/(?P<name>[A-Za-z0-9-:_]+)/session/(?P<assignment_id>\d+).json$', ajax.assignment_json),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9-._]+)/(?P<name>[A-Za-z0-9-:_]+)/sessions.json$', ajax.assignments_json),
url(r'^agenda/(?P<owner>[A-Za-z0-9-.+_]+@[A-Za-z0-9-._]+)/(?P<name>[A-Za-z0-9-:_]+).json$', ajax.agenda_infourl),
url(r'^agenda/by-room$', views.agenda_by_room),
url(r'^agenda/by-type$', views.agenda_by_type),
url(r'^agenda/by-type/(?P<type>[a-z]+)$', views.agenda_by_type),
url(r'^agenda/by-type/(?P<type>[a-z]+)/ics$', views.agenda_by_type_ics),
url(r'^agendas/edit$', views.edit_agendas),
url(r'^agendas/list$', views.list_agendas, name='meeting_list_agendas'),
url(r'^agendas/edit$', RedirectView.as_view(pattern_name='meeting_list_agendas', permanent=True)),
url(r'^timeslots/edit$', views.edit_timeslots),
url(r'^rooms$', ajax.timeslot_roomsurl),
url(r'^room/(?P<roomid>\d+).json$', ajax.timeslot_roomurl),

View file

@ -304,30 +304,33 @@ def edit_agenda(request, num=None, owner=None, name=None):
##############################################################################
# show the properties associated with an agenda (visible, public)
# this page uses ajax POST requests to the API
#
AgendaPropertiesForm = modelform_factory(Schedule, fields=('name','visible', 'public'))
@role_required('Area Director','Secretariat')
@ensure_csrf_cookie
def edit_agenda_properties(request, num=None, owner=None, name=None):
meeting = get_meeting(num)
person = get_person_by_email(owner)
schedule = get_schedule_by_name(meeting, person, name)
if schedule is None:
raise Http404("No meeting information for meeting %s owner %s schedule %s available" % (num, owner, name))
form = AgendaPropertiesForm(instance=schedule)
cansee, canedit, secretariat = agenda_permissions(meeting, schedule, request.user)
if not (canedit or has_role(request.user,'Secretariat')):
return HttpResponseForbidden("You may not edit this agenda")
else:
if request.method == 'POST':
form = AgendaPropertiesForm(instance=schedule,data=request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('ietf.meeting.views.list_agendas',kwargs={'num': num}))
else:
form = AgendaPropertiesForm(instance=schedule)
return render(request, "meeting/properties_edit.html",
{"schedule":schedule,
"form":form,
"meeting":meeting,
"hide_menu": True,
})
##############################################################################
@ -335,11 +338,7 @@ def edit_agenda_properties(request, num=None, owner=None, name=None):
#
@role_required('Area Director','Secretariat')
@ensure_csrf_cookie
def edit_agendas(request, num=None, order=None):
#if request.method == 'POST':
# return agenda_create(request, num, owner, name)
def list_agendas(request, num=None ):
meeting = get_meeting(num)
user = request.user
@ -350,10 +349,11 @@ def edit_agendas(request, num=None, order=None):
schedules = schedules.order_by('owner', 'name')
schedules = sorted(list(schedules),key=lambda x:not x.is_official)
return render(request, "meeting/agenda_list.html",
{"meeting": meeting,
"schedules": schedules.all(),
"hide_menu": True,
"schedules": schedules,
})
@ensure_csrf_cookie
@ -927,3 +927,62 @@ def add_session_drafts(request, session_id, num):
'already_linked': session.sessionpresentation_set.filter(document__type_id='draft'),
'form': form,
})
@role_required('Secretariat')
def make_schedule_official(request, num, owner, name):
meeting = get_meeting(num)
person = get_person_by_email(owner)
schedule = get_schedule_by_name(meeting, person, name)
if schedule is None:
raise Http404
if request.method == 'POST':
if not (schedule.public and schedule.visible):
schedule.public = True
schedule.visible = True
schedule.save()
meeting.agenda = schedule
meeting.save()
return HttpResponseRedirect(reverse('ietf.meeting.views.list_agendas',kwargs={'num':num}))
if not schedule.public:
messages.warning(request,"This schedule will be made public as it is made official.")
if not schedule.visible:
messages.warning(request,"This schedule will be made visible as it is made official.")
return render(request, "meeting/make_schedule_official.html",
{ 'schedule' : schedule,
'meeting' : meeting,
}
)
@role_required('Secretariat','Area Director')
def delete_schedule(request, num, owner, name):
meeting = get_meeting(num)
person = get_person_by_email(owner)
schedule = get_schedule_by_name(meeting, person, name)
if schedule.name=='Empty-Schedule':
return HttpResponseForbidden('You may not delete the default empty schedule')
if schedule == meeting.agenda:
return HttpResponseForbidden('You may not delete the official agenda for %s'%meeting)
if not ( has_role(request.user, 'Secretariat') or person.user == request.user ):
return HttpResponseForbidden("You may not delete other user's schedules")
if request.method == 'POST':
schedule.delete()
return HttpResponseRedirect(reverse('ietf.meeting.views.list_agendas',kwargs={'num':num}))
return render(request, "meeting/delete_schedule.html",
{ 'schedule' : schedule,
'meeting' : meeting,
}
)

View file

@ -1,177 +0,0 @@
/*
* agenda_properties_edit.js
*
* Copyright (c) 2013, The IETF Trust. See ../../../LICENSE.
*
* www.credil.org: Project Orlando 2013
* Author: Justin Hornosty ( justin@credil.org )
* Michael Richardson <mcr@sandelman.ca>
*
* This file should contain functions relating to
* editing the properties of a single agenda.
*
*/
//////////////-GLOBALS----////////////////////////////////////////
/////////////-END-GLOBALS-///////////////////////////////////////
var cancel_url;
$(document).ready(function() {
init_agenda_edit();
cancel_url = $("#agenda_cancel_url").attr("href");
/* hide the side bar by default. */
$("#close_ietf_menubar").click();
});
function init_agenda_edit(){
log("initstuff() ran");
static_listeners();
$(".agenda_delete").unbind('click');
$(".agenda_delete").click(delete_agenda);
$("#agenda_save").unbind('click');
$("#agenda_save").click(save_agenda);
$(".agenda_official_mark").unbind('click');
$(".agenda_official_mark").click(toggle_official);
}
function toggle_public(event) {
var span_to_replace = event.target;
var current_value = $(event.target).html();
var agenda_url = $(event.target).closest('tr').attr('href');
var new_value = 1;
log("value "+current_value);
if(current_value == "public") {
new_value = 0;
}
event.preventDefault();
$.ajax({ "url": agenda_url,
"type": "POST",
"data": { "public" : new_value },
"dataType": "json",
"success": function(result) {
/* result is a json object */
value = result["public"];
log("new value "+value);
$(span_to_replace).html(value);
}});
}
function toggle_visible(event) {
var span_to_replace = event.target;
var current_value = $(event.target).html();
var agenda_url = $(event.target).closest('tr').attr('href');
var new_value = 1;
log("value "+current_value);
if(current_value == "visible") {
new_value = 0;
}
event.preventDefault();
$.ajax({ "url": agenda_url,
"type": "POST",
"data": { "visible" : new_value },
"dataType": "json",
"success": function(result) {
/* result is a json object */
value = result["visible"]
log("new value "+value)
$(span_to_replace).html(value)
}});
}
function toggle_official(event) {
var agenda_name = $(event.target).closest('tr').attr('agenda_name');
var agenda_id = $(event.target).closest('tr').attr('id');
var meeting_url = $(".agenda_list_title").attr('href');
event.preventDefault();
/*
* if any of them are clicked, then go through all of them
* and set them to "unofficial", then based upon the return
* we might this one to official.
*/
var value = 0;
if($(event.target).html() == "official") {
value = 1;
}
var new_value = agenda_name;
var new_official = 1;
if(value > 0) {
new_value = "None";
new_official = 0;
}
var rows = $(".agenda_list tr:gt(0)");
rows.each(function(index) {
log("row: "+this);
/* this is now the tr */
$(this).removeClass("agenda_official_row");
$(this).addClass("agenda_unofficial_row");
/* not DRY, this occurs deep in the model too */
$(this).find(".agenda_official_mark").html("unofficial");
});
//log("clicked on "+agenda_url+" sending to "+meeting_url);
$.ajax({ "url": meeting_url,
"type": "POST",
"data": { "agenda" : new_value },
"dataType": "json",
"success": function(result) {
/* result is a json object */
if(new_official) {
$("#"+agenda_id).find(".agenda_official_mark").html("official");
$("#"+agenda_id).addClass("agenda_official_row");
}}});
}
function save_agenda(form) {
var agenda_url = form.action;
var name_str = form.elements["name"].value;
var public_flag = false;
var visible_flag= false;
public_flag = form.elements["public"].checked ? true : false;
visible_flag = form.elements["visible"].checked ? true: false;
console.log("POST to ",agenda_url," with name:", name_str,
"visible:", visible_flag,
"public:", public_flag);
$.ajax({"url": agenda_url,
"type": "POST",
"data": { "public" : public_flag,
"visible": visible_flag,
"name" : name_str,
},
"dataType": "json",
"success": function(result) {
window.location.assign(cancel_url);
}});
}
/*
* Local Variables:
* c-basic-offset:4
* End:
*/

View file

@ -1,101 +0,0 @@
/*
* agenda_property_utils.js
*
* Copyright (c) 2013, The IETF Trust. See ../../../LICENSE.
*
* www.credil.org: Project Orlando 2013
* Author: Justin Hornosty ( justin@credil.org )
* Michael Richardson <mcr@sandelman.ca>
*
* Some functions for toggling, saving and deleting agenda properties.
*
*/
//////////////-GLOBALS----////////////////////////////////////////
/////////////-END-GLOBALS-///////////////////////////////////////
function delete_agenda(event) {
var agenda_url = $(event.target).closest('tr').attr('href') + ".json";
event.preventDefault();
$("#agenda_delete_dialog").dialog({
buttons : {
"Confirm" : function() {
$.ajax({
url: agenda_url,
type: 'DELETE',
success: function(result) {
window.location.reload(true);
}
});
$(this).dialog("close");
},
"Cancel" : function() {
$(this).dialog("close");
}
}
});
$("#room_delete_dialog").dialog("open");
}
function toggle_public(event) {
var span_to_replace = event.target;
var current_value = $(event.target).html();
var agenda_url = $(event.target).closest('tr').attr('href');
var new_value = 1;
log("value "+current_value)
if(current_value == "public") {
new_value = 0
}
event.preventDefault();
$.ajax({ "url": agenda_url,
"type": "POST",
"data": { "public" : new_value },
"dataType": "json",
"success": function(result) {
/* result is a json object */
value = result["public"]
log("new value "+value)
$(span_to_replace).html(value)
}});
}
function toggle_visible(event) {
var span_to_replace = event.target;
var current_value = $(event.target).html();
var agenda_url = $(event.target).closest('tr').attr('href');
var new_value = 1;
log("value "+current_value)
if(current_value == "visible") {
new_value = 0
}
event.preventDefault();
$.ajax({ "url": agenda_url,
"type": "POST",
"data": { "visible" : new_value },
"dataType": "json",
"success": function(result) {
/* result is a json object */
value = result["visible"]
log("new value "+value)
$(span_to_replace).html(value)
}});
}
/*
* Local Variables:
* c-basic-offset:4
* End:
*/

View file

@ -1,123 +0,0 @@
/*
* agendas_edit.js
*
* Copyright (c) 2013, The IETF Trust. See ../../../LICENSE.
*
* www.credil.org: Project Orlando 2013
* Author: Justin Hornosty ( justin@credil.org )
* Michael Richardson <mcr@sandelman.ca>
*
* This file should contain functions relating to
* editing a list of agendas
*
*/
//////////////-GLOBALS----////////////////////////////////////////
/////////////-END-GLOBALS-///////////////////////////////////////
$(document).ready(function() {
init_agendas_edit();
/* hide the side bar by default. */
$("#close_ietf_menubar").click();
});
/*
init_timeslot_editf()
This is ran at page load and sets up appropriate listeners
*/
function init_agendas_edit(){
log("initstuff() ran");
static_listeners();
$(".agenda_delete").unbind('click');
$(".agenda_delete").click(delete_agenda);
$(".agenda_official_mark").unbind('click');
$(".agenda_official_mark").click(toggle_official);
}
function toggle_official(event) {
var agenda_line = $(event.target).closest('tr');
var agenda_url = agenda_line.attr('href');
var agenda_name = agenda_line.attr('agenda_name');
var agenda_id = agenda_line.attr('id');
var meeting_url = $(".agenda_list_title").attr('href');
event.preventDefault();
/*
* if any of them are clicked, then go through all of them
* and set them to "unofficial", then based upon the return
* we might this one to official.
*/
/* if agenda_official is > 1, then it is enabled */
var value = 0;
if($(event.target).html() == "official") {
value = 1;
}
var new_value = agenda_name;
var new_official = 1;
if(value > 0) {
new_value = "None";
new_official = 0;
}
if(new_official == 1) {
// see if this item is public, fail otherwise.
var agenda_public_span = agenda_line.find('.agenda_public').html();
// console.log("public_span", agenda_public_span);
if (agenda_public_span == "private") {
$("#agenda_notpublic_dialog").dialog();
return;
}
}
var rows = $(".agenda_list tr:gt(0)");
rows.each(function(index) {
log("row: "+this);
/* this is now the tr */
$(this).removeClass("agenda_official_row");
$(this).addClass("agenda_unofficial_row");
/* not DRY, this occurs deep in the model too */
$(this).find(".agenda_official_mark").html("unofficial");
});
log("clicked on "+agenda_url+" sending to "+meeting_url);
$.ajax({ "url": meeting_url,
"type": "POST",
"data": { "agenda" : new_value },
"dataType": "json",
"success": function(result) {
/* result is a json object, which has the agenda_href to mark official */
var agenda_href = result.agenda_href;
var rows = $(".agenda_list tr:gt(0)");
rows.each(function(index) {
var my_href = $(this).attr('href')
/* this is now the tr */
if(agenda_href == my_href) {
$(this).find(".agenda_official_mark").html("official");
$(this).addClass("agenda_official_row");
}
});
}});
}
/*
* Local Variables:
* c-basic-offset:4
* End:
*/

View file

@ -3,91 +3,48 @@
{% load origin %}
{% load staticfiles %}
{% load ietf_filters %}
{% load humanize %}
{% block title %}IETF {{ meeting.number }} Meeting Agenda{% endblock %}
{% load agenda_custom_tags %}
{% block pagehead %}
<link rel='stylesheet' type='text/css' href="{% static 'ietf/css/agenda/jquery-ui-themes/jquery-ui-1.8.11.custom.css' %}" />
<link rel='stylesheet' type='text/css' href="{% static 'ietf/css/agenda/base2.css' %}" />
<link rel='stylesheet' type='text/css' href="{% static 'ietf/css/agenda/agenda.css' %}" />
{% endblock pagehead %}
{% block js %}
<script type="text/javascript" src="{% static 'ietf/js/agenda/jquery-1.8.2.min.js' %}"></script>
<script src="{% static 'jquery.cookie/jquery.cookie.js' %}"></script>
<script>
jQuery.ajaxSetup({
crossDomain: false, // obviates need for sameOrigin test
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type)) {
xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
}
}
});
</script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/jquery-ui-1.9.0.custom/jquery-ui.custom.js' %}"></script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/jquery-ui-1.9.0.custom/jquery.ui.widget.js' %}"></script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/jquery-ui-1.9.0.custom/jquery.ui.droppable.js' %}"></script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/jquery-ui-1.9.0.custom/jquery.ui.sortable.js' %}"></script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/jquery-ui-1.9.0.custom/jquery.ui.accordion.js' %}"></script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/jquery-ui-1.9.0.custom/jquery.ui.draggable.js' %}"></script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/agenda_listeners.js' %}"></script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/agenda_helpers.js' %}"></script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/agenda_property_utils.js' %}"></script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/agendas_edit.js' %}"></script>
{% endblock js %}
{% block title %}IETF {{ meeting.number }} Meeting Agenda List{% endblock %}
{% block content %}
{% origin %}
<div class="wrapper custom_text_stuff">
<div style="ui-icon ui-icon-arrow-1-w" id="close_ietf_menubar">
&lt;
</div>
<h1>IETF {{meeting.number}} Agenda List</h1>
<div href="{{ meeting.json_url }}" class="agenda_list_title">
<p>Meeting {{meeting.number}}</p>
</div>
{% comment %}
<div>
<p><a href="{% url "ietf.meeting.views.edit_timeslots" meeting.number %}">Edit Timeslots</a></p>
</div>
{% endcomment %}
<div class="agenda_list_edit">
<p><a href="{% url "ietf.meeting.views.edit_timeslots" meeting.number %}">Edit Timeslots</a></p>
</div>
<div id="class_list" class="agenda_list">
<table>
<tr>
<th></th>
<th>Owner</th>
<th>Name</th>
<th>Visible</th>
<th>Public</th>
</tr>
{% for agenda in schedules %}
<tr agenda_name="{{agenda.name}}" id="agenda_name_{{agenda.name|slugify}}" href="{{agenda.base_url}}" class="{{agenda.official_class}}_row">
<td class="agenda_mark agenda_data"> <span class="styled_button agenda_official_mark {{agenda.official_class}}">{{ agenda.official_token }}</span></td>
<td class="agenda_data"> <span class="agenda_owner">{{ agenda.owner }}</span> </td>
<td class="agenda_data">
<a href="{% url "ietf.meeting.views.edit_agenda" agenda.meeting.number agenda.owner_email agenda.name %}"><span class="agenda_name">{{ agenda.name }}</span></a>
</td>
<td class="agenda_data"> <span class="agenda_visible {{agenda.visible_class}}">{{ agenda.visible_token }}</span></a></td>
<td class="agenda_data"> <span class="agenda_public {{agenda.public_class}}">{{ agenda.public_token }}</span></td>
<td class="agenda_mark agenda_data"> <a href="{% url "ietf.meeting.views.edit_agenda_properties" agenda.meeting.number agenda.owner_email agenda.name %}"><span class="styled_button agenda_edit">EDIT</span></a> </td>
<td class="agenda_mark agenda_data"> <span class="styled_button agenda_delete">DEL</span> </td>
<div>
{% regroup schedules by is_official as classed_schedules %}
{% for class in classed_schedules %}
<div class="panel panel-default">
<div class="panel-heading">{{class.grouper|yesno:"Official,Unofficial"}} Schedule{{class.list|length|pluralize}}</div>
<div class="panel-body">
<table class="table table-condensed table-striped">
<tr>
<th class="col-md-4">Name</th>
<th class="col-md-4">Owner</th>
<th class="col-md-1">Visible</th>
<th class="col-md-1">Public</th>
<th class="col-md-1"></th>
</tr>
{% for agenda in class.list %}
<tr>
<td><a href="{% url "ietf.meeting.views.edit_agenda" agenda.meeting.number agenda.owner_email agenda.name %}">
{{ agenda.name }}</a></td>
<td>{{ agenda.owner }}</td>
<td>{{ agenda.visible_token }}</td>
<td>{{ agenda.public_token }}</td>
<td><a class="btn btn-default" href="{% url "ietf.meeting.views.edit_agenda_properties" agenda.meeting.number agenda.owner_email agenda.name %}">
EDIT</a></td>
</tr>
{% endfor %}
</table>
{% endfor %}
</table>
</div>
</div>
<div class="dialog" id="agenda_delete_dialog">
Are you sure you want to delete this agenda?
</div>
<div class="dialog" id="agenda_notpublic_dialog">
You can not mark an agenda as official, if it is not public.
</div>
{% endfor %}
</div>
{% endblock %}
{% endblock content %}

View file

@ -0,0 +1,28 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin %}
{% load staticfiles %}
{% load ietf_filters %}
{% load bootstrap3 %}
{% block title %}Delete IETF {{ meeting.number }} Meeting Agenda: {{schedule.owner}} / {{ schedule.name }}{% endblock %}
{% block content %}
{% origin %}
<h1>Delete IETF {{meeting.number}} Schedule: {{schedule.owner}}/{{schedule.name}} </h1>
<div>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{# Null Form #}
{% buttons %}
<input class="btn btn-primary" type="submit" value="Delete schedule" name="save">
<a href="{% url 'ietf.meeting.views.list_agendas' num=meeting.number %}" class="btn btn-default">Cancel</a>
{% endbuttons %}
</form>
</div>
{% endblock %}

View file

@ -117,7 +117,7 @@ promiselist.push(ss_promise);
<div id="unassigned-items">
<div id="all_agendas" class="events_bar_buttons">
<a href="{% url "ietf.meeting.views.edit_agendas" meeting.number %}">
<a href="{% url "ietf.meeting.views.list_agendas" meeting.number %}">
<button class="styled_button">all agendas</button>
</a>
</div>

View file

@ -0,0 +1,29 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin %}
{% load staticfiles %}
{% load ietf_filters %}
{% load bootstrap3 %}
{% block title %}IETF {{ meeting.number }} : Make {{schedule.owner}} / {{ schedule.name }} Official{% endblock %}
{% block content %}
{% origin %}
<h1>IETF {{meeting.number}}</h1>
<h2>Make Schedule: {{schedule.owner}}/{{schedule.name}} Official
<div>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{# Null Form #}
{% buttons %}
<input class="btn btn-primary" type="submit" value="Make this schedule official" name="save">
<a href="{% url 'ietf.meeting.views.list_agendas' num=meeting.number %}" class="btn btn-default">Cancel</a>
{% endbuttons %}
</form>
</div>
{% endblock %}

View file

@ -15,7 +15,7 @@
<div id="read_only">
<p>You do not have access this agenda. It belongs to {{ schedule.owner }}.</p>
<p><a href="{% url "ietf.meeting.views.edit_agendas" meeting.number %}">List your meetings</a>.</p>
<p><a href="{% url "ietf.meeting.views.list_agendas" meeting.number %}">List your meetings</a>.</p>
<div class="wrapper custom_text_stuff"></div>
</div>

View file

@ -3,84 +3,32 @@
{% load origin %}
{% load staticfiles %}
{% load ietf_filters %}
{% load humanize %}
{% load bootstrap3 %}
{% block title %}IETF {{ meeting.number }} Meeting Agenda: {{schedule.owner}} / {{ schedule.name }}{% endblock %}
{% load agenda_custom_tags %}
{% block pagehead %}
<link rel='stylesheet' type='text/css' href="{% static 'ietf/css/agenda/jquery-ui-themes/jquery-ui-1.8.11.custom.css' %}" />
<link rel='stylesheet' type='text/css' href="{% static 'ietf/css/agenda/base2.css' %}" />
<link rel='stylesheet' type='text/css' href="{% static 'ietf/css/agenda/agenda.css' %}" />
{% endblock pagehead %}
{% block js %}
<script type="text/javascript" src="{% static 'ietf/js/agenda/jquery-1.8.2.min.js' %}"></script>
<script src="{% static 'jquery.cookie/jquery.cookie.js' %}"></script>
<script>
jQuery.ajaxSetup({
crossDomain: false, // obviates need for sameOrigin test
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type)) {
xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
}
}
});
</script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/jquery-ui-1.9.0.custom/jquery-ui.custom.js' %}"></script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/jquery-ui-1.9.0.custom/jquery.ui.widget.js' %}"></script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/jquery-ui-1.9.0.custom/jquery.ui.droppable.js' %}"></script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/jquery-ui-1.9.0.custom/jquery.ui.sortable.js' %}"></script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/jquery-ui-1.9.0.custom/jquery.ui.accordion.js' %}"></script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/jquery-ui-1.9.0.custom/jquery.ui.draggable.js' %}"></script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/agenda_listeners.js' %}"></script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/agenda_helpers.js' %}"></script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/agenda_property_utils.js' %}"></script>
<script type='text/javascript' src="{% static 'ietf/js/agenda/agenda_properties_edit.js' %}"></script>
{% endblock js %}
{% block content %}
{% origin %}
</tr></table></div>
<div class="wrapper custom_text_stuff">
<div style="ui-icon ui-icon-arrow-1-w" id="close_ietf_menubar">
&lt;
</div>
<div href="{{ meeting.json_url }}" class="agenda_list_title">
<p>Meeting {{meeting.number}}</p>
</div>
<h1>IETF {{meeting.number}}</h1>
<h2>Schedule: {{schedule.owner}}/{{schedule.name}} ({{schedule.official_token }})
{% if not schedule.is_official %}
<a class="btn btn-default btn-sm" href="{% url 'ietf.meeting.views.make_schedule_official' num=meeting.number owner=schedule.owner.email_address name=schedule.name %}">Make this the official schedule</a>
<a class="btn btn-warning btn-sm" href="{% url 'ietf.meeting.views.delete_schedule' num=meeting.number owner=schedule.owner.email_address name=schedule.name %}">Delete this schedule</a>
{% endif %}
</h2>
<div id="agenda_edit_properties">
<div id="title">
<p>Schedule: {{schedule.owner}}/{{schedule.name}}</p>
<!-- done with table to reuse code from table view -->
<table class="agenda_list"><tr></tr><tr agenda_name="{{schedule.name}}" id="agenda_name_{{schedule.name|slugify}}" ><td>
<span class="styled_button agenda_official_mark {{schedule.official_class}}">{{ schedule.official_token }}</span>
</td></tr></table>
</div>
<div>
<form action="{{schedule.json_url}}" method="POST">
<fieldset>
<table>
{{ form.as_table }}
<tr>
<td></td>
<td colspan=2><input type="button" name="save" value="save" onClick="save_agenda(this.form)" class="styled_button">
<a id="agenda_cancel_url" href="{% url "ietf.meeting.views.edit_agendas" meeting.number %}"><span class="styled_button agenda_cancel">Cancel</span></a></td>
<td><span class="styled_button agenda_delete">DEL</span></td>
</tr>
</table>
</fieldset>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<input class="btn btn-primary" type="submit" value="Save" name="save">
<a href="{% url 'ietf.meeting.views.list_agendas' num=meeting.number %}" class="btn btn-default">Cancel</a>
{% endbuttons %}
</form>
</div>
<div class="dialog" id="agenda_delete_dialog">
Are you sure you want to delete this agenda?
</div>
</div>
{% endblock %}