0003-agendas-manager-views-for-resources-38942.patch
chrono/manager/forms.py | ||
---|---|---|
35 | 35 |
TimePeriodException, |
36 | 36 |
TimePeriodExceptionSource, |
37 | 37 |
VirtualMember, |
38 |
Resource, |
|
38 | 39 |
WEEKDAYS_LIST, |
39 | 40 |
) |
40 | 41 | |
... | ... | |
67 | 68 |
self.fields['maximal_booking_delay'].required = True |
68 | 69 | |
69 | 70 | |
71 |
class ResourceAddForm(forms.ModelForm): |
|
72 |
class Meta: |
|
73 |
model = Resource |
|
74 |
fields = ['label', 'description'] |
|
75 | ||
76 | ||
77 |
class ResourceEditForm(forms.ModelForm): |
|
78 |
class Meta: |
|
79 |
model = Resource |
|
80 |
fields = ['label', 'slug', 'description'] |
|
81 | ||
82 | ||
70 | 83 |
class NewEventForm(forms.ModelForm): |
71 | 84 |
class Meta: |
72 | 85 |
model = Event |
chrono/manager/templates/chrono/manager_home.html | ||
---|---|---|
5 | 5 |
<h2>{% trans 'Agendas' %}</h2> |
6 | 6 |
{% if user.is_staff %} |
7 | 7 |
<span class="actions"> |
8 |
<a href="{% url 'chrono-manager-resource-list' %}">{% trans 'Resources' %}</a> |
|
8 | 9 |
<a rel="popup" href="{% url 'chrono-manager-agendas-import' %}">{% trans 'Import' %}</a> |
9 | 10 |
<a rel="popup" href="{% url 'chrono-manager-agenda-add' %}">{% trans 'New' %}</a> |
10 | 11 |
</span> |
... | ... | |
17 | 18 |
<div> |
18 | 19 |
<ul class="objects-list single-links"> |
19 | 20 |
{% for object in object_list %} |
20 |
<li><a href="{% url 'chrono-manager-agenda-view' pk=object.id %}">{{ object.label }}</li> |
|
21 |
<li><a href="{% url 'chrono-manager-agenda-view' pk=object.id %}">{{ object.label }}</a></li>
|
|
21 | 22 |
{% endfor %} |
22 | 23 |
</ul> |
23 | 24 |
</div> |
chrono/manager/templates/chrono/manager_resource_detail.html | ||
---|---|---|
1 |
{% extends "chrono/manager_resource_list.html" %} |
|
2 |
{% load i18n %} |
|
3 | ||
4 |
{% block page-title-extra-label %} |
|
5 |
- {{ object.label }} |
|
6 |
{% endblock %} |
|
7 | ||
8 |
{% block breadcrumb %} |
|
9 |
{{ block.super }} |
|
10 |
<a href="{% url 'chrono-manager-resource-view' pk=object.pk %}">{{ object }}</a> |
|
11 |
{% endblock %} |
|
12 | ||
13 |
{% block appbar %} |
|
14 |
<h2>{{ object }}</h2> |
|
15 |
<span class="actions"> |
|
16 |
<a rel="popup" href="{% url 'chrono-manager-resource-edit' pk=object.pk %}">{% trans 'Edit' %}</a> |
|
17 |
<a rel="popup" href="{% url 'chrono-manager-resource-delete' pk=object.pk %}">{% trans 'Delete' %}</a> |
|
18 |
</span> |
|
19 |
{% endblock %} |
chrono/manager/templates/chrono/manager_resource_form.html | ||
---|---|---|
1 |
{% extends "chrono/manager_home.html" %} |
|
2 |
{% load i18n %} |
|
3 | ||
4 |
{% block appbar %} |
|
5 |
{% if object.id %} |
|
6 |
<h2>{% trans "Edit Resource" %}</h2> |
|
7 |
{% else %} |
|
8 |
<h2>{% trans "New Resource" %}</h2> |
|
9 |
{% endif %} |
|
10 |
{% endblock %} |
|
11 | ||
12 |
{% block content %} |
|
13 | ||
14 |
<form method="post" enctype="multipart/form-data"> |
|
15 |
{% csrf_token %} |
|
16 |
{{ form.as_p }} |
|
17 |
<div class="buttons"> |
|
18 |
<button class="submit-button">{% trans "Save" %}</button> |
|
19 |
<a class="cancel" href="{% url 'chrono-manager-resource-list' %}">{% trans 'Cancel' %}</a> |
|
20 |
</div> |
|
21 |
</form> |
|
22 |
{% endblock %} |
chrono/manager/templates/chrono/manager_resource_list.html | ||
---|---|---|
1 |
{% extends "chrono/manager_base.html" %} |
|
2 |
{% load i18n %} |
|
3 | ||
4 |
{% block breadcrumb %} |
|
5 |
{{ block.super }} |
|
6 |
<a href="{% url 'chrono-manager-resource-list' %}">{% trans "Resources" %}</a> |
|
7 |
{% endblock %} |
|
8 | ||
9 |
{% block appbar %} |
|
10 |
<h2>{% trans 'Resources' %}</h2> |
|
11 |
<span class="actions"> |
|
12 |
<a rel="popup" href="{% url 'chrono-manager-resource-add' %}">{% trans 'New' %}</a> |
|
13 |
</span> |
|
14 |
{% endblock %} |
|
15 | ||
16 | ||
17 |
{% block content %} |
|
18 |
{% if object_list %} |
|
19 |
<div> |
|
20 |
<ul class="objects-list single-links"> |
|
21 |
{% for object in object_list %} |
|
22 |
<li> |
|
23 |
<a href="{% url 'chrono-manager-resource-view' pk=object.pk %}">{{ object.label }} ({{ object.slug }})</a> |
|
24 |
</li> |
|
25 |
{% endfor %} |
|
26 |
</ul> |
|
27 |
</div> |
|
28 |
{% else %} |
|
29 |
<div class="big-msg-info"> |
|
30 |
{% blocktrans %} |
|
31 |
This site doesn't have any resource yet. Click on the "New" button in the top |
|
32 |
right of the page to add a first one. |
|
33 |
{% endblocktrans %} |
|
34 |
</div> |
|
35 |
{% endif %} |
|
36 |
{% endblock %} |
chrono/manager/urls.py | ||
---|---|---|
20 | 20 | |
21 | 21 |
urlpatterns = [ |
22 | 22 |
url(r'^$', views.homepage, name='chrono-manager-homepage'), |
23 |
url(r'^resources/$', views.resource_list, name='chrono-manager-resource-list'), |
|
24 |
url(r'^resource/add/$', views.resource_add, name='chrono-manager-resource-add'), |
|
25 |
url(r'^resource/(?P<pk>\d+)/$', views.resource_view, name='chrono-manager-resource-view'), |
|
26 |
url(r'^resource/(?P<pk>\d+)/edit/$', views.resource_edit, name='chrono-manager-resource-edit'), |
|
27 |
url(r'^resource/(?P<pk>\d+)/delete/$', views.resource_delete, name='chrono-manager-resource-delete'), |
|
23 | 28 |
url(r'^agendas/add/$', views.agenda_add, name='chrono-manager-agenda-add'), |
24 | 29 |
url(r'^agendas/import/$', views.agendas_import, name='chrono-manager-agendas-import'), |
25 | 30 |
url(r'^agendas/(?P<pk>\d+)/$', views.agenda_view, name='chrono-manager-agenda-view'), |
chrono/manager/views.py | ||
---|---|---|
57 | 57 |
AgendaImportError, |
58 | 58 |
TimePeriodExceptionSource, |
59 | 59 |
VirtualMember, |
60 |
Resource, |
|
60 | 61 |
) |
61 | 62 | |
62 | 63 |
from .forms import ( |
... | ... | |
76 | 77 |
TimePeriodAddForm, |
77 | 78 |
TimePeriodExceptionSourceReplaceForm, |
78 | 79 |
VirtualMemberForm, |
80 |
ResourceAddForm, |
|
81 |
ResourceEditForm, |
|
79 | 82 |
) |
80 | 83 |
from .utils import import_site |
81 | 84 | |
... | ... | |
97 | 100 |
homepage = HomepageView.as_view() |
98 | 101 | |
99 | 102 | |
103 |
class ResourceListView(ListView): |
|
104 |
template_name = 'chrono/manager_resource_list.html' |
|
105 |
model = Resource |
|
106 | ||
107 | ||
108 |
resource_list = ResourceListView.as_view() |
|
109 | ||
110 | ||
111 |
class ResourceDetailView(DetailView): |
|
112 |
template_name = 'chrono/manager_resource_detail.html' |
|
113 |
model = Resource |
|
114 | ||
115 | ||
116 |
resource_view = ResourceDetailView.as_view() |
|
117 | ||
118 | ||
119 |
class ResourceAddView(CreateView): |
|
120 |
template_name = 'chrono/manager_resource_form.html' |
|
121 |
model = Resource |
|
122 |
form_class = ResourceAddForm |
|
123 | ||
124 |
def get_success_url(self): |
|
125 |
return reverse('chrono-manager-resource-view', kwargs={'pk': self.object.id}) |
|
126 | ||
127 | ||
128 |
resource_add = ResourceAddView.as_view() |
|
129 | ||
130 | ||
131 |
class ResourceEditView(UpdateView): |
|
132 |
template_name = 'chrono/manager_resource_form.html' |
|
133 |
model = Resource |
|
134 |
form_class = ResourceEditForm |
|
135 | ||
136 |
def get_success_url(self): |
|
137 |
return reverse('chrono-manager-resource-view', kwargs={'pk': self.object.id}) |
|
138 | ||
139 | ||
140 |
resource_edit = ResourceEditView.as_view() |
|
141 | ||
142 | ||
143 |
class ResourceDeleteView(DeleteView): |
|
144 |
template_name = 'chrono/manager_confirm_delete.html' |
|
145 |
model = Resource |
|
146 | ||
147 |
def get_success_url(self): |
|
148 |
return reverse('chrono-manager-resource-list') |
|
149 | ||
150 | ||
151 |
resource_delete = ResourceDeleteView.as_view() |
|
152 | ||
153 | ||
100 | 154 |
class AgendaAddView(CreateView): |
101 | 155 |
template_name = 'chrono/manager_agenda_form.html' |
102 | 156 |
model = Agenda |
tests/test_manager.py | ||
---|---|---|
6 | 6 |
import json |
7 | 7 |
import mock |
8 | 8 |
import os |
9 |
import re |
|
10 | 9 | |
11 | 10 |
from django.contrib.auth.models import User, Group |
12 | 11 |
from django.db import connection |
... | ... | |
25 | 24 |
Desk, |
26 | 25 |
Event, |
27 | 26 |
MeetingType, |
27 |
Resource, |
|
28 | 28 |
TimePeriod, |
29 | 29 |
TimePeriodException, |
30 | 30 |
TimePeriodExceptionSource, |
... | ... | |
180 | 180 |
resp = app.get('/manage/agendas/%s/settings' % '9999', status=404) |
181 | 181 | |
182 | 182 | |
183 |
def test_add_resource(app, admin_user): |
|
184 |
app = login(app) |
|
185 |
resp = app.get('/manage/', status=200) |
|
186 |
resp = resp.click('Resources') |
|
187 |
resp = resp.click('New') |
|
188 |
resp.form['label'] = 'Foo bar' |
|
189 |
resp = resp.form.submit() |
|
190 |
resource = Resource.objects.latest('pk') |
|
191 |
assert resp.location.endswith('/manage/resource/%s/' % resource.pk) |
|
192 |
assert resource.label == 'Foo bar' |
|
193 |
assert resource.slug == 'foo-bar' |
|
194 | ||
195 | ||
196 |
def test_edit_resource(app, admin_user): |
|
197 |
resource = Resource.objects.create(label='Foo bar') |
|
198 | ||
199 |
app = login(app) |
|
200 |
resp = app.get('/manage/resource/%s/' % resource.pk, status=200) |
|
201 |
resp = resp.click('Edit') |
|
202 |
resp.form['label'] = 'Foo bar baz' |
|
203 |
resp.form['slug'] = 'baz' |
|
204 |
resp = resp.form.submit() |
|
205 |
assert resp.location.endswith('/manage/resource/%s/' % resource.pk) |
|
206 |
resource.refresh_from_db() |
|
207 |
assert resource.label == 'Foo bar baz' |
|
208 |
assert resource.slug == 'baz' |
|
209 | ||
210 | ||
211 |
def test_delete_resource(app, admin_user): |
|
212 |
resource = Resource.objects.create(label='Foo bar') |
|
213 | ||
214 |
app = login(app) |
|
215 |
resp = app.get('/manage/resource/%s/' % resource.pk, status=200) |
|
216 |
resp = resp.click('Delete') |
|
217 |
resp = resp.form.submit() |
|
218 |
assert resp.location.endswith('/manage/resources/') |
|
219 |
assert Resource.objects.exists() is False |
|
220 | ||
221 | ||
183 | 222 |
def test_add_agenda(app, admin_user): |
184 | 223 |
app = login(app) |
185 | 224 |
resp = app.get('/manage/', status=200) |
186 |
- |