agendas: add resource to agenda (#38942)

This commit is contained in:
Lauréline Guérin 2020-05-18 16:45:35 +02:00
parent a06c7796c8
commit b1b92bfa5c
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
7 changed files with 195 additions and 0 deletions

View File

@ -102,6 +102,14 @@ class EventForm(forms.ModelForm):
exclude = ['full', 'meeting_type', 'desk', 'resources']
class AgendaResourceForm(forms.Form):
resource = forms.ModelChoiceField(label=_('Resource'), queryset=Resource.objects.none())
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['resource'].queryset = Resource.objects.exclude(agenda=self.initial['agenda'])
class NewMeetingTypeForm(forms.ModelForm):
class Meta:
model = MeetingType

View File

@ -0,0 +1,23 @@
{% extends "chrono/manager_agenda_view.html" %}
{% load i18n %}
{% block breadcrumb %}
{{ block.super }}
<a href="">{% trans "Add resource" %}</a>
{% endblock %}
{% block appbar %}
<h2>{% trans "Add resource" %}</h2>
{% endblock %}
{% block content %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<div class="buttons">
<button class="submit-button">{% trans "Save" %}</button>
<a class="cancel" href="{% url 'chrono-manager-agenda-settings' pk=agenda.pk %}">{% trans 'Cancel' %}</a>
</div>
</form>
{% endblock %}

View File

@ -13,6 +13,7 @@
{% endblock %}
{% block agenda-extra-management-actions %}
{% if has_resources %}<a rel="popup" href="{% url 'chrono-manager-agenda-add-resource' pk=object.pk %}">{% trans 'Add resource' %}</a>{% endif %}
<a rel="popup" href="{% url 'chrono-manager-agenda-add-meeting-type' pk=object.id %}">{% trans 'New Meeting Type' %}</a>
<a rel="popup" href="{% url 'chrono-manager-agenda-add-desk' pk=object.id %}">{% trans 'New Desk' %}</a>
{% endblock %}
@ -97,4 +98,34 @@
</div>
</div>
{% with object.resources.all as agenda_resources %}
{% if has_resources %}
<div class="section">
<h3>{% trans 'Resources' %}</h3>
<div>
{% if agenda_resources %}
<ul class="objects-list single-links">
{% for resource in agenda_resources %}
<li>
<a href="{% url 'chrono-manager-resource-view' pk=resource.pk %}">
{{ resource.label }}
<span class="identifier">[{% trans "identifier:" %} {{ resource.slug }}]</span>
</a>
<a rel="popup" class="delete" href="{% url 'chrono-manager-agenda-delete-resource' pk=object.pk resource_pk=resource.pk %}">{% trans "remove" %}</a>
</li>
{% endfor %}
</ul>
{% else %}
<div class="big-msg-info">
{% blocktrans %}
This agenda doesn't have any resource yet. Click on the "Add resource" button in
the top right of the page to add a first one.
{% endblocktrans %}
</div>
{% endif %}
</div>
</div>
{% endif %}
{% endwith %}
{% endblock %}

View File

@ -17,3 +17,32 @@
<a rel="popup" href="{% url 'chrono-manager-resource-delete' pk=object.pk %}">{% trans 'Delete' %}</a>
</span>
{% endblock %}
{% block content %}
<div class="section">
<h3>{% trans 'Used in meetings agendas' %}</h3>
<div>
{% with object.agenda_set.all as agendas %}
{% if agendas %}
<ul class="objects-list single-links">
{% for agenda in agendas %}
<li>
<a href="{% url 'chrono-manager-agenda-settings' pk=agenda.pk %}">
{{ agenda.label }}
</a>
</li>
{% endfor %}
</ul>
{% else %}
<div class="big-msg-info">
{% blocktrans %}
This resource is not used yet.
{% endblocktrans %}
</div>
{% endif %}
{% endwith %}
</div>
</div>
{% endblock %}

View File

@ -63,6 +63,16 @@ urlpatterns = [
views.event_delete,
name='chrono-manager-event-delete',
),
url(
r'^agendas/(?P<pk>\d+)/add-resource/$',
views.agenda_add_resource,
name='chrono-manager-agenda-add-resource',
),
url(
r'^agendas/(?P<pk>\d+)/resource/(?P<resource_pk>\d+)/delete/$',
views.agenda_delete_resource,
name='chrono-manager-agenda-delete-resource',
),
url(
r'^agendas/(?P<pk>\d+)/add-meeting-type$',
views.agenda_add_meeting_type,

View File

@ -79,6 +79,7 @@ from .forms import (
VirtualMemberForm,
ResourceAddForm,
ResourceEditForm,
AgendaResourceForm,
)
from .utils import import_site
@ -787,6 +788,8 @@ class AgendaSettings(ManagedAgendaMixin, DetailView):
for virtual_member in self.object.get_virtual_members()
]
context['meeting_types'] = self.object.iter_meetingtypes()
if self.agenda.kind == 'meetings':
context['has_resources'] = Resource.objects.exists()
return context
def get_events(self):
@ -933,6 +936,39 @@ class EventDeleteView(ManagedAgendaMixin, DeleteView):
event_delete = EventDeleteView.as_view()
class AgendaAddResourceView(ManagedAgendaMixin, FormView):
template_name = 'chrono/manager_agenda_resource_form.html'
model = Event
form_class = AgendaResourceForm
def set_agenda(self, **kwargs):
self.agenda = get_object_or_404(Agenda, id=kwargs.get('pk'), kind='meetings')
def form_valid(self, form):
self.agenda.resources.add(form.cleaned_data['resource'])
return super().form_valid(form)
agenda_add_resource = AgendaAddResourceView.as_view()
class AgendaResourceDeleteView(ManagedAgendaMixin, DeleteView):
template_name = 'chrono/manager_confirm_delete.html'
model = Resource
pk_url_kwarg = 'resource_pk'
def set_agenda(self, **kwargs):
self.agenda = get_object_or_404(Agenda, id=kwargs.get('pk'), kind='meetings')
def delete(self, request, *args, **kwargs):
self.object = self.get_object()
self.agenda.resources.remove(self.object)
return HttpResponseRedirect(self.get_success_url())
agenda_delete_resource = AgendaResourceDeleteView.as_view()
class AgendaAddMeetingTypeView(ManagedAgendaMixin, CreateView):
template_name = 'chrono/manager_meeting_type_form.html'
model = Event

View File

@ -193,6 +193,19 @@ def test_add_resource(app, admin_user):
assert resource.slug == 'foo-bar'
def test_view_resource(app, admin_user):
agenda = Agenda.objects.create(label=u'Foo Bar', kind='meetings')
resource = Resource.objects.create(label='Resource 1')
app = login(app)
resp = app.get('/manage/resource/%s/' % resource.pk, status=200)
assert '/manage/agendas/%s/settings' % agenda.pk not in resp.text
agenda.resources.add(resource)
resp = app.get('/manage/resource/%s/' % resource.pk, status=200)
assert '/manage/agendas/%s/settings' % agenda.pk in resp.text
def test_edit_resource(app, admin_user):
resource = Resource.objects.create(label='Foo bar')
@ -259,6 +272,7 @@ def test_options_agenda(app, admin_user):
resp = resp.form.submit()
assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.id)
resp = resp.follow()
assert 'has_resources' not in resp.context
assert 'Foo baz' in resp.text
assert '<h2>Settings' in resp.text
@ -322,6 +336,50 @@ def test_options_agenda_as_manager(app, manager_user):
assert '<h2>Settings' in resp.text
def test_agenda_resources(app, admin_user):
agenda = Agenda.objects.create(label=u'Foo bar', kind='events')
resource = Resource.objects.create(label='Resource 1')
app = login(app)
# not for events agenda
app.get('/manage/agendas/%s/add-resource/' % agenda.pk, status=404)
app.get('/manage/agendas/%s/resource/%s/delete/' % (agenda.pk, resource.pk), status=404)
def test_meetings_agenda_resources(app, admin_user):
agenda = Agenda.objects.create(label=u'Foo bar', kind='meetings')
app = login(app)
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
assert 'has_resources' in resp.context
assert resp.context['has_resources'] is False
assert 'Add resource' not in resp.text
resource = Resource.objects.create(label='Resource 1')
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
assert 'has_resources' in resp.context
assert resp.context['has_resources'] is True
assert '/manage/resource/%s/' % resource.pk not in resp.text
assert '/manage/agendas/%s/resource/%s/delete/' % (agenda.pk, resource.pk) not in resp.text
resp = resp.click('Add resource')
assert list(resp.context['form'].fields['resource'].queryset) == [resource]
resp.form['resource'] = resource.pk
resp = resp.form.submit()
assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.pk)
assert list(agenda.resources.all()) == [resource]
resp = resp.follow()
assert '/manage/resource/%s/' % resource.pk in resp.text
assert '/manage/agendas/%s/resource/%s/delete/' % (agenda.pk, resource.pk) in resp.text
resp = resp.click('Add resource')
assert list(resp.context['form'].fields['resource'].queryset) == []
resp = app.get('/manage/agendas/%s/resource/%s/delete/' % (agenda.pk, resource.pk))
resp = resp.form.submit()
assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.pk)
assert list(agenda.resources.all()) == []
resp = resp.follow()
assert '/manage/resource/%s/' % resource.pk not in resp.text
assert '/manage/agendas/%s/resource/%s/delete/' % (agenda.pk, resource.pk) not in resp.text
def test_delete_agenda(app, admin_user):
agenda = Agenda(label=u'Foo bar')
agenda.save()