0001-misc-remove-obsolete-user-search-cell-32039.patch
MANIFEST.in | ||
---|---|---|
2 | 2 |
recursive-include combo/locale *.po *.mo |
3 | 3 | |
4 | 4 |
# static |
5 |
recursive-include combo/apps/usersearch/static *.css *.js *.ico *.gif *.png *.jpg |
|
6 | 5 |
recursive-include combo/apps/lingo/static *.css *.js *.ico *.gif *.png *.jpg |
7 | 6 |
recursive-include combo/apps/dataviz/static *.css *.js *.ico *.gif *.png *.jpg |
8 | 7 |
recursive-include combo/apps/dashboard/static *.js |
... | ... | |
17 | 16 |
recursive-include combo/apps/calendar/templates *.html |
18 | 17 |
recursive-include combo/apps/dashboard/templates *.html |
19 | 18 |
recursive-include combo/apps/search/templates *.html |
20 |
recursive-include combo/apps/usersearch/templates *.html |
|
21 | 19 |
recursive-include combo/apps/dataviz/templates *.html |
22 | 20 |
recursive-include combo/apps/family/templates *.html |
23 | 21 |
recursive-include combo/apps/fargo/templates *.html |
combo/apps/usersearch/__init__.py | ||
---|---|---|
1 |
# combo - content management system |
|
2 |
# Copyright (C) 2014-2016 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
import django.apps |
|
18 |
from django.utils.translation import ugettext_lazy as _ |
|
19 | ||
20 |
class AppConfig(django.apps.AppConfig): |
|
21 |
name = 'combo.apps.usersearch' |
|
22 |
verbose_name = _('Backoffice User Search') |
|
23 | ||
24 |
def get_before_urls(self): |
|
25 |
from . import urls |
|
26 |
return urls.urlpatterns |
|
27 | ||
28 |
default_app_config = 'combo.apps.usersearch.AppConfig' |
combo/apps/usersearch/migrations/0001_initial.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 |
from django.db import models, migrations |
|
5 | ||
6 | ||
7 |
class Migration(migrations.Migration): |
|
8 | ||
9 |
dependencies = [ |
|
10 |
('auth', '0001_initial'), |
|
11 |
('data', '0015_feedcell_title'), |
|
12 |
] |
|
13 | ||
14 |
operations = [ |
|
15 |
migrations.CreateModel( |
|
16 |
name='UserSearchCell', |
|
17 |
fields=[ |
|
18 |
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), |
|
19 |
('placeholder', models.CharField(max_length=20)), |
|
20 |
('order', models.PositiveIntegerField()), |
|
21 |
('slug', models.SlugField(verbose_name='Slug', blank=True)), |
|
22 |
('public', models.BooleanField(default=True, verbose_name='Public')), |
|
23 |
('restricted_to_unlogged', models.BooleanField(default=False, verbose_name='Restrict to unlogged users')), |
|
24 |
('groups', models.ManyToManyField(to='auth.Group', verbose_name='Groups', blank=True)), |
|
25 |
('page', models.ForeignKey(to='data.Page')), |
|
26 |
], |
|
27 |
options={ |
|
28 |
'verbose_name': 'User Search', |
|
29 |
}, |
|
30 |
bases=(models.Model,), |
|
31 |
), |
|
32 |
] |
combo/apps/usersearch/migrations/0002_usersearchcell_extra_css_class.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 |
from django.db import migrations, models |
|
5 | ||
6 | ||
7 |
class Migration(migrations.Migration): |
|
8 | ||
9 |
dependencies = [ |
|
10 |
('usersearch', '0001_initial'), |
|
11 |
] |
|
12 | ||
13 |
operations = [ |
|
14 |
migrations.AddField( |
|
15 |
model_name='usersearchcell', |
|
16 |
name='extra_css_class', |
|
17 |
field=models.CharField(max_length=100, verbose_name='Extra classes for CSS styling', blank=True), |
|
18 |
), |
|
19 |
] |
combo/apps/usersearch/migrations/0003_usersearchcell_last_update_timestamp.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 |
from django.db import migrations, models |
|
5 |
import datetime |
|
6 |
from django.utils.timezone import utc |
|
7 | ||
8 | ||
9 |
class Migration(migrations.Migration): |
|
10 | ||
11 |
dependencies = [ |
|
12 |
('usersearch', '0002_usersearchcell_extra_css_class'), |
|
13 |
] |
|
14 | ||
15 |
operations = [ |
|
16 |
migrations.AddField( |
|
17 |
model_name='usersearchcell', |
|
18 |
name='last_update_timestamp', |
|
19 |
field=models.DateTimeField(default=datetime.datetime.now(utc), auto_now=True), |
|
20 |
preserve_default=False, |
|
21 |
), |
|
22 |
] |
combo/apps/usersearch/models.py | ||
---|---|---|
1 |
# combo - content management system |
|
2 |
# Copyright (C) 2014-2016 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
from django.conf import settings |
|
18 |
from django.utils.translation import ugettext_lazy as _ |
|
19 |
from django.contrib.auth.models import User |
|
20 | ||
21 |
from combo.data.models import CellBase |
|
22 |
from combo.data.library import register_cell_class |
|
23 | ||
24 | ||
25 |
@register_cell_class |
|
26 |
class UserSearchCell(CellBase): |
|
27 |
template_name = 'combo/usersearch.html' |
|
28 | ||
29 |
class Media: |
|
30 |
js = ('js/usersearch.js',) |
|
31 | ||
32 |
class Meta: |
|
33 |
verbose_name = _('User Search') |
|
34 | ||
35 |
@classmethod |
|
36 |
def is_enabled(cls): |
|
37 |
return settings.USERSEARCH_CELL_ENABLED |
|
38 | ||
39 |
def is_visible(self, user=None): |
|
40 |
return super(UserSearchCell, self).is_visible(user=user) |
|
41 | ||
42 |
def modify_global_context(self, context, request): |
|
43 |
if 'selected_user_id' in request.GET: |
|
44 |
context['selected_user'] = User.objects.get(pk=request.GET['selected_user_id']) |
combo/apps/usersearch/static/js/usersearch.js | ||
---|---|---|
1 |
$(function() { |
|
2 |
$('.usersearch').delegate('input', 'keyup', function() { |
|
3 |
var q = $(this).val(); |
|
4 |
var search_result_ul = $(this).parent().find('ul.result'); |
|
5 |
search_result_ul.empty(); |
|
6 |
$.getJSON($(this).data('autocomplete-json'), |
|
7 |
{'q': q}, |
|
8 |
function (response) { |
|
9 |
search_result_ul.empty(); |
|
10 |
$(response).each(function(idx, elem) { |
|
11 |
var new_elem = '<li><a href="?selected_user_id=' + encodeURIComponent(elem.pk) + '">'; |
|
12 |
new_elem = new_elem + elem.fields.first_name + ' ' + elem.fields.last_name; |
|
13 |
new_elem = new_elem + ' <span class="email">' + elem.fields.email + '</span>'; |
|
14 |
new_elem = new_elem + '</a></li>' |
|
15 |
$(new_elem).appendTo(search_result_ul); |
|
16 |
}); |
|
17 |
} |
|
18 |
); |
|
19 |
return false; |
|
20 |
}); |
|
21 |
}); |
combo/apps/usersearch/templates/combo/usersearch.html | ||
---|---|---|
1 |
{% load i18n %} |
|
2 |
<div class="usersearch"> |
|
3 |
<input type="text" autocomplete="off" placeholder="{% trans 'Name, email, etc.' %}" data-autocomplete-json="{% url 'combo-ajax-usersearch' %}" name="q" /> |
|
4 |
<ul class="result"></ul> |
|
5 |
{% if selected_user %} |
|
6 |
<div class="selected-user"> |
|
7 |
{% trans "Selected user is:" %} {{ selected_user.first_name }} {{ selected_user.last_name }} |
|
8 |
<span class="email">{{ selected_user.email }}</span> |
|
9 |
</div> |
|
10 |
{% endif %} |
|
11 |
</div> |
combo/apps/usersearch/urls.py | ||
---|---|---|
1 |
# combo - content management system |
|
2 |
# Copyright (C) 2014-2016 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
from django.conf.urls import url |
|
18 | ||
19 |
from .views import ajax_usersearch |
|
20 | ||
21 |
urlpatterns = [ |
|
22 |
url(r'^ajax/usersearch/$', |
|
23 |
ajax_usersearch, name='combo-ajax-usersearch'), |
|
24 |
] |
combo/apps/usersearch/views.py | ||
---|---|---|
1 |
# combo - content management system |
|
2 |
# Copyright (C) 2014-2016 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
import json |
|
18 | ||
19 |
from django.http import HttpResponse |
|
20 |
from django.contrib.auth.models import User |
|
21 |
from django.db.models import Q |
|
22 |
from django.core import serializers |
|
23 |
from django.core.exceptions import PermissionDenied |
|
24 | ||
25 |
from .models import UserSearchCell |
|
26 | ||
27 | ||
28 |
def ajax_usersearch(request): |
|
29 |
# allow access if the user can see at least one UserSearch cell |
|
30 |
for cell in UserSearchCell.objects.all(): |
|
31 |
if cell.is_visible(request.user) and cell.page.is_visible(request.user): |
|
32 |
break |
|
33 |
else: |
|
34 |
raise PermissionDenied |
|
35 |
query = request.GET.get('q') |
|
36 |
if query: |
|
37 |
users = User.objects.all() |
|
38 |
# pseudo full-text search |
|
39 |
for elem in query.split(): |
|
40 |
users = users.filter(Q(username__icontains=elem) |
|
41 |
|Q(first_name__icontains=elem) |
|
42 |
|Q(last_name__icontains=elem) |
|
43 |
|Q(email__icontains=elem)) |
|
44 |
users = json.loads(serializers.serialize( |
|
45 |
'json', users[:10], fields=('username', 'first_name', 'last_name', 'email'))) |
|
46 |
else: |
|
47 |
users = [] |
|
48 |
response = HttpResponse(content_type='application/json') |
|
49 |
json.dump(users, response, indent=2) |
|
50 |
return response |
combo/settings.py | ||
---|---|---|
73 | 73 |
'combo.apps.fargo', |
74 | 74 |
'combo.apps.notifications', |
75 | 75 |
'combo.apps.search', |
76 |
'combo.apps.usersearch', |
|
77 | 76 |
'combo.apps.maps', |
78 | 77 |
'combo.apps.calendar', |
79 | 78 |
'combo.apps.pwa', |
80 |
- |