Projet

Général

Profil

0002-manager-open-the-correct-tab-after-redirect-65653.patch

Lauréline Guérin, 24 mai 2022 22:19

Télécharger (17,7 ko)

Voir les différences:

Subject: [PATCH 2/2] manager: open the correct tab after redirect (#65653)

 chrono/manager/static/js/chrono.manager.js    | 10 +++
 chrono/manager/views.py                       | 62 ++++++++++++++++---
 tests/manager/test_all.py                     |  2 +-
 tests/manager/test_meetings_agenda_options.py |  2 +-
 tests/manager/test_resource.py                |  4 +-
 tests/manager/test_timeperiod.py              |  2 +-
 tests/manager/test_unavailability_calendar.py |  6 +-
 7 files changed, 71 insertions(+), 17 deletions(-)
chrono/manager/static/js/chrono.manager.js
81 81
      });
82 82
    }
83 83
  });
84

  
85
  window.addEventListener('DOMContentLoaded', function() {
86
    /* focus tab from #open:<tab slug> anchor, to point to open panel */
87
    if (document.location.hash && document.location.hash.indexOf('#open:') == 0) {
88
      const $tab_button = $('#tab-' + document.location.hash.substring(6) + '[role=tab]');
89
      if ($tab_button.length) {
90
        $('.pk-tabs')[0].tabs.selectTab($tab_button[0]);
91
      }
92
    }
93
  });
84 94
});
chrono/manager/views.py
1201 1201

  
1202 1202

  
1203 1203
class ManagedAgendaMixin(ViewableAgendaMixin):
1204
    tab_anchor = None
1205

  
1204 1206
    def check_permissions(self, user):
1205 1207
        return self.agenda.can_be_managed(user)
1206 1208

  
......
1212 1214
        return kwargs
1213 1215

  
1214 1216
    def get_success_url(self):
1215
        return reverse('chrono-manager-agenda-settings', kwargs={'pk': self.agenda.id})
1217
        url = reverse('chrono-manager-agenda-settings', kwargs={'pk': self.agenda.id})
1218
        if self.tab_anchor:
1219
            url += '#open:%s' % self.tab_anchor
1220
        return url
1216 1221

  
1217 1222

  
1218 1223
class AgendaEditView(ManagedAgendaMixin, UpdateView):
......
1233 1238
class AgendaBookingDelaysView(AgendaEditView):
1234 1239
    form_class = AgendaBookingDelaysForm
1235 1240
    title = _('Configure booking delays')
1241
    tab_anchor = 'delays'
1236 1242

  
1237 1243

  
1238 1244
agenda_booking_delays = AgendaBookingDelaysView.as_view()
......
1241 1247
class AgendaRolesView(AgendaEditView):
1242 1248
    form_class = AgendaRolesForm
1243 1249
    title = _('Configure roles')
1250
    tab_anchor = 'permissions'
1244 1251

  
1245 1252

  
1246 1253
agenda_roles = AgendaRolesView.as_view()
......
1249 1256
class AgendaDisplaySettingsView(AgendaEditView):
1250 1257
    form_class = AgendaDisplaySettingsForm
1251 1258
    title = _("Configure display options")
1259
    tab_anchor = 'display-options'
1252 1260

  
1253 1261
    def set_agenda(self, **kwargs):
1254 1262
        self.agenda = get_object_or_404(Agenda.objects.exclude(kind='virtual'), pk=kwargs.get('pk'))
......
1263 1271
class AgendaBookingCheckSettingsView(AgendaEditView):
1264 1272
    form_class = AgendaBookingCheckSettingsForm
1265 1273
    title = _("Configure booking check options")
1274
    tab_anchor = 'booking-check-options'
1266 1275

  
1267 1276
    def set_agenda(self, **kwargs):
1268 1277
        self.agenda = get_object_or_404(Agenda, pk=kwargs.get('pk'), kind='events')
......
1795 1804

  
1796 1805
class ManagedAgendaSubobjectMixin:
1797 1806
    agenda = None
1807
    tab_anchor = None
1798 1808

  
1799 1809
    def dispatch(self, request, *args, **kwargs):
1800 1810
        self.agenda = self.get_object().agenda
......
1808 1818
        return context
1809 1819

  
1810 1820
    def get_success_url(self):
1811
        return reverse('chrono-manager-agenda-settings', kwargs={'pk': self.agenda.id})
1821
        url = reverse('chrono-manager-agenda-settings', kwargs={'pk': self.agenda.id})
1822
        if self.tab_anchor:
1823
            url += '#open:%s' % self.tab_anchor
1824
        return url
1812 1825

  
1813 1826

  
1814 1827
class ManagedDeskMixin:
1815 1828
    desk = None
1829
    tab_anchor = None
1816 1830

  
1817 1831
    def dispatch(self, request, *args, **kwargs):
1818 1832
        try:
......
1837 1851
        return context
1838 1852

  
1839 1853
    def get_success_url(self):
1840
        return reverse('chrono-manager-agenda-settings', kwargs={'pk': self.desk.agenda.id})
1854
        url = reverse('chrono-manager-agenda-settings', kwargs={'pk': self.desk.agenda.id})
1855
        if self.tab_anchor:
1856
            url += '#open:%s' % self.tab_anchor
1857
        return url
1841 1858

  
1842 1859

  
1843 1860
class ManagedTimePeriodMixin:
1844 1861
    agenda = None
1862
    tab_anchor = None
1845 1863

  
1846 1864
    def dispatch(self, request, *args, **kwargs):
1847 1865
        self.time_period = self.get_object()
......
1859 1877
        return context
1860 1878

  
1861 1879
    def get_success_url(self):
1862
        return reverse('chrono-manager-agenda-settings', kwargs={'pk': self.agenda.id})
1880
        url = reverse('chrono-manager-agenda-settings', kwargs={'pk': self.agenda.id})
1881
        if self.tab_anchor:
1882
            url += '#open:%s' % self.tab_anchor
1883
        return url
1863 1884

  
1864 1885

  
1865 1886
class ManagedTimePeriodExceptionMixin:
1866

  
1867 1887
    desk = None
1868 1888
    unavailability_calendar = None
1889
    tab_anchor = None
1869 1890

  
1870 1891
    def dispatch(self, request, *args, **kwargs):
1871 1892
        object_ = self.get_object()
......
1892 1913

  
1893 1914
    def get_success_url(self):
1894 1915
        if self.desk:
1895
            return reverse('chrono-manager-agenda-settings', kwargs={'pk': self.desk.agenda.id})
1916
            url = reverse('chrono-manager-agenda-settings', kwargs={'pk': self.desk.agenda.id})
1896 1917
        elif self.unavailability_calendar:
1897
            return reverse(
1918
            url = reverse(
1898 1919
                'chrono-manager-unavailability-calendar-settings',
1899 1920
                kwargs={'pk': self.unavailability_calendar.pk},
1900 1921
            )
1922
        if self.tab_anchor:
1923
            url += '#open:%s' % self.tab_anchor
1924
        return url
1901 1925

  
1902 1926

  
1903 1927
class AgendaSettings(ManagedAgendaMixin, DetailView):
......
2136 2160
    template_name = 'chrono/manager_agenda_notifications_form.html'
2137 2161
    model = AgendaNotificationsSettings
2138 2162
    form_class = AgendaNotificationsForm
2163
    tab_anchor = 'notifications'
2139 2164

  
2140 2165
    def get_object(self):
2141 2166
        try:
......
2158 2183
    title = _('Reminder Settings')
2159 2184
    model = AgendaReminderSettings
2160 2185
    form_class = AgendaReminderForm
2186
    tab_anchor = 'reminders'
2161 2187

  
2162 2188
    def get_object(self):
2163 2189
        try:
......
2592 2618
class AgendaAddResourceView(ManagedAgendaMixin, FormView):
2593 2619
    template_name = 'chrono/manager_agenda_resource_form.html'
2594 2620
    form_class = AgendaResourceForm
2621
    tab_anchor = 'resources'
2595 2622

  
2596 2623
    def set_agenda(self, **kwargs):
2597 2624
        self.agenda = get_object_or_404(Agenda, id=kwargs.get('pk'), kind='meetings')
......
2613 2640
    template_name = 'chrono/manager_confirm_delete.html'
2614 2641
    model = Resource
2615 2642
    pk_url_kwarg = 'resource_pk'
2643
    tab_anchor = 'resources'
2616 2644

  
2617 2645
    def set_agenda(self, **kwargs):
2618 2646
        self.agenda = get_object_or_404(Agenda, id=kwargs.get('pk'), kind='meetings')
......
2674 2702
                        break
2675 2703

  
2676 2704
        return HttpResponseRedirect(
2677
            reverse('chrono-manager-agenda-settings', kwargs={'pk': self.desk.agenda_id})
2705
            '%s#open:time-periods'
2706
            % reverse('chrono-manager-agenda-settings', kwargs={'pk': self.desk.agenda_id})
2678 2707
        )
2679 2708

  
2680 2709

  
......
2775 2804
class AgendaAddTimePeriodView(ManagedDeskMixin, FormView):
2776 2805
    template_name = 'chrono/manager_time_period_form.html'
2777 2806
    form_class = TimePeriodAddForm
2807
    tab_anchor = 'time-periods'
2778 2808

  
2779 2809
    def get_form_kwargs(self):
2780 2810
        return super(FormView, self).get_form_kwargs()
......
2794 2824
class VirtualAgendaAddTimePeriodView(ManagedAgendaMixin, FormView):
2795 2825
    template_name = 'chrono/manager_time_period_form.html'
2796 2826
    form_class = TimePeriodAddForm
2827
    tab_anchor = 'time-periods'
2797 2828

  
2798 2829
    def get_form_kwargs(self):
2799 2830
        return super(FormView, self).get_form_kwargs()
......
2810 2841
    template_name = 'chrono/manager_time_period_form.html'
2811 2842
    model = TimePeriod
2812 2843
    form_class = TimePeriodForm
2844
    tab_anchor = 'time-periods'
2813 2845

  
2814 2846

  
2815 2847
time_period_edit = TimePeriodEditView.as_view()
......
2818 2850
class TimePeriodDeleteView(ManagedTimePeriodMixin, DeleteView):
2819 2851
    template_name = 'chrono/manager_confirm_delete.html'
2820 2852
    model = TimePeriod
2853
    tab_anchor = 'time-periods'
2821 2854

  
2822 2855
    def delete(self, request, *args, **kwargs):
2823 2856
        time_period = self.get_object()
......
2847 2880
    model = Desk
2848 2881
    form_class = NewDeskForm
2849 2882
    agenda = None
2883
    tab_anchor = 'desks'
2850 2884

  
2851 2885
    def set_agenda(self, **kwargs):
2852 2886
        self.agenda = get_object_or_404(Agenda, pk=kwargs.get('pk'), kind='meetings')
......
2859 2893
    template_name = 'chrono/manager_desk_form.html'
2860 2894
    model = Desk
2861 2895
    form_class = DeskForm
2896
    tab_anchor = 'desks'
2862 2897

  
2863 2898
    def get_queryset(self):
2864 2899
        return super().get_queryset().filter(agenda__kind='meetings')
......
2870 2905
class DeskDeleteView(ManagedAgendaSubobjectMixin, DeleteView):
2871 2906
    template_name = 'chrono/manager_confirm_delete.html'
2872 2907
    model = Desk
2908
    tab_anchor = 'desks'
2873 2909

  
2874 2910
    def dispatch(self, request, *args, **kwargs):
2875 2911
        agenda = self.get_object().agenda
......
2939 2975
    template_name = 'chrono/manager_time_period_exception_form.html'
2940 2976
    model = TimePeriodException
2941 2977
    form_class = NewTimePeriodExceptionForm
2978
    tab_anchor = 'time-periods'
2942 2979

  
2943 2980
    def get_context_data(self, **kwargs):
2944 2981
        context = super().get_context_data(**kwargs)
......
2969 3006
    template_name = 'chrono/manager_time_period_exception_form.html'
2970 3007
    model = TimePeriodException
2971 3008
    form_class = TimePeriodExceptionForm
3009
    tab_anchor = 'time-periods'
2972 3010

  
2973 3011
    def form_valid(self, form):
2974 3012
        result = super().form_valid(form)
......
3016 3054
class TimePeriodExceptionDeleteView(ManagedTimePeriodExceptionMixin, DeleteView):
3017 3055
    template_name = 'chrono/manager_confirm_exception_delete.html'
3018 3056
    model = TimePeriodException
3057
    tab_anchor = 'time-periods'
3019 3058

  
3020 3059
    def get_success_url(self):
3021 3060
        if self.desk:
......
3062 3101
    model = Desk
3063 3102
    form_class = DeskExceptionsImportForm
3064 3103
    template_name = 'chrono/manager_import_exceptions.html'
3104
    tab_anchor = 'time-periods'
3065 3105

  
3066 3106
    def get_context_data(self, **kwargs):
3067 3107
        context = super().get_context_data(**kwargs)
......
3123 3163
class TimePeriodExceptionSourceDeleteView(ManagedTimePeriodExceptionMixin, DeleteView):
3124 3164
    template_name = 'chrono/manager_confirm_source_delete.html'
3125 3165
    model = TimePeriodExceptionSource
3166
    tab_anchor = 'time-periods'
3126 3167

  
3127 3168
    def delete(self, request, *args, **kwargs):
3128 3169
        source = self.get_object()
......
3150 3191
    model = TimePeriodExceptionSource
3151 3192
    form_class = TimePeriodExceptionSourceReplaceForm
3152 3193
    template_name = 'chrono/manager_replace_exceptions.html'
3194
    tab_anchor = 'time-periods'
3153 3195

  
3154 3196
    def get_queryset(self):
3155 3197
        queryset = super().get_queryset()
......
3180 3222

  
3181 3223
class TimePeriodExceptionSourceRefreshView(ManagedTimePeriodExceptionMixin, DetailView):
3182 3224
    model = TimePeriodExceptionSource
3225
    tab_anchor = 'time-periods'
3183 3226

  
3184 3227
    def get_queryset(self):
3185 3228
        queryset = super().get_queryset()
......
3448 3491

  
3449 3492
        messages.info(self.request, message % {'source': source, 'desk': source.desk})
3450 3493
        return HttpResponseRedirect(
3451
            reverse('chrono-manager-agenda-settings', kwargs={'pk': source.desk.agenda_id})
3494
            '%s#open:time-periods'
3495
            % reverse('chrono-manager-agenda-settings', kwargs={'pk': source.desk.agenda_id})
3452 3496
        )
3453 3497

  
3454 3498

  
tests/manager/test_all.py
2274 2274
    url = '/manage/timeperiods/%s/delete' % tp.pk
2275 2275
    resp = resp.click(href=url)
2276 2276
    resp = resp.form.submit()
2277
    assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.id)
2277
    assert resp.location.endswith('/manage/agendas/%s/settings#open:time-periods' % agenda.id)
2278 2278
    assert TimePeriod.objects.count() == 0
2279 2279

  
2280 2280

  
tests/manager/test_meetings_agenda_options.py
378 378
    resp = resp.click('Desk A')
379 379
    resp = resp.click('Delete')
380 380
    resp = resp.form.submit()
381
    assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.pk)
381
    assert resp.location.endswith('/manage/agendas/%s/settings#open:desks' % agenda.pk)
382 382
    assert Desk.objects.count() == 1
383 383

  
384 384
    # only one desk
tests/manager/test_resource.py
572 572
    assert list(resp.context['form'].fields['resource'].queryset) == [resource]
573 573
    resp.form['resource'] = resource.pk
574 574
    resp = resp.form.submit()
575
    assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.pk)
575
    assert resp.location.endswith('/manage/agendas/%s/settings#open:resources' % agenda.pk)
576 576
    assert list(agenda.resources.all()) == [resource]
577 577
    resp = resp.follow()
578 578
    assert '/manage/resource/%s/' % resource.pk in resp.text
......
582 582

  
583 583
    resp = app.get('/manage/agendas/%s/resource/%s/delete/' % (agenda.pk, resource.pk))
584 584
    resp = resp.form.submit()
585
    assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.pk)
585
    assert resp.location.endswith('/manage/agendas/%s/settings#open:resources' % agenda.pk)
586 586
    assert list(agenda.resources.all()) == []
587 587
    resp = resp.follow()
588 588
    assert '/manage/resource/%s/' % resource.pk not in resp.text
tests/manager/test_timeperiod.py
211 211
    resp = resp.click('Wednesday', index=0)
212 212
    resp = resp.click('Delete')
213 213
    resp = resp.form.submit()
214
    assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.id)
214
    assert resp.location.endswith('/manage/agendas/%s/settings#open:time-periods' % agenda.id)
215 215
    assert TimePeriod.objects.count() == 1
216 216

  
217 217

  
tests/manager/test_unavailability_calendar.py
216 216
    resp = resp.click(
217 217
        href='/manage/desk/%s/unavailability-calendar/%s/toggle/' % (desk.pk, unavailability_calendar.pk)
218 218
    )
219
    settings_url = '/manage/agendas/%s/settings' % agenda.pk
219
    settings_url = '/manage/agendas/%s/settings#open:time-periods' % agenda.pk
220 220
    assert resp.location.endswith(settings_url)
221 221
    # exception from calendar displayed on the settings page
222 222
    resp = app.get(settings_url)
......
233 233
    resp = resp.click(
234 234
        href='/manage/desk/%s/unavailability-calendar/%s/toggle/' % (desk.pk, unavailability_calendar.pk)
235 235
    )
236
    assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.pk)
236
    assert resp.location.endswith('/manage/agendas/%s/settings#open:time-periods' % agenda.pk)
237 237
    resp = app.get(exceptions_url)
238 238
    assert 'calendar' in resp.text
239 239
    assert 'enable' in resp.text
......
255 255
    resp = resp.click(
256 256
        href='/manage/desk/%s/unavailability-calendar/%s/toggle/' % (desk.pk, unavailability_calendar.pk)
257 257
    )
258
    assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.pk)
258
    assert resp.location.endswith('/manage/agendas/%s/settings#open:time-periods' % agenda.pk)
259 259
    resp = resp.follow()
260 260
    assert 'One or several bookings overlap with exceptions.' in resp.text
261 261

  
262
-