0001-public-add-page-selector-in-site-settings-58475.patch
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 |
- |