make it possible to remove a speakerproposal from an eventproposal, move proposal delete buttons to the proposal detail pages, fix a button here and there
This commit is contained in:
parent
1f58471927
commit
157050d30e
15
src/program/templates/event_proposal_remove_person.html
Normal file
15
src/program/templates/event_proposal_remove_person.html
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{% extends 'program_base.html' %}
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
|
||||||
|
{% block program_content %}
|
||||||
|
<h3>Remove "{{ speakerproposal.name }}" from "{{ eventproposal.title }}"?</h3>
|
||||||
|
<p class="lead">Really remove this {{ eventproposal.event_type.host_title }} from this event?</p>
|
||||||
|
|
||||||
|
<form method="POST" enctype="multipart/form-data">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% bootstrap_button "<i class='fas fa-times'></i> Remove" button_type="submit" button_class="btn-danger" %}
|
||||||
|
<a href="{% url 'program:eventproposal_detail' camp_slug=camp.slug pk=eventproposal.uuid %}">{% bootstrap_button "<i class='fas fa-undo'></i> Cancel" button_type="link" button_class="btn-primary" %}</a>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% endblock program_content %}
|
||||||
|
|
|
@ -27,18 +27,24 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">{{ eventproposal.event_type.host_title }} List</div>
|
<div class="panel-heading">{{ eventproposal.event_type.host_title }} List for {{ eventproposal.title }}</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{% if eventproposal.speakers.exists %}
|
{% if eventproposal.speakers.exists %}
|
||||||
{% include 'includes/speaker_proposal_table.html' with speakerproposals=eventproposal.speakers.all %}
|
{% include 'includes/speaker_proposal_table.html' with speakerproposals=eventproposal.speakers.all %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<i>Nothing found.</i>
|
<i>Nothing found.</i>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if eventproposal.get_available_speakerproposals.exists %}
|
||||||
|
<a href="{% url 'program:eventproposal_selectperson' camp_slug=camp.slug event_uuid=eventproposal.uuid %}" class="btn btn-success pull-right"><i class="fas fa-plus"></i><span class="h5"> Add {{ eventproposal.event_type.host_title }}</span></a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{% url 'program:speakerproposal_create' camp_slug=camp.slug event_uuid=eventproposal.uuid %}" class="btn btn-success pull-right"><i class="fas fa-plus"></i><span class="h5"> Add {{ eventproposal.event_type.host_title }}</span></a>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a href="{% url 'program:proposal_list' camp_slug=camp.slug %}" class="btn btn-primary">Back to List</a>
|
<a href="{% url 'program:proposal_list' camp_slug=camp.slug %}" class="btn btn-primary">Back to List</a>
|
||||||
|
<a href="{% url 'program:eventproposal_delete' camp_slug=camp.slug pk=eventproposal.uuid %}" class="btn btn-danger pull-right"><i class="fas fa-times"></i><span class="h5"> Delete</span></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{% endblock program_content %}
|
{% endblock program_content %}
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{% url 'program:speakerproposal_create' camp_slug=camp.slug event_uuid=eventproposal.uuid %}" class="btn btn-success btn-sm"><i class="fas fa-plus"></i><span class="h5"> Add {{ eventproposal.event_type.host_title }}</span></a>
|
<a href="{% url 'program:speakerproposal_create' camp_slug=camp.slug event_uuid=eventproposal.uuid %}" class="btn btn-success btn-sm"><i class="fas fa-plus"></i><span class="h5"> Add {{ eventproposal.event_type.host_title }}</span></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="{% url 'program:eventproposal_delete' camp_slug=camp.slug pk=eventproposal.uuid %}" class="btn btn-danger btn-sm"><i class="fas fa-times"></i><span class="h5"> Delete</span></a>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -35,10 +35,10 @@
|
||||||
<i class="fas fa-eye"></i><span class="h5"> Detail</span></a>
|
<i class="fas fa-eye"></i><span class="h5"> Detail</span></a>
|
||||||
{% if not camp.read_only %}
|
{% if not camp.read_only %}
|
||||||
<a href="{% url 'program:speakerproposal_update' camp_slug=camp.slug pk=speakerproposal.uuid %}" class="btn btn-primary btn-sm"><i class="fas fa-edit"></i><span class="h5"> Modify</span></a>
|
<a href="{% url 'program:speakerproposal_update' camp_slug=camp.slug pk=speakerproposal.uuid %}" class="btn btn-primary btn-sm"><i class="fas fa-edit"></i><span class="h5"> Modify</span></a>
|
||||||
<a href="{% url 'program:speakerproposalurl_create' camp_slug=camp.slug speaker_uuid=speakerproposal.uuid %}" class="btn btn-success btn-sm"><i class="fas fa-plus"></i><span class="h5"> Add URL</span></a>
|
{% if eventproposal and eventproposal.speakers.count > 1 %}
|
||||||
{% if not speakerproposal.eventproposals.all %}
|
<a href="{% url 'program:eventproposal_removeperson' camp_slug=camp.slug event_uuid=eventproposal.uuid speaker_uuid=speakerproposal.uuid %}" class="btn btn-danger btn-sm"><i class="fas fa-times"></i><span class="h5"> Remove</span></a>
|
||||||
<a href="{% url 'program:speakerproposal_delete' camp_slug=camp.slug pk=speakerproposal.uuid %}" class="btn btn-danger btn-sm"><i class="fas fa-times"></i><span class="h5"> Delete</span></a>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<a href="{% url 'program:speakerproposalurl_create' camp_slug=camp.slug speaker_uuid=speakerproposal.uuid %}" class="btn btn-success btn-sm"><i class="fas fa-plus"></i><span class="h5"> Add URL</span></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<form method="POST" enctype="multipart/form-data">
|
<form method="POST" enctype="multipart/form-data">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% bootstrap_button "<i class='fas fa-times'></i> Delete" button_type="submit" button_class="btn-danger" %}
|
{% bootstrap_button "<i class='fas fa-times'></i> Delete" button_type="submit" button_class="btn-danger" %}
|
||||||
<a href="{% url 'program:proposal_list' camp_slug=camp.slug %}">{% bootstrap_button "<i class='fas fa-undo'></i> Cancel" button_type="link" button_class="btn-primary" %}</a>
|
<a href="{% url 'program:proposal_list' camp_slug=camp.slug %}" class="btn btn-primary" ><i class='fas fa-undo'></i> Cancel</a>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{% endblock program_content %}
|
{% endblock program_content %}
|
||||||
|
|
|
@ -39,6 +39,9 @@
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a href="{% url 'program:proposal_list' camp_slug=camp.slug %}" class="btn btn-primary">Back to List</a>
|
<a href="{% url 'program:proposal_list' camp_slug=camp.slug %}" class="btn btn-primary">Back to List</a>
|
||||||
|
{% if not speakerproposal.eventproposals.all %}
|
||||||
|
<a href="{% url 'program:speakerproposal_delete' camp_slug=camp.slug pk=speakerproposal.uuid %}" class="btn btn-danger pull-right"><i class="fas fa-times"></i><span class="h5"> Delete Person</span></a>
|
||||||
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{% endblock program_content %}
|
{% endblock program_content %}
|
||||||
|
|
|
@ -122,6 +122,11 @@ urlpatterns = [
|
||||||
EventProposalAddPersonView.as_view(),
|
EventProposalAddPersonView.as_view(),
|
||||||
name='eventproposal_addperson'
|
name='eventproposal_addperson'
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
'<uuid:event_uuid>/remove_person/<uuid:speaker_uuid>/',
|
||||||
|
EventProposalRemovePersonView.as_view(),
|
||||||
|
name='eventproposal_removeperson'
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
'<uuid:event_uuid>/add_url/',
|
'<uuid:event_uuid>/add_url/',
|
||||||
UrlCreateView.as_view(),
|
UrlCreateView.as_view(),
|
||||||
|
|
|
@ -287,6 +287,65 @@ class EventProposalAddPersonView(LoginRequiredMixin, CampViewMixin, EnsureWritab
|
||||||
return reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug})
|
return reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug})
|
||||||
|
|
||||||
|
|
||||||
|
class EventProposalRemovePersonView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureCFPOpenMixin, UpdateView):
|
||||||
|
"""
|
||||||
|
This view is for removing a speakerproposal from an existing eventproposal
|
||||||
|
"""
|
||||||
|
model = models.EventProposal
|
||||||
|
template_name = 'event_proposal_remove_person.html'
|
||||||
|
fields = []
|
||||||
|
pk_url_kwarg = 'event_uuid'
|
||||||
|
|
||||||
|
def dispatch(self, request, *args, **kwargs):
|
||||||
|
""" Get the speakerproposal object and check a few things """
|
||||||
|
# get the speakerproposal object from URL kwargs
|
||||||
|
self.speakerproposal = get_object_or_404(models.SpeakerProposal, pk=kwargs['speaker_uuid'], user=request.user)
|
||||||
|
# run the super() dispatch method so we have self.camp otherwise the .all() lookup below craps out
|
||||||
|
response = super().dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
|
# is this speakerproposal even in use on this eventproposal
|
||||||
|
if self.speakerproposal not in self.get_object().speakers.all():
|
||||||
|
# this speaker is not associated with this event
|
||||||
|
raise Http404
|
||||||
|
|
||||||
|
# all good
|
||||||
|
return response
|
||||||
|
|
||||||
|
def get_context_data(self, *args, **kwargs):
|
||||||
|
""" Make speakerproposal object available in template """
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context['speakerproposal'] = self.speakerproposal
|
||||||
|
return context
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
""" Remove the speaker from the event """
|
||||||
|
if self.speakerproposal not in self.get_object().speakers.all():
|
||||||
|
# this speaker is not associated with this event
|
||||||
|
raise Http404
|
||||||
|
|
||||||
|
if self.get_object().speakers.count() == 1:
|
||||||
|
messages.error(self.request, "Cannot delete the last person associalted with event!")
|
||||||
|
return redirect(reverse(
|
||||||
|
'program:eventproposal_detail', kwargs={
|
||||||
|
'camp_slug': self.camp.slug,
|
||||||
|
'pk': self.get_object().uuid
|
||||||
|
}))
|
||||||
|
|
||||||
|
form.instance.speakers.remove(self.speakerproposal)
|
||||||
|
return redirect(self.get_success_url())
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
messages.success(self.request, "Speaker %s has been removed from %s" % (
|
||||||
|
self.speakerproposal.name,
|
||||||
|
self.get_object().title
|
||||||
|
))
|
||||||
|
return reverse(
|
||||||
|
'program:eventproposal_detail', kwargs={
|
||||||
|
'camp_slug': self.camp.slug,
|
||||||
|
'pk': self.get_object().uuid
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
class EventProposalCreateView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureCFPOpenMixin, CreateView):
|
class EventProposalCreateView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureCFPOpenMixin, CreateView):
|
||||||
"""
|
"""
|
||||||
This view allows a user to create a new eventproposal linked to an existing speakerproposal
|
This view allows a user to create a new eventproposal linked to an existing speakerproposal
|
||||||
|
|
Loading…
Reference in a new issue