search: add/edit search engines with options (#52439)

This commit is contained in:
Lauréline Guérin 2021-04-06 15:56:04 +02:00
parent 54950b51b2
commit 9ddf332711
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
6 changed files with 246 additions and 20 deletions

View File

@ -48,14 +48,7 @@ class SelectWithDisabled(forms.Select):
return option_dict
class TextEngineSettingsForm(forms.ModelForm):
selected_page = forms.ModelChoiceField(
label=_('Page'),
required=False,
queryset=Page.objects.none(),
help_text=_("Select a page to limit the search on this page and sub pages contents."),
widget=SelectWithDisabled(),
)
class TextEngineSettingsUpdateForm(forms.ModelForm):
title = forms.CharField(label=_('Custom Title'), required=False)
with_description = forms.BooleanField(label=_("Display page's description in results"), required=False)
@ -64,7 +57,25 @@ class TextEngineSettingsForm(forms.ModelForm):
fields = []
def __init__(self, *args, **kwargs):
kwargs.pop('engine_slug')
self.engine_slug = kwargs.pop('engine_slug')
super().__init__(*args, **kwargs)
def get_title(self):
return _('Update "Page Contents" engine')
class TextEngineSettingsForm(TextEngineSettingsUpdateForm):
selected_page = forms.ModelChoiceField(
label=_('Page'),
required=False,
queryset=Page.objects.none(),
help_text=_("Select a page to limit the search on this page and sub pages contents."),
widget=SelectWithDisabled(),
)
field_order = ['selected_page', 'title', 'with_description']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
used_slugs = [
e['slug'].replace('_text_page_', '')
@ -93,12 +104,7 @@ class TextEngineSettingsForm(forms.ModelForm):
return '_text'
class CardsEngineSettingsForm(forms.ModelForm):
selected_view = forms.ChoiceField(
label=_('Custom view'),
required=False,
)
without_user = forms.BooleanField(label=_('Ignore the logged-in user'), required=False)
class CardsEngineSettingsUpdateForm(forms.ModelForm):
title = forms.CharField(label=_('Custom Title'), required=False)
class Meta:
@ -108,7 +114,25 @@ class CardsEngineSettingsForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
all_engines = engines.get_engines()
self.engine_slug = kwargs.pop('engine_slug')
self.engine = all_engines.get(self.engine_slug, {})
self.engine = all_engines.get(
':'.join(self.engine_slug.split(':')[:3]).replace('__without-user__', ''), {}
)
super().__init__(*args, **kwargs)
def get_title(self):
return _('Update "%s" engine') % self.engine.get('label')
class CardsEngineSettingsForm(CardsEngineSettingsUpdateForm):
selected_view = forms.ChoiceField(
label=_('Custom view'),
required=False,
)
without_user = forms.BooleanField(label=_('Ignore the logged-in user'), required=False)
field_order = ['selected_view', 'without_user', 'title']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['selected_view'].choices = [(None, _('- All cards -'))] + [
(v['id'], v['text']) for v in self.engine.get('custom_views', [])
@ -124,3 +148,26 @@ class CardsEngineSettingsForm(forms.ModelForm):
if self.cleaned_data['selected_view']:
slug = '%s:%s' % (slug, self.cleaned_data['selected_view'])
return slug
class UsersEngineSettingsUpdateForm(forms.ModelForm):
title = forms.CharField(label=_('Custom Title'), required=False)
class Meta:
model = SearchCell
fields = []
def __init__(self, *args, **kwargs):
self.engine_slug = kwargs.pop('engine_slug')
super().__init__(*args, **kwargs)
def get_title(self):
return _('Update "Users" engine')
def get_slug(self):
return self.engine_slug
class UsersEngineSettingsForm(UsersEngineSettingsUpdateForm):
def get_title(self):
return _('Add a "Users" engine')

View File

@ -19,7 +19,14 @@ from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from combo.apps.search.forms import CardsEngineSettingsForm, TextEngineSettingsForm
from combo.apps.search.forms import (
CardsEngineSettingsForm,
CardsEngineSettingsUpdateForm,
TextEngineSettingsForm,
TextEngineSettingsUpdateForm,
UsersEngineSettingsForm,
UsersEngineSettingsUpdateForm,
)
from combo.apps.search.models import SearchCell
from combo.data.models import PageSnapshot
@ -41,11 +48,13 @@ def page_search_cell_add_engine(request, page_pk, cell_reference, engine_slug):
'%s#cell-%s' % (reverse('combo-manager-page-view', kwargs={'pk': page_pk}), cell_reference)
)
if engine_slug != '_text' and not engine_slug.startswith('cards:'):
if engine_slug not in ['_text', 'users'] and not engine_slug.startswith('cards:'):
# add engine without intermediary form and popup
return add_slug(engine_slug)
form_class = TextEngineSettingsForm
if engine_slug == 'users':
form_class = UsersEngineSettingsForm
if engine_slug.startswith('cards:'):
form_class = CardsEngineSettingsForm
@ -65,7 +74,51 @@ def page_search_cell_add_engine(request, page_pk, cell_reference, engine_slug):
'form': form,
'cell': cell,
}
return render(request, 'combo/manager/add-engine-form.html', context)
return render(request, 'combo/manager/engine-form.html', context)
def page_search_cell_update_engine(request, page_pk, cell_reference, engine_slug):
cell = get_object_or_404(SearchCell, pk=cell_reference.split('-')[1], page=page_pk)
form_class = TextEngineSettingsUpdateForm
if engine_slug == 'users':
form_class = UsersEngineSettingsUpdateForm
if engine_slug.startswith('cards:'):
form_class = CardsEngineSettingsUpdateForm
if request.method == 'POST':
form = form_class(instance=cell, data=request.POST, engine_slug=engine_slug)
if form.is_valid():
kwargs = {
'title': form.cleaned_data['title'],
}
for key in ['without_user', 'with_description']:
if form.cleaned_data.get(key):
kwargs[key] = True
if not cell._search_services.get('options'):
cell._search_services['options'] = {}
cell._search_services['options'][engine_slug] = kwargs
cell.save()
PageSnapshot.take(cell.page, request=request, comment=_('changed cell "%s"') % cell)
return HttpResponseRedirect(
'%s#cell-%s' % (reverse('combo-manager-page-view', kwargs={'pk': page_pk}), cell_reference)
)
else:
initial = {
'title': cell._search_services.get('options', {}).get(engine_slug, {}).get('title'),
'without_user': cell._search_services.get('options', {}).get(engine_slug, {}).get('without_user'),
'with_description': cell._search_services.get('options', {})
.get(engine_slug, {})
.get('with_description'),
}
form = form_class(instance=cell, engine_slug=engine_slug, initial=initial)
context = {
'form': form,
'cell': cell,
}
return render(request, 'combo/manager/engine-form.html', context)
def page_search_cell_delete_engine(request, page_pk, cell_reference, engine_slug):

View File

@ -22,6 +22,9 @@
{% for engine in engines %}
<li data-link-item-id="{{ engine.0 }}"><span class="handle"></span>
<span>{{ engine.1 }}{% if engine.2.title %} ({% trans "Custom title:"%}{{ engine.2.title }}){% endif %}</span>
{% if engine.0 == '_text' or engine.0 == 'users' or engine.0|startswith:'cards:' %}
<a rel="popup" title="{% trans "Edit" %}" class="link-action-icon edit" href="{% url 'combo-manager-page-search-cell-update-engine' page_pk=page.pk cell_reference=cell.get_reference engine_slug=engine.0 %}">{% trans "Edit" %}</a>
{% endif %}
<a title="{% trans "Delete" %}" class="link-action-icon delete" href="{% url 'combo-manager-page-search-cell-delete-engine' page_pk=page.pk cell_reference=cell.get_reference engine_slug=engine.0 %}">{% trans "Delete" %}</a>
</li>
{% endfor %}
@ -51,7 +54,7 @@ $(function () {
<div class="buttons">
{% trans "Add an engine:" %}
{% for key, engine in cell.available_engines.items %}
<a {% if key == '_text' or key|startswith:'cards:' %}rel="popup"{% endif %} href="{% url 'combo-manager-page-search-cell-add-engine' page_pk=page.pk cell_reference=cell.get_reference engine_slug=key %}">{{ engine.label }}</a> {% if not forloop.last %}|{% endif %}
<a {% if key == '_text' or key == 'users' or key|startswith:'cards:' %}rel="popup"{% endif %} href="{% url 'combo-manager-page-search-cell-add-engine' page_pk=page.pk cell_reference=cell.get_reference engine_slug=key %}">{{ engine.label }}</a> {% if not forloop.last %}|{% endif %}
{% endfor %}
</div>
{% endif %}

View File

@ -27,6 +27,11 @@ search_manager_urls = [
manager_views.page_search_cell_add_engine,
name='combo-manager-page-search-cell-add-engine',
),
url(
r'^pages/(?P<page_pk>\d+)/cell/(?P<cell_reference>[\w_]+-\d+)/engine/(?P<engine_slug>[\w_:-]+)/edit/$',
manager_views.page_search_cell_update_engine,
name='combo-manager-page-search-cell-update-engine',
),
url(
r'^pages/(?P<page_pk>\d+)/cell/(?P<cell_reference>[\w_]+-\d+)/engine/(?P<engine_slug>[\w_:-]+)/delete/$',
manager_views.page_search_cell_delete_engine,

View File

@ -565,6 +565,23 @@ def test_manager_search_cell(settings, app, admin_user):
% (page.pk, cell.pk)
in resp.text
)
assert (
'/manage/search/pages/%s/cell/search_searchcell-%s/engine/_text/edit/' % (page.pk, cell.pk)
not in resp.text
)
assert (
'/manage/search/pages/%s/cell/search_searchcell-%s/engine/search1/edit/' % (page.pk, cell.pk)
not in resp.text
)
assert (
'/manage/search/pages/%s/cell/search_searchcell-%s/engine/search_tmpl/edit/' % (page.pk, cell.pk)
not in resp.text
)
assert (
'/manage/search/pages/%s/cell/search_searchcell-%s/engine/search_alternate_key/edit/'
% (page.pk, cell.pk)
not in resp.text
)
assert (
'/manage/search/pages/%s/cell/search_searchcell-%s/engine/_text/delete/' % (page.pk, cell.pk)
not in resp.text
@ -613,6 +630,23 @@ def test_manager_search_cell(settings, app, admin_user):
% (page.pk, cell.pk)
in resp.text
)
assert (
'/manage/search/pages/%s/cell/search_searchcell-%s/engine/_text/edit/' % (page.pk, cell.pk)
in resp.text
)
assert (
'/manage/search/pages/%s/cell/search_searchcell-%s/engine/search1/edit/' % (page.pk, cell.pk)
not in resp.text
)
assert (
'/manage/search/pages/%s/cell/search_searchcell-%s/engine/search_tmpl/edit/' % (page.pk, cell.pk)
not in resp.text
)
assert (
'/manage/search/pages/%s/cell/search_searchcell-%s/engine/search_alternate_key/edit/'
% (page.pk, cell.pk)
not in resp.text
)
assert (
'/manage/search/pages/%s/cell/search_searchcell-%s/engine/_text/delete/' % (page.pk, cell.pk)
in resp.text
@ -631,7 +665,21 @@ def test_manager_search_cell(settings, app, admin_user):
not in resp.text
)
# edit engines
resp = resp.click(href='.*/search_searchcell-%s/engine/_text/edit/' % cell.pk)
resp.form['title'] = 'Custom Title'
resp.form['with_description'] = True
resp = resp.form.submit('submit')
assert resp.status_int == 302
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference()))
cell.refresh_from_db()
assert cell._search_services['options']['_text'] == {
'title': 'Custom Title',
'with_description': True,
}
# delete engines
resp = app.get('/manage/pages/%s/' % page.pk)
resp = resp.click(href='.*/search_searchcell-%s/engine/_text/delete/' % cell.pk)
assert resp.status_int == 302
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference()))
@ -866,6 +914,11 @@ def test_wcs_add_search_engines(mock_wcs, settings, app, admin_user):
% (page.pk, cell.pk)
in resp.text
)
assert (
'/manage/search/pages/%s/cell/search_searchcell-%s/engine/cards:c21f969b:card-bar/edit/'
% (page.pk, cell.pk)
not in resp.text
)
assert (
'/manage/search/pages/%s/cell/search_searchcell-%s/engine/cards:c21f969b:card-bar/delete/'
% (page.pk, cell.pk)
@ -897,6 +950,11 @@ def test_wcs_add_search_engines(mock_wcs, settings, app, admin_user):
% (page.pk, cell.pk)
in resp.text
)
assert (
'/manage/search/pages/%s/cell/search_searchcell-%s/engine/cards:c21f969b:card-bar/edit/'
% (page.pk, cell.pk)
in resp.text
)
assert (
'/manage/search/pages/%s/cell/search_searchcell-%s/engine/cards:c21f969b:card-bar/delete/'
% (page.pk, cell.pk)
@ -915,6 +973,16 @@ def test_wcs_add_search_engines(mock_wcs, settings, app, admin_user):
cell.refresh_from_db()
assert cell._search_services['data'] == ['cards:c21f969b:card-bar', 'cards:c21f969b:card-bar:foo']
# edit engine
resp = resp.follow()
resp = resp.click(href='.*/search_searchcell-%s/engine/cards:c21f969b:card-bar/edit/' % cell.pk)
resp.form['title'] = 'Custom Title Foo Bar'
resp = resp.form.submit('submit')
assert resp.status_int == 302
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference()))
cell.refresh_from_db()
assert cell._search_services['options']['cards:c21f969b:card-bar'] == {'title': 'Custom Title Foo Bar'}
# remove engine
resp = resp.follow()
resp = resp.click(href='.*/search_searchcell-%s/engine/cards:c21f969b:card-bar:foo/delete/' % cell.pk)
@ -1053,6 +1121,56 @@ def test_profile_search_engines(settings, app):
assert 'users' in search_engines.keys()
def test_profile_add_search_engines(settings, app, admin_user):
settings.KNOWN_SERVICES = {'authentic': {'default': {'title': 'authentic', 'url': 'https://authentic/'}}}
Page.objects.create(slug='users', title='Users', sub_slug='(?P<name_id>[a-z0-9]+)')
page = Page.objects.create(title='One', slug='one', template_name='standard')
cell = SearchCell.objects.create(page=page, placeholder='content', order=0)
app = login(app)
resp = app.get('/manage/pages/%s/' % page.pk)
assert (
'/manage/search/pages/%s/cell/search_searchcell-%s/engine/users/add/' % (page.pk, cell.pk)
in resp.text
)
assert (
'/manage/search/pages/%s/cell/search_searchcell-%s/engine/users/edit/' % (page.pk, cell.pk)
not in resp.text
)
assert (
'/manage/search/pages/%s/cell/search_searchcell-%s/engine/users/delete/' % (page.pk, cell.pk)
not in resp.text
)
resp = resp.click(href='.*/search_searchcell-%s/engine/users/add/' % cell.pk)
resp.form['title'] = 'Custom Title'
resp = resp.form.submit('submit')
assert resp.status_int == 302
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference()))
cell.refresh_from_db()
assert cell._search_services['data'] == ['users']
assert cell._search_services['options']['users'] == {'title': 'Custom Title'}
# edit engine
resp = app.get('/manage/pages/%s/' % page.pk)
resp = resp.click(href='.*/search_searchcell-%s/engine/users/edit/' % cell.pk)
resp.form['title'] = 'Custom Title Foo Bar'
resp = resp.form.submit('submit')
assert resp.status_int == 302
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference()))
cell.refresh_from_db()
assert cell._search_services['options']['users'] == {'title': 'Custom Title Foo Bar'}
# remove engine
resp = resp.follow()
resp = resp.click(href='.*/search_searchcell-%s/engine/users/delete/' % cell.pk)
assert resp.status_int == 302
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference()))
cell.refresh_from_db()
assert cell._search_services['data'] == []
def test_private_search(app):
page = Page(title='example page', slug='example-page')
page.save()