From 1af89d99efbdd05dc6057eb39332a4822d24aec8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Sat, 22 Sep 2018 18:12:22 +0200 Subject: [PATCH] manager: add widget to define time periods for multiple days at once (#25970) --- chrono/manager/forms.py | 11 ++++++++++- chrono/manager/static/css/style.scss | 13 +++++++++++++ chrono/manager/views.py | 17 +++++++++++++---- chrono/manager/widgets.py | 24 +++++++++++++++++++++++- tests/test_manager.py | 15 ++++++++++++--- 5 files changed, 71 insertions(+), 9 deletions(-) diff --git a/chrono/manager/forms.py b/chrono/manager/forms.py index 296856f..ccd8eb3 100644 --- a/chrono/manager/forms.py +++ b/chrono/manager/forms.py @@ -28,7 +28,7 @@ from django.utils.timezone import make_aware from django.utils.translation import ugettext_lazy as _ from chrono.agendas.models import (Agenda, Event, MeetingType, TimePeriod, Desk, - TimePeriodException) + TimePeriodException, WEEKDAYS_LIST) from . import widgets @@ -91,6 +91,15 @@ class MeetingTypeForm(forms.ModelForm): exclude = [] +class TimePeriodAddForm(forms.Form): + weekdays = forms.MultipleChoiceField( + label=_('Days'), + widget=widgets.WeekdaysWidget(), + choices=WEEKDAYS_LIST) + start_time = forms.TimeField(label=_('Start Time'), widget=widgets.TimeWidget()) + end_time = forms.TimeField(label=_('End Time'), widget=widgets.TimeWidget()) + + class TimePeriodForm(forms.ModelForm): class Meta: model = TimePeriod diff --git a/chrono/manager/static/css/style.scss b/chrono/manager/static/css/style.scss index 9281d2b..a6b8aee 100644 --- a/chrono/manager/static/css/style.scss +++ b/chrono/manager/static/css/style.scss @@ -246,3 +246,16 @@ span.start-time { top: 3ex; z-index: 100; } + +ul#id_weekdays { + margin: 0; + padding: 0; + list-style: none; + max-width: 42em; + li { + margin: 0; + padding: 0; + display: inline-block; + width: 10em; + } +} diff --git a/chrono/manager/views.py b/chrono/manager/views.py index 06d6d20..b9adf74 100644 --- a/chrono/manager/views.py +++ b/chrono/manager/views.py @@ -37,7 +37,7 @@ from chrono.agendas.models import (Agenda, Event, MeetingType, TimePeriod, from .forms import (AgendaAddForm, AgendaEditForm, EventForm, NewMeetingTypeForm, MeetingTypeForm, TimePeriodForm, ImportEventsForm, NewDeskForm, DeskForm, TimePeriodExceptionForm, - ExceptionsImportForm, AgendasImportForm) + ExceptionsImportForm, AgendasImportForm, TimePeriodAddForm) from .utils import import_site @@ -621,10 +621,19 @@ class MeetingTypeDeleteView(ManagedAgendaSubobjectMixin, DeleteView): meeting_type_delete = MeetingTypeDeleteView.as_view() -class AgendaAddTimePeriodView(ManagedDeskMixin, CreateView): +class AgendaAddTimePeriodView(ManagedDeskMixin, FormView): template_name = 'chrono/manager_time_period_form.html' - model = TimePeriod - form_class = TimePeriodForm + form_class = TimePeriodAddForm + + def form_valid(self, form): + for weekday in form.cleaned_data.get('weekdays'): + period = TimePeriod( + weekday=weekday, + start_time=form.cleaned_data['start_time'], + end_time=form.cleaned_data['end_time'], + desk=self.desk) + period.save() + return super(AgendaAddTimePeriodView, self).form_valid(form) agenda_add_time_period = AgendaAddTimePeriodView.as_view() diff --git a/chrono/manager/widgets.py b/chrono/manager/widgets.py index dc541dd..58d1377 100644 --- a/chrono/manager/widgets.py +++ b/chrono/manager/widgets.py @@ -11,7 +11,7 @@ import json import re import uuid -from django.forms.widgets import DateTimeInput, DateInput, TimeInput +from django.forms.widgets import DateTimeInput, DateInput, TimeInput, SelectMultiple from django.utils.formats import get_language from django.utils.safestring import mark_safe @@ -173,3 +173,25 @@ class TimeWidget(PickerWidgetMixin, TimeInput): options['format'] = options.get('format', 'hh:ii') super(TimeWidget, self).__init__(attrs, options, usel10n) + + +class WeekdaysWidget(SelectMultiple): + def render(self, name, value, attrs=None, choices=()): + s = [] + value = value or [] + for choice_id, choice_label in self.choices: + s.append('
  • ' % { + 'name': name, + 'checked': 'checked' if choice_id in value else '', + 'choice_id': choice_id, + 'choice_label': choice_label}) + return mark_safe('') + + def value_from_datadict(self, data, files, name): + choices = [] + for choice_id, choice_label in self.choices: + if data.get('%s-%s' % (name, choice_id)): + choices.append(choice_id) + return choices diff --git a/tests/test_manager.py b/tests/test_manager.py index 79d02be..d8115cd 100644 --- a/tests/test_manager.py +++ b/tests/test_manager.py @@ -650,7 +650,7 @@ def test_meetings_agenda_add_time_period(app, admin_user): resp = app.get('/manage/agendas/%s/' % agenda.id, status=302).follow() resp = resp.click('Settings') resp = resp.click('Add a time period') - resp.form['weekday'].select(text='Wednesday') + resp.form['weekdays-2'].checked = True resp.form['start_time'] = '10:00' resp.form['end_time'] = '17:00' resp = resp.form.submit() @@ -663,7 +663,7 @@ def test_meetings_agenda_add_time_period(app, admin_user): # add a second time period resp = resp.click('Add a time period', index=0) - resp.form['weekday'].select(text='Monday') + resp.form['weekdays-0'].checked = True resp.form['start_time'] = '10:00' resp.form['end_time'] = '13:00' resp = resp.form.submit() @@ -677,8 +677,17 @@ def test_meetings_agenda_add_time_period(app, admin_user): assert 'Edit Time Period' in resp.text resp.form['start_time'] = '9:00' resp = resp.form.submit() + resp = resp.follow() assert TimePeriod.objects.get(desk=desk, weekday=2).start_time.hour == 9 + # and add same time periods on multiple days + resp = resp.click('Add a time period', index=0) + resp.form['weekdays-4'].checked = True + resp.form['weekdays-5'].checked = True + resp.form['start_time'] = '10:00' + resp.form['end_time'] = '13:00' + resp = resp.form.submit() + assert TimePeriod.objects.filter(desk=desk).count() == 4 def test_meetings_agenda_delete_time_period(app, admin_user): agenda = Agenda(label=u'Foo bar', kind='meetings') @@ -810,7 +819,7 @@ def test_meetings_agenda_add_time_period_exception(app, admin_user): resp = resp.form.submit().follow() # adding a new time period resp = resp.click('Add a time period') - resp.form['weekday'].select(text='Wednesday') + resp.form['weekdays-2'].checked = True resp.form['start_time'] = '10:00' resp.form['end_time'] = '17:00' resp = resp.form.submit().follow() -- 2.19.0