manager: open the correct tab after redirect (#65653)

This commit is contained in:
Lauréline Guérin 2022-05-24 22:14:41 +02:00
parent e271ea375e
commit f3e6e96136
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
7 changed files with 69 additions and 17 deletions

View File

@ -48,4 +48,12 @@ $(function() {
total_form.val(form_num + 1);
})
}
/* focus tab from #open:<tab slug> anchor, to point to open panel */
if (document.location.hash && document.location.hash.indexOf('#open:') == 0) {
const $tab_button = $('#tab-' + document.location.hash.substring(6) + '[role=tab]');
if ($tab_button.length) {
$('.pk-tabs')[0].tabs.selectTab($tab_button[0]);
}
}
});

View File

@ -1154,6 +1154,8 @@ class ViewableAgendaMixin:
class ManagedAgendaMixin(ViewableAgendaMixin):
tab_anchor = None
def check_permissions(self, user):
return self.agenda.can_be_managed(user)
@ -1165,7 +1167,10 @@ class ManagedAgendaMixin(ViewableAgendaMixin):
return kwargs
def get_success_url(self):
return reverse('chrono-manager-agenda-settings', kwargs={'pk': self.agenda.id})
url = reverse('chrono-manager-agenda-settings', kwargs={'pk': self.agenda.id})
if self.tab_anchor:
url += '#open:%s' % self.tab_anchor
return url
class AgendaEditView(ManagedAgendaMixin, UpdateView):
@ -1186,6 +1191,7 @@ agenda_edit = AgendaEditView.as_view()
class AgendaBookingDelaysView(AgendaEditView):
form_class = AgendaBookingDelaysForm
title = _('Configure booking delays')
tab_anchor = 'delays'
agenda_booking_delays = AgendaBookingDelaysView.as_view()
@ -1194,6 +1200,7 @@ agenda_booking_delays = AgendaBookingDelaysView.as_view()
class AgendaRolesView(AgendaEditView):
form_class = AgendaRolesForm
title = _('Configure roles')
tab_anchor = 'permissions'
agenda_roles = AgendaRolesView.as_view()
@ -1202,6 +1209,7 @@ agenda_roles = AgendaRolesView.as_view()
class AgendaDisplaySettingsView(AgendaEditView):
form_class = AgendaDisplaySettingsForm
title = _("Configure display options")
tab_anchor = 'display-options'
def set_agenda(self, **kwargs):
self.agenda = get_object_or_404(Agenda.objects.exclude(kind='virtual'), pk=kwargs.get('pk'))
@ -1216,6 +1224,7 @@ agenda_display_settings = AgendaDisplaySettingsView.as_view()
class AgendaBookingCheckSettingsView(AgendaEditView):
form_class = AgendaBookingCheckSettingsForm
title = _("Configure booking check options")
tab_anchor = 'booking-check-options'
def set_agenda(self, **kwargs):
self.agenda = get_object_or_404(Agenda, pk=kwargs.get('pk'), kind='events')
@ -1748,6 +1757,7 @@ agenda_open_events_view = AgendaOpenEventsView.as_view()
class ManagedAgendaSubobjectMixin:
agenda = None
tab_anchor = None
def dispatch(self, request, *args, **kwargs):
self.agenda = self.get_object().agenda
@ -1761,11 +1771,15 @@ class ManagedAgendaSubobjectMixin:
return context
def get_success_url(self):
return reverse('chrono-manager-agenda-settings', kwargs={'pk': self.agenda.id})
url = reverse('chrono-manager-agenda-settings', kwargs={'pk': self.agenda.id})
if self.tab_anchor:
url += '#open:%s' % self.tab_anchor
return url
class ManagedDeskMixin:
desk = None
tab_anchor = None
def dispatch(self, request, *args, **kwargs):
try:
@ -1790,11 +1804,15 @@ class ManagedDeskMixin:
return context
def get_success_url(self):
return reverse('chrono-manager-agenda-settings', kwargs={'pk': self.desk.agenda.id})
url = reverse('chrono-manager-agenda-settings', kwargs={'pk': self.desk.agenda.id})
if self.tab_anchor:
url += '#open:%s' % self.tab_anchor
return url
class ManagedTimePeriodMixin:
agenda = None
tab_anchor = None
def dispatch(self, request, *args, **kwargs):
self.time_period = self.get_object()
@ -1812,13 +1830,16 @@ class ManagedTimePeriodMixin:
return context
def get_success_url(self):
return reverse('chrono-manager-agenda-settings', kwargs={'pk': self.agenda.id})
url = reverse('chrono-manager-agenda-settings', kwargs={'pk': self.agenda.id})
if self.tab_anchor:
url += '#open:%s' % self.tab_anchor
return url
class ManagedTimePeriodExceptionMixin:
desk = None
unavailability_calendar = None
tab_anchor = None
def dispatch(self, request, *args, **kwargs):
object_ = self.get_object()
@ -1845,12 +1866,15 @@ class ManagedTimePeriodExceptionMixin:
def get_success_url(self):
if self.desk:
return reverse('chrono-manager-agenda-settings', kwargs={'pk': self.desk.agenda.id})
url = reverse('chrono-manager-agenda-settings', kwargs={'pk': self.desk.agenda.id})
elif self.unavailability_calendar:
return reverse(
url = reverse(
'chrono-manager-unavailability-calendar-settings',
kwargs={'pk': self.unavailability_calendar.pk},
)
if self.tab_anchor:
url += '#open:%s' % self.tab_anchor
return url
class AgendaSettingsRedirectView(RedirectView):
@ -2092,6 +2116,7 @@ class AgendaNotificationsSettingsView(ManagedAgendaMixin, UpdateView):
template_name = 'chrono/manager_agenda_notifications_form.html'
model = AgendaNotificationsSettings
form_class = AgendaNotificationsForm
tab_anchor = 'notifications'
def get_object(self):
try:
@ -2114,6 +2139,7 @@ class AgendaReminderSettingsView(AgendaEditView):
title = _('Reminder Settings')
model = AgendaReminderSettings
form_class = AgendaReminderForm
tab_anchor = 'reminders'
def get_object(self):
try:
@ -2548,6 +2574,7 @@ event_checked = EventCheckedView.as_view()
class AgendaAddResourceView(ManagedAgendaMixin, FormView):
template_name = 'chrono/manager_agenda_resource_form.html'
form_class = AgendaResourceForm
tab_anchor = 'resources'
def set_agenda(self, **kwargs):
self.agenda = get_object_or_404(Agenda, id=kwargs.get('pk'), kind='meetings')
@ -2569,6 +2596,7 @@ class AgendaResourceDeleteView(ManagedAgendaMixin, DeleteView):
template_name = 'chrono/manager_confirm_delete.html'
model = Resource
pk_url_kwarg = 'resource_pk'
tab_anchor = 'resources'
def set_agenda(self, **kwargs):
self.agenda = get_object_or_404(Agenda, id=kwargs.get('pk'), kind='meetings')
@ -2630,7 +2658,8 @@ class UnavailabilityCalendarToggleView(ManagedDeskMixin, DetailView):
break
return HttpResponseRedirect(
reverse('chrono-manager-agenda-settings', kwargs={'pk': self.desk.agenda_id})
'%s#open:time-periods'
% reverse('chrono-manager-agenda-settings', kwargs={'pk': self.desk.agenda_id})
)
@ -2731,6 +2760,7 @@ def process_time_period_add_form(form, desk=None, agenda=None):
class AgendaAddTimePeriodView(ManagedDeskMixin, FormView):
template_name = 'chrono/manager_time_period_form.html'
form_class = TimePeriodAddForm
tab_anchor = 'time-periods'
def get_form_kwargs(self):
return super(FormView, self).get_form_kwargs()
@ -2750,6 +2780,7 @@ agenda_add_time_period = AgendaAddTimePeriodView.as_view()
class VirtualAgendaAddTimePeriodView(ManagedAgendaMixin, FormView):
template_name = 'chrono/manager_time_period_form.html'
form_class = TimePeriodAddForm
tab_anchor = 'time-periods'
def get_form_kwargs(self):
return super(FormView, self).get_form_kwargs()
@ -2766,6 +2797,7 @@ class TimePeriodEditView(ManagedTimePeriodMixin, UpdateView):
template_name = 'chrono/manager_time_period_form.html'
model = TimePeriod
form_class = TimePeriodForm
tab_anchor = 'time-periods'
time_period_edit = TimePeriodEditView.as_view()
@ -2774,6 +2806,7 @@ time_period_edit = TimePeriodEditView.as_view()
class TimePeriodDeleteView(ManagedTimePeriodMixin, DeleteView):
template_name = 'chrono/manager_confirm_delete.html'
model = TimePeriod
tab_anchor = 'time-periods'
def delete(self, request, *args, **kwargs):
time_period = self.get_object()
@ -2803,6 +2836,7 @@ class AgendaAddDesk(ManagedAgendaMixin, CreateView):
model = Desk
form_class = NewDeskForm
agenda = None
tab_anchor = 'desks'
def set_agenda(self, **kwargs):
self.agenda = get_object_or_404(Agenda, pk=kwargs.get('pk'), kind='meetings')
@ -2815,6 +2849,7 @@ class DeskEditView(ManagedAgendaSubobjectMixin, UpdateView):
template_name = 'chrono/manager_desk_form.html'
model = Desk
form_class = DeskForm
tab_anchor = 'desks'
def get_queryset(self):
return super().get_queryset().filter(agenda__kind='meetings')
@ -2826,6 +2861,7 @@ desk_edit = DeskEditView.as_view()
class DeskDeleteView(ManagedAgendaSubobjectMixin, DeleteView):
template_name = 'chrono/manager_confirm_delete.html'
model = Desk
tab_anchor = 'desks'
def dispatch(self, request, *args, **kwargs):
agenda = self.get_object().agenda
@ -2895,6 +2931,7 @@ class AgendaAddTimePeriodExceptionView(ManagedDeskMixin, CreateView):
template_name = 'chrono/manager_time_period_exception_form.html'
model = TimePeriodException
form_class = NewTimePeriodExceptionForm
tab_anchor = 'time-periods'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
@ -2925,6 +2962,7 @@ class TimePeriodExceptionEditView(ManagedTimePeriodExceptionMixin, UpdateView):
template_name = 'chrono/manager_time_period_exception_form.html'
model = TimePeriodException
form_class = TimePeriodExceptionForm
tab_anchor = 'time-periods'
def form_valid(self, form):
result = super().form_valid(form)
@ -2972,6 +3010,7 @@ time_period_exception_extract_list = TimePeriodExceptionExtractListView.as_view(
class TimePeriodExceptionDeleteView(ManagedTimePeriodExceptionMixin, DeleteView):
template_name = 'chrono/manager_confirm_exception_delete.html'
model = TimePeriodException
tab_anchor = 'time-periods'
def get_success_url(self):
if self.desk:
@ -3018,6 +3057,7 @@ class DeskImportTimePeriodExceptionsView(ManagedAgendaSubobjectMixin, UpdateView
model = Desk
form_class = DeskExceptionsImportForm
template_name = 'chrono/manager_import_exceptions.html'
tab_anchor = 'time-periods'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
@ -3079,6 +3119,7 @@ desk_import_time_period_exceptions = DeskImportTimePeriodExceptionsView.as_view(
class TimePeriodExceptionSourceDeleteView(ManagedTimePeriodExceptionMixin, DeleteView):
template_name = 'chrono/manager_confirm_source_delete.html'
model = TimePeriodExceptionSource
tab_anchor = 'time-periods'
def delete(self, request, *args, **kwargs):
source = self.get_object()
@ -3106,6 +3147,7 @@ class TimePeriodExceptionSourceReplaceView(ManagedTimePeriodExceptionMixin, Upda
model = TimePeriodExceptionSource
form_class = TimePeriodExceptionSourceReplaceForm
template_name = 'chrono/manager_replace_exceptions.html'
tab_anchor = 'time-periods'
def get_queryset(self):
queryset = super().get_queryset()
@ -3136,6 +3178,7 @@ time_period_exception_source_replace = TimePeriodExceptionSourceReplaceView.as_v
class TimePeriodExceptionSourceRefreshView(ManagedTimePeriodExceptionMixin, DetailView):
model = TimePeriodExceptionSource
tab_anchor = 'time-periods'
def get_queryset(self):
queryset = super().get_queryset()
@ -3404,7 +3447,8 @@ class TimePeriodExceptionSourceToggleView(ManagedTimePeriodExceptionMixin, Detai
messages.info(self.request, message % {'source': source, 'desk': source.desk})
return HttpResponseRedirect(
reverse('chrono-manager-agenda-settings', kwargs={'pk': source.desk.agenda_id})
'%s#open:time-periods'
% reverse('chrono-manager-agenda-settings', kwargs={'pk': source.desk.agenda_id})
)

View File

@ -2248,7 +2248,7 @@ def test_virtual_agenda_settings_delete_excluded_period(app, admin_user):
url = '/manage/timeperiods/%s/delete' % tp.pk
resp = resp.click(href=url)
resp = resp.form.submit()
assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.id)
assert resp.location.endswith('/manage/agendas/%s/settings#open:time-periods' % agenda.id)
assert TimePeriod.objects.count() == 0

View File

@ -378,7 +378,7 @@ def test_meetings_agenda_delete_desk(app, admin_user):
resp = resp.click('Desk A')
resp = resp.click('Delete')
resp = resp.form.submit()
assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.pk)
assert resp.location.endswith('/manage/agendas/%s/settings#open:desks' % agenda.pk)
assert Desk.objects.count() == 1
# only one desk

View File

@ -572,7 +572,7 @@ def test_meetings_agenda_resources(app, admin_user):
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 resp.location.endswith('/manage/agendas/%s/settings#open:resources' % agenda.pk)
assert list(agenda.resources.all()) == [resource]
resp = resp.follow()
assert '/manage/resource/%s/' % resource.pk in resp.text
@ -582,7 +582,7 @@ def test_meetings_agenda_resources(app, admin_user):
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 resp.location.endswith('/manage/agendas/%s/settings#open:resources' % agenda.pk)
assert list(agenda.resources.all()) == []
resp = resp.follow()
assert '/manage/resource/%s/' % resource.pk not in resp.text

View File

@ -211,7 +211,7 @@ def test_meetings_agenda_delete_time_period(app, admin_user):
resp = resp.click('Wednesday', index=0)
resp = resp.click('Delete')
resp = resp.form.submit()
assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.id)
assert resp.location.endswith('/manage/agendas/%s/settings#open:time-periods' % agenda.id)
assert TimePeriod.objects.count() == 1

View File

@ -216,7 +216,7 @@ def test_unavailability_calendar_in_desk(app, admin_user):
resp = resp.click(
href='/manage/desk/%s/unavailability-calendar/%s/toggle/' % (desk.pk, unavailability_calendar.pk)
)
settings_url = '/manage/agendas/%s/settings' % agenda.pk
settings_url = '/manage/agendas/%s/settings#open:time-periods' % agenda.pk
assert resp.location.endswith(settings_url)
# exception from calendar displayed on the settings page
resp = app.get(settings_url)
@ -233,7 +233,7 @@ def test_unavailability_calendar_in_desk(app, admin_user):
resp = resp.click(
href='/manage/desk/%s/unavailability-calendar/%s/toggle/' % (desk.pk, unavailability_calendar.pk)
)
assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.pk)
assert resp.location.endswith('/manage/agendas/%s/settings#open:time-periods' % agenda.pk)
resp = app.get(exceptions_url)
assert 'calendar' in resp.text
assert 'enable' in resp.text
@ -255,7 +255,7 @@ def test_unavailability_calendar_in_desk(app, admin_user):
resp = resp.click(
href='/manage/desk/%s/unavailability-calendar/%s/toggle/' % (desk.pk, unavailability_calendar.pk)
)
assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.pk)
assert resp.location.endswith('/manage/agendas/%s/settings#open:time-periods' % agenda.pk)
resp = resp.follow()
assert 'One or several bookings overlap with exceptions.' in resp.text