From 157050d30e9182751a5556248b19bc10b128ad5d Mon Sep 17 00:00:00 2001 From: Thomas Steen Rasmussen Date: Thu, 24 May 2018 11:43:46 +0200 Subject: [PATCH] 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 --- .../event_proposal_remove_person.html | 15 +++++ .../templates/eventproposal_detail.html | 8 ++- .../includes/event_proposal_table.html | 1 - .../includes/speaker_proposal_table.html | 6 +- src/program/templates/proposal_delete.html | 2 +- .../templates/speakerproposal_detail.html | 3 + src/program/urls.py | 5 ++ src/program/views.py | 59 +++++++++++++++++++ 8 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 src/program/templates/event_proposal_remove_person.html diff --git a/src/program/templates/event_proposal_remove_person.html b/src/program/templates/event_proposal_remove_person.html new file mode 100644 index 00000000..9adf37da --- /dev/null +++ b/src/program/templates/event_proposal_remove_person.html @@ -0,0 +1,15 @@ +{% extends 'program_base.html' %} +{% load bootstrap3 %} + +{% block program_content %} +

Remove "{{ speakerproposal.name }}" from "{{ eventproposal.title }}"?

+

Really remove this {{ eventproposal.event_type.host_title }} from this event?

+ +
+ {% csrf_token %} + {% bootstrap_button " Remove" button_type="submit" button_class="btn-danger" %} + {% bootstrap_button " Cancel" button_type="link" button_class="btn-primary" %} +
+ +{% endblock program_content %} + diff --git a/src/program/templates/eventproposal_detail.html b/src/program/templates/eventproposal_detail.html index 8cdc4e47..30ff479d 100644 --- a/src/program/templates/eventproposal_detail.html +++ b/src/program/templates/eventproposal_detail.html @@ -27,18 +27,24 @@
-
{{ eventproposal.event_type.host_title }} List
+
{{ eventproposal.event_type.host_title }} List for {{ eventproposal.title }}
{% if eventproposal.speakers.exists %} {% include 'includes/speaker_proposal_table.html' with speakerproposals=eventproposal.speakers.all %} {% else %} Nothing found. {% endif %} + {% if eventproposal.get_available_speakerproposals.exists %} + Add {{ eventproposal.event_type.host_title }} + {% else %} + Add {{ eventproposal.event_type.host_title }} + {% endif %}

Back to List + Delete

{% endblock program_content %} diff --git a/src/program/templates/includes/event_proposal_table.html b/src/program/templates/includes/event_proposal_table.html index b6aa3825..7bc954a0 100644 --- a/src/program/templates/includes/event_proposal_table.html +++ b/src/program/templates/includes/event_proposal_table.html @@ -31,7 +31,6 @@ {% else %} Add {{ eventproposal.event_type.host_title }} {% endif %} - Delete {% endif %} diff --git a/src/program/templates/includes/speaker_proposal_table.html b/src/program/templates/includes/speaker_proposal_table.html index 8d9dc275..fea5d254 100644 --- a/src/program/templates/includes/speaker_proposal_table.html +++ b/src/program/templates/includes/speaker_proposal_table.html @@ -35,10 +35,10 @@ Detail {% if not camp.read_only %} Modify - Add URL - {% if not speakerproposal.eventproposals.all %} - Delete + {% if eventproposal and eventproposal.speakers.count > 1 %} + Remove {% endif %} + Add URL {% endif %} diff --git a/src/program/templates/proposal_delete.html b/src/program/templates/proposal_delete.html index 489cabcb..89842635 100644 --- a/src/program/templates/proposal_delete.html +++ b/src/program/templates/proposal_delete.html @@ -12,7 +12,7 @@
{% csrf_token %} {% bootstrap_button " Delete" button_type="submit" button_class="btn-danger" %} - {% bootstrap_button " Cancel" button_type="link" button_class="btn-primary" %} + Cancel
{% endblock program_content %} diff --git a/src/program/templates/speakerproposal_detail.html b/src/program/templates/speakerproposal_detail.html index fec1c34f..a8b657d5 100644 --- a/src/program/templates/speakerproposal_detail.html +++ b/src/program/templates/speakerproposal_detail.html @@ -39,6 +39,9 @@

Back to List + {% if not speakerproposal.eventproposals.all %} + Delete Person + {% endif %}

{% endblock program_content %} diff --git a/src/program/urls.py b/src/program/urls.py index 1186aefa..c4d7cb69 100644 --- a/src/program/urls.py +++ b/src/program/urls.py @@ -122,6 +122,11 @@ urlpatterns = [ EventProposalAddPersonView.as_view(), name='eventproposal_addperson' ), + path( + '/remove_person//', + EventProposalRemovePersonView.as_view(), + name='eventproposal_removeperson' + ), path( '/add_url/', UrlCreateView.as_view(), diff --git a/src/program/views.py b/src/program/views.py index 10bfcddd..1b776543 100644 --- a/src/program/views.py +++ b/src/program/views.py @@ -287,6 +287,65 @@ class EventProposalAddPersonView(LoginRequiredMixin, CampViewMixin, EnsureWritab 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): """ This view allows a user to create a new eventproposal linked to an existing speakerproposal