Projet

Général

Profil

0001-public-add-page-selector-in-site-settings-58475.patch

Valentin Deniaud, 23 novembre 2021 14:22

Télécharger (12,4 ko)

Voir les différences:

Subject: [PATCH 1/2] public: add page selector in site settings (#58475)

 combo/data/migrations/0049_sitesettings.py    |  8 ++--
 .../migrations/0051_auto_20211110_1521.py     | 40 +++++++++++++++++++
 combo/data/models.py                          | 26 ++++++++++--
 .../widgets/select_with_other_option.html     |  8 ++++
 combo/manager/forms.py                        |  8 ++++
 .../templates/combo/site_settings.html        | 29 +++++++++++++-
 combo/public/views.py                         | 14 +++++--
 tests/test_manager.py                         | 12 ++++++
 tests/test_public.py                          | 23 +++++++++++
 9 files changed, 155 insertions(+), 13 deletions(-)
 create mode 100644 combo/data/migrations/0051_auto_20211110_1521.py
 create mode 100644 combo/data/templates/combo/widgets/select_with_other_option.html
combo/data/migrations/0049_sitesettings.py
21 21
                    'initial_login_page_path',
22 22
                    models.CharField(
23 23
                        max_length=100,
24
                        verbose_name='Initial login page path',
25
                        help_text='Page to redirect to the first time user logs in.',
24
                        verbose_name='',
25
                        help_text='Path or full URL.',
26 26
                        blank=True,
27 27
                    ),
28 28
                ),
......
30 30
                    'welcome_page_path',
31 31
                    models.CharField(
32 32
                        max_length=100,
33
                        verbose_name='Welcome page path',
34
                        help_text='Page to redirect to on the first visit, to suggest user to log in.',
33
                        verbose_name='',
34
                        help_text='Path or full URL.',
35 35
                        blank=True,
36 36
                    ),
37 37
                ),
combo/data/migrations/0051_auto_20211110_1521.py
1
# Generated by Django 2.2.19 on 2021-11-10 14:21
2

  
3
import django.db.models.deletion
4
from django.db import migrations, models
5

  
6

  
7
class Migration(migrations.Migration):
8

  
9
    dependencies = [
10
        ('data', '0050_populate_site_settings'),
11
    ]
12

  
13
    operations = [
14
        migrations.AddField(
15
            model_name='sitesettings',
16
            name='initial_login_page',
17
            field=models.ForeignKey(
18
                blank=True,
19
                null=True,
20
                on_delete=django.db.models.deletion.SET_NULL,
21
                related_name='+',
22
                to='data.Page',
23
                verbose_name='Initial login page',
24
                help_text='Page to redirect to the first time user logs in.',
25
            ),
26
        ),
27
        migrations.AddField(
28
            model_name='sitesettings',
29
            name='welcome_page',
30
            field=models.ForeignKey(
31
                blank=True,
32
                null=True,
33
                on_delete=django.db.models.deletion.SET_NULL,
34
                related_name='+',
35
                to='data.Page',
36
                verbose_name='Welcome page',
37
                help_text='Page to redirect to on the first visit, to suggest user to log in.',
38
            ),
39
        ),
40
    ]
combo/data/models.py
2209 2209

  
2210 2210

  
2211 2211
class SiteSettings(models.Model):
2212
    welcome_page_path = models.CharField(
2213
        _('Welcome page path'),
2212
    welcome_page = models.ForeignKey(
2213
        to=Page,
2214
        verbose_name=_('Welcome page'),
2215
        on_delete=models.SET_NULL,
2216
        null=True,
2217
        blank=True,
2218
        related_name='+',
2214 2219
        help_text=_('Page to redirect to on the first visit, to suggest user to log in.'),
2220
    )
2221
    welcome_page_path = models.CharField(
2222
        verbose_name='',
2223
        help_text=_('Path or full URL.'),
2215 2224
        max_length=100,
2216 2225
        blank=True,
2217 2226
    )
2218
    initial_login_page_path = models.CharField(
2219
        _('Initial login page path'),
2227
    initial_login_page = models.ForeignKey(
2228
        to=Page,
2229
        verbose_name=_('Initial login page'),
2220 2230
        help_text=_('Page to redirect to the first time user logs in.'),
2231
        on_delete=models.SET_NULL,
2232
        null=True,
2233
        blank=True,
2234
        related_name='+',
2235
    )
2236
    initial_login_page_path = models.CharField(
2237
        verbose_name='',
2238
        help_text=_('Path or full URL.'),
2221 2239
        max_length=100,
2222 2240
        blank=True,
2223 2241
    )
combo/data/templates/combo/widgets/select_with_other_option.html
1
{% load i18n %}
2

  
3
<select name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}>{% for group_name, group_choices, group_index in widget.optgroups %}{% if group_name %}
4
  <optgroup label="{{ group_name }}">{% endif %}{% for option in group_choices %}
5
  {% include option.template_name with widget=option %}{% endfor %}{% if group_name %}
6
  </optgroup>{% endif %}{% endfor %}
7
<!-- "other" option: -->  <option value="" data-other="true">{% trans "Other:" %}</option>
8
</select>
combo/manager/forms.py
326 326
    class Meta:
327 327
        model = SiteSettings
328 328
        fields = '__all__'
329

  
330
    def __init__(self, *args, **kwargs):
331
        super().__init__(*args, **kwargs)
332
        self.fields['welcome_page'].widget.template_name = 'combo/widgets/select_with_other_option.html'
333
        self.fields['welcome_page'].widget.attrs['class'] = 'page-selector'
334
        self.fields['initial_login_page'].widget.template_name = 'combo/widgets/select_with_other_option.html'
335
        self.fields['initial_login_page'].widget.attrs['class'] = 'page-selector'
336
        self.fields['welcome_page'].queryset = self.fields['welcome_page'].queryset.filter(public=True)
combo/manager/templates/combo/site_settings.html
7 7

  
8 8
{% block content %}
9 9

  
10
<form method="post">
10
<form method="post" id="site-settings-form">
11 11
  {% csrf_token %}
12 12
  {{ form.as_p }}
13 13
  <div class="buttons">
14 14
    <button class="submit-button">{% trans "Save" %}</button>
15 15
    <a class="cancel" href="{% url 'combo-manager-homepage' %}">{% trans 'Cancel' %}</a>
16 16
  </div>
17

  
18
  <script>
19
  $('select.page-selector').each(function() {
20
    field_id = $(this).attr('id')
21
    custom_url_field_id = '#' + field_id + '_path'
22
    if($(custom_url_field_id).val())
23
      $(this).children('option[data-other=true]').prop('selected', true);
24
  });
25

  
26
  $('select').change(function(){
27
    field_id = $(this).attr('id')
28
    custom_url_field_id = '#' + field_id + '_path'
29
    if ($('option:selected', this).data('other'))
30
      $(custom_url_field_id).parent('p').show();
31
    else
32
      $(custom_url_field_id).parent('p').hide();
33
  }).trigger('change');
34

  
35
  $('form#site-settings-form').submit(function() {
36
    $('select.page-selector').each(function() {
37
      field_id = $(this).attr('id')
38
      custom_url_field_id = '#' + field_id + '_path'
39
      if(!$('option:selected', this).data('other'))
40
        $(custom_url_field_id).val('');
41
    });
42
  });
43
  </script>
17 44
</form>
18 45
{% endblock %}
combo/public/views.py
463 463
    site_settings = SiteSettings.objects.get()
464 464
    if (
465 465
        parts == ['index']
466
        and site_settings.initial_login_page_path
466
        and (site_settings.initial_login_page or site_settings.initial_login_page_path)
467 467
        and (request.user and not request.user.is_anonymous)
468 468
    ):
469 469
        profile, dummy = Profile.objects.get_or_create(user=request.user)
......
471 471
            # first connection of user, record that and redirect to welcome URL
472 472
            profile.initial_login_view_timestamp = timezone.now()
473 473
            profile.save()
474
            page_path = utils.get_templated_url(site_settings.initial_login_page_path)
474
            if site_settings.initial_login_page:
475
                page_path = site_settings.initial_login_page.get_online_url()
476
            else:
477
                page_path = utils.get_templated_url(site_settings.initial_login_page_path)
475 478
            return HttpResponseRedirect(page_path)
476 479

  
477 480
    if (
478 481
        parts == ['index']
479
        and site_settings.welcome_page_path
482
        and (site_settings.welcome_page or site_settings.welcome_page_path)
480 483
        and (not request.user or request.user.is_anonymous)
481 484
    ):
482 485
        if not request.session.setdefault('visited', False):
483 486
            # first visit, the user is not logged in.
484 487
            request.session['visited'] = True
485
            page_path = utils.get_templated_url(site_settings.welcome_page_path)
488
            if site_settings.welcome_page:
489
                page_path = site_settings.welcome_page.get_online_url()
490
            else:
491
                page_path = utils.get_templated_url(site_settings.welcome_page_path)
486 492
            return HttpResponseRedirect(page_path)
487 493

  
488 494
    try:
tests/test_manager.py
2668 2668

  
2669 2669

  
2670 2670
def test_site_settings(app, admin_user):
2671
    public_page = Page.objects.create(title='Public', slug='public')
2672
    private_page = Page.objects.create(title='Private', slug='private', public=False)
2671 2673
    app = login(app)
2672 2674

  
2673 2675
    resp = app.get('/manage/')
......
2687 2689
    site_settings.refresh_from_db()
2688 2690
    assert site_settings.welcome_page_path == ''
2689 2691
    assert site_settings.initial_login_page_path == ''
2692

  
2693
    assert list(resp.context['form'].fields['welcome_page'].queryset) == [public_page]
2694
    assert list(resp.context['form'].fields['initial_login_page'].queryset) == [public_page, private_page]
2695
    resp.form['welcome_page'].select(text='Public')
2696
    resp.form['initial_login_page'].select(text='Private')
2697
    resp.form.submit()
2698

  
2699
    site_settings.refresh_from_db()
2700
    assert site_settings.welcome_page == public_page
2701
    assert site_settings.initial_login_page == private_page
tests/test_public.py
696 696
        resp = app.get('/', status=302)
697 697
        assert resp.location == 'https://authentic.example.org/bar/'
698 698

  
699
    profile.initial_login_view_timestamp = None
700
    profile.save(update_fields=['initial_login_view_timestamp'])
701

  
702
    site_settings.initial_login_page = page
703
    site_settings.save()
704

  
705
    # first visit
706
    app = login(app)
707
    resp = app.get('/', status=302)
708
    assert urllib.parse.urlparse(resp.location).path == '/initial-login/'
709

  
710
    # visit again
711
    resp = app.get('/', status=200)
712

  
699 713

  
700 714
def test_welcome_page(app, admin_user):
701 715
    Page.objects.all().delete()
......
744 758
        resp = app.get('/', status=302)
745 759
        assert resp.location == 'https://authentic.example.org/bar/'
746 760

  
761
    site_settings.welcome_page = page
762
    site_settings.save()
763

  
764
    app.cookiejar.clear()
765
    resp = app.get('/', status=302)
766
    assert urllib.parse.urlparse(resp.location).path == '/welcome/'
767

  
768
    resp = app.get('/', status=200)
769

  
747 770

  
748 771
def test_post_cell(app):
749 772
    Page.objects.all().delete()
750
-