public: add page selector in site settings (#58475)

This commit is contained in:
Valentin Deniaud 2021-11-10 15:21:57 +01:00
parent 6b1f7d1d4d
commit 17400f7110
9 changed files with 157 additions and 13 deletions

View File

@ -21,8 +21,8 @@ class Migration(migrations.Migration):
'initial_login_page_path',
models.CharField(
max_length=100,
verbose_name='Initial login page path',
help_text='Page to redirect to the first time user logs in.',
verbose_name='',
help_text='Path or full URL.',
blank=True,
),
),
@ -30,8 +30,8 @@ class Migration(migrations.Migration):
'welcome_page_path',
models.CharField(
max_length=100,
verbose_name='Welcome page path',
help_text='Page to redirect to on the first visit, to suggest user to log in.',
verbose_name='',
help_text='Path or full URL.',
blank=True,
),
),

View File

@ -0,0 +1,40 @@
# Generated by Django 2.2.19 on 2021-11-10 14:21
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('data', '0050_populate_site_settings'),
]
operations = [
migrations.AddField(
model_name='sitesettings',
name='initial_login_page',
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name='+',
to='data.Page',
verbose_name='Initial login page',
help_text='Page to redirect to the first time user logs in.',
),
),
migrations.AddField(
model_name='sitesettings',
name='welcome_page',
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name='+',
to='data.Page',
verbose_name='Welcome page',
help_text='Page to redirect to on the first visit, to suggest user to log in.',
),
),
]

View File

@ -2222,15 +2222,33 @@ def cell_maintain_page_cell_cache(sender, instance=None, **kwargs):
class SiteSettings(models.Model):
welcome_page_path = models.CharField(
_('Welcome page path'),
welcome_page = models.ForeignKey(
to=Page,
verbose_name=_('Welcome page'),
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='+',
help_text=_('Page to redirect to on the first visit, to suggest user to log in.'),
)
welcome_page_path = models.CharField(
verbose_name='',
help_text=_('Path or full URL.'),
max_length=100,
blank=True,
)
initial_login_page_path = models.CharField(
_('Initial login page path'),
initial_login_page = models.ForeignKey(
to=Page,
verbose_name=_('Initial login page'),
help_text=_('Page to redirect to the first time user logs in.'),
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='+',
)
initial_login_page_path = models.CharField(
verbose_name='',
help_text=_('Path or full URL.'),
max_length=100,
blank=True,
)

View File

@ -0,0 +1,8 @@
{% load i18n %}
<select name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}>{% for group_name, group_choices, group_index in widget.optgroups %}{% if group_name %}
<optgroup label="{{ group_name }}">{% endif %}{% for option in group_choices %}
{% include option.template_name with widget=option %}{% endfor %}{% if group_name %}
</optgroup>{% endif %}{% endfor %}
<!-- "other" option: --> <option value="" data-other="true">{% trans "Other:" %}</option>
</select>

View File

@ -326,3 +326,11 @@ class SiteSettingsForm(forms.ModelForm):
class Meta:
model = SiteSettings
fields = '__all__'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['welcome_page'].widget.template_name = 'combo/widgets/select_with_other_option.html'
self.fields['welcome_page'].widget.attrs['class'] = 'page-selector'
self.fields['initial_login_page'].widget.template_name = 'combo/widgets/select_with_other_option.html'
self.fields['initial_login_page'].widget.attrs['class'] = 'page-selector'
self.fields['welcome_page'].queryset = self.fields['welcome_page'].queryset.filter(public=True)

View File

@ -7,12 +7,39 @@
{% block content %}
<form method="post">
<form method="post" id="site-settings-form">
{% csrf_token %}
{{ form.as_p }}
<div class="buttons">
<button class="submit-button">{% trans "Save" %}</button>
<a class="cancel" href="{% url 'combo-manager-homepage' %}">{% trans 'Cancel' %}</a>
</div>
<script>
$('select.page-selector').each(function() {
field_id = $(this).attr('id')
custom_url_field_id = '#' + field_id + '_path'
if($(custom_url_field_id).val())
$(this).children('option[data-other=true]').prop('selected', true);
});
$('select').change(function(){
field_id = $(this).attr('id')
custom_url_field_id = '#' + field_id + '_path'
if ($('option:selected', this).data('other'))
$(custom_url_field_id).parent('p').show();
else
$(custom_url_field_id).parent('p').hide();
}).trigger('change');
$('form#site-settings-form').submit(function() {
$('select.page-selector').each(function() {
field_id = $(this).attr('id')
custom_url_field_id = '#' + field_id + '_path'
if(!$('option:selected', this).data('other'))
$(custom_url_field_id).val('');
});
});
</script>
</form>
{% endblock %}

View File

@ -463,7 +463,7 @@ def page(request):
site_settings = SiteSettings.objects.get()
if (
parts == ['index']
and site_settings.initial_login_page_path
and (site_settings.initial_login_page or site_settings.initial_login_page_path)
and (request.user and not request.user.is_anonymous)
):
profile, dummy = Profile.objects.get_or_create(user=request.user)
@ -471,18 +471,24 @@ def page(request):
# first connection of user, record that and redirect to welcome URL
profile.initial_login_view_timestamp = timezone.now()
profile.save()
page_path = utils.get_templated_url(site_settings.initial_login_page_path)
if site_settings.initial_login_page:
page_path = site_settings.initial_login_page.get_online_url()
else:
page_path = utils.get_templated_url(site_settings.initial_login_page_path)
return HttpResponseRedirect(page_path)
if (
parts == ['index']
and site_settings.welcome_page_path
and (site_settings.welcome_page or site_settings.welcome_page_path)
and (not request.user or request.user.is_anonymous)
):
if not request.session.setdefault('visited', False):
# first visit, the user is not logged in.
request.session['visited'] = True
page_path = utils.get_templated_url(site_settings.welcome_page_path)
if site_settings.welcome_page:
page_path = site_settings.welcome_page.get_online_url()
else:
page_path = utils.get_templated_url(site_settings.welcome_page_path)
return HttpResponseRedirect(page_path)
try:

View File

@ -2689,11 +2689,15 @@ def test_redirect_to_page_edit(app, admin_user):
def test_site_settings(app, admin_user):
public_page = Page.objects.create(title='Public', slug='public')
private_page = Page.objects.create(title='Private', slug='private', public=False)
app = login(app)
resp = app.get('/manage/')
resp = resp.click('Site Settings')
resp.form['welcome_page'].select(text='Other:')
resp.form['welcome_page_path'] = '/welcome/'
resp.form['initial_login_page'].select(text='Other:')
resp.form['initial_login_page_path'] = '/initial-login/'
resp.form.submit()
@ -2708,3 +2712,13 @@ def test_site_settings(app, admin_user):
site_settings.refresh_from_db()
assert site_settings.welcome_page_path == ''
assert site_settings.initial_login_page_path == ''
assert list(resp.context['form'].fields['welcome_page'].queryset) == [public_page]
assert list(resp.context['form'].fields['initial_login_page'].queryset) == [public_page, private_page]
resp.form['welcome_page'].select(text='Public')
resp.form['initial_login_page'].select(text='Private')
resp.form.submit()
site_settings.refresh_from_db()
assert site_settings.welcome_page == public_page
assert site_settings.initial_login_page == private_page

View File

@ -696,6 +696,20 @@ def test_initial_login_page(app, admin_user):
resp = app.get('/', status=302)
assert resp.location == 'https://authentic.example.org/bar/'
profile.initial_login_view_timestamp = None
profile.save(update_fields=['initial_login_view_timestamp'])
site_settings.initial_login_page = page
site_settings.save()
# first visit
app = login(app)
resp = app.get('/', status=302)
assert urllib.parse.urlparse(resp.location).path == '/initial-login/'
# visit again
resp = app.get('/', status=200)
def test_welcome_page(app, admin_user):
Page.objects.all().delete()
@ -744,6 +758,15 @@ def test_welcome_page(app, admin_user):
resp = app.get('/', status=302)
assert resp.location == 'https://authentic.example.org/bar/'
site_settings.welcome_page = page
site_settings.save()
app.cookiejar.clear()
resp = app.get('/', status=302)
assert urllib.parse.urlparse(resp.location).path == '/welcome/'
resp = app.get('/', status=200)
def test_post_cell(app):
Page.objects.all().delete()