Commit 2d13baf3ff9a0372e07cc2a8f7b28cb2cbee6454

Authored by Luan
1 parent 006fe4a1

Adding specific filters to search #23 #24

src/search/forms.py
@@ -8,13 +8,35 @@ from django.utils.translation import ugettext_lazy as _ @@ -8,13 +8,35 @@ from django.utils.translation import ugettext_lazy as _
8 from haystack.forms import SearchForm 8 from haystack.forms import SearchForm
9 9
10 from accounts.models import User 10 from accounts.models import User
11 -from super_archives.models import Message 11 +from super_archives.models import Message, MailingList
12 12
13 13
14 class ColabSearchForm(SearchForm): 14 class ColabSearchForm(SearchForm):
15 q = forms.CharField(label=_('Search'), required=False) 15 q = forms.CharField(label=_('Search'), required=False)
16 order = forms.CharField(widget=forms.HiddenInput(), required=False) 16 order = forms.CharField(widget=forms.HiddenInput(), required=False)
17 type = forms.CharField(required=False, label=_(u'Type')) 17 type = forms.CharField(required=False, label=_(u'Type'))
  18 + author = forms.CharField(required=False, label=_(u'Author'))
  19 + # ticket status
  20 + tag = forms.CharField(required=False, label=_(u'Status'))
  21 + # mailinglist tag
  22 + list = forms.MultipleChoiceField(
  23 + required=False,
  24 + label=_(u'Mailinglist'),
  25 + choices=[(v, v) for v in MailingList.objects.values('name')
  26 + for (v, v) in v.items()]
  27 + )
  28 + milestone = forms.CharField(required=False, label=_(u'Milestone'))
  29 + priority = forms.CharField(required=False, label=_(u'Priority'))
  30 + component = forms.CharField(required=False, label=_(u'Component'))
  31 + severity = forms.CharField(required=False, label=_(u'Severity'))
  32 + reporter = forms.CharField(required=False, label=_(u'Reporter'))
  33 + keywords = forms.CharField(required=False, label=_(u'Keywords'))
  34 + collaborators = forms.CharField(required=False, label=_(u'Collaborators'))
  35 + repository_name = forms.CharField(required=False, label=_(u'Repository'))
  36 + username = forms.CharField(required=False, label=_(u'Username'))
  37 + name = forms.CharField(required=False, label=_(u'Name'))
  38 + institution = forms.CharField(required=False, label=_(u'Institution'))
  39 + role = forms.CharField(required=False, label=_(u'Role'))
18 40
19 def search(self): 41 def search(self):
20 if not self.is_valid(): 42 if not self.is_valid():
@@ -33,25 +55,44 @@ class ColabSearchForm(SearchForm): @@ -33,25 +55,44 @@ class ColabSearchForm(SearchForm):
33 types = self.cleaned_data['type'] 55 types = self.cleaned_data['type']
34 sqs = sqs.filter(type__in=types.split()) 56 sqs = sqs.filter(type__in=types.split())
35 57
36 -  
37 if self.cleaned_data['order']: 58 if self.cleaned_data['order']:
38 for option, dict_order in settings.ORDERING_DATA.items(): 59 for option, dict_order in settings.ORDERING_DATA.items():
39 if self.cleaned_data['order'] == option: 60 if self.cleaned_data['order'] == option:
40 if dict_order['fields']: 61 if dict_order['fields']:
41 sqs = sqs.order_by(*dict_order['fields']) 62 sqs = sqs.order_by(*dict_order['fields'])
42 - # if self.cleaned_data['type'] == 'user':  
43 - # sqs = self.searchqueryset.models(User)  
44 - # elif self.cleaned_data['type'] in ['message', 'thread']:  
45 - # sqs = self.searchqueryset.models(Message)  
46 - # elif self.cleaned_data['type'] == 'wiki':  
47 - # sqs = self.searchqueryset.models(Wiki)  
48 - # elif self.cleaned_data['type'] == 'changeset':  
49 - # sqs = self.searchqueryset.models(Changeset)  
50 - # elif self.cleaned_data['type'] == 'ticket':  
51 - # sqs = self.searchqueryset.models(Ticket)  
52 - # else:  
53 - # sqs = self.searchqueryset.all()  
54 63
  64 + if self.cleaned_data['author']:
  65 + sqs = sqs.filter(author=self.cleaned_data['author'])
  66 +
  67 + if self.cleaned_data['milestone']:
  68 + sqs = sqs.filter(milestone=self.cleaned_data['milestone'])
  69 + if self.cleaned_data['priority']:
  70 + sqs = sqs.filter(priority=self.cleaned_data['priority'])
  71 + if self.cleaned_data['severity']:
  72 + sqs = sqs.filter(severity=self.cleaned_data['severity'])
  73 + if self.cleaned_data['reporter']:
  74 + sqs = sqs.filter(reporter=self.cleaned_data['reporter'])
  75 + if self.cleaned_data['keywords']:
  76 + sqs = sqs.filter(keywords=self.cleaned_data['keywords'])
  77 + if self.cleaned_data['collaborators']:
  78 + sqs = sqs.filter(collaborators=self.cleaned_data['collaborators'])
  79 + if self.cleaned_data['repository_name']:
  80 + sqs = sqs.filter(
  81 + repository_name=self.cleaned_data['repository_name']
  82 + )
  83 + if self.cleaned_data['username']:
  84 + sqs = sqs.filter(username=self.cleaned_data['username'])
  85 + if self.cleaned_data['name']:
  86 + sqs = sqs.filter(name=self.cleaned_data['name'])
  87 + if self.cleaned_data['institution']:
  88 + sqs = sqs.filter(institution=self.cleaned_data['institution'])
  89 + if self.cleaned_data['role']:
  90 + sqs = sqs.filter(role=self.cleaned_data['role'])
  91 + if self.cleaned_data['tag']:
  92 + sqs = sqs.filter(tag=self.cleaned_data['tag'])
  93 +
  94 + if self.cleaned_data['list']:
  95 + sqs = sqs.filter(tag__in=self.cleaned_data['list'])
55 96
56 if self.load_all: 97 if self.load_all:
57 sqs = sqs.load_all() 98 sqs = sqs.load_all()
src/search/views.py
1 # -*- coding:utf-8 -*- 1 # -*- coding:utf-8 -*-
2 2
3 from django.conf import settings 3 from django.conf import settings
  4 +from django.utils.translation import ugettext as _
  5 +
4 from haystack.views import SearchView 6 from haystack.views import SearchView
5 7
6 8
7 class ColabSearchView(SearchView): 9 class ColabSearchView(SearchView):
8 def extra_context(self, *args, **kwargs): 10 def extra_context(self, *args, **kwargs):
9 - # Retornar todos os campos de cada tipo a serem filtrados  
10 - # retornar os nomes dos campos  
11 - # retornar os ícones dos tipos  
12 -  
13 - # a critical point on the system  
14 types = { 11 types = {
15 'wiki': { 12 'wiki': {
16 'icon': 'file', 13 'icon': 'file',
17 - 'fields': [  
18 - 'title', 'description', 'author', 'collaborators',  
19 - 'created', 'modified',  
20 - ], 14 + 'name': _(u'Wiki'),
  15 + 'fields': {'author': _(u'Author')},
21 }, 16 },
22 - 'discussion': { 17 + 'thread': {
23 'icon': 'thread', 18 'icon': 'thread',
24 - 'fields': [  
25 - 'title', 'description', 'created', 'modified', 'author',  
26 - 'tag',  
27 - ], 19 + 'name': _(u'Discussion'),
  20 + 'fields': {'author': _(u'Author'), 'list': _(u'Mailinglist')},
28 }, 21 },
29 'ticket': { 22 'ticket': {
30 'icon': 'ticket', 23 'icon': 'ticket',
31 - 'fields': [  
32 - 'title', 'description', 'milestone', 'priority',  
33 - 'component', 'version', 'severity', 'reporter', 'author',  
34 - 'status', 'keywords', 'collaborators', 'created',  
35 - 'modified',  
36 - ], 24 + 'name': _(u'Ticket'),
  25 + 'fields': {
  26 + 'milestone': _(u'Milestone'), 'priority': _(u'Priority'),
  27 + 'component': _(u'Component'), 'severity': _(u'Severity'),
  28 + 'reporter': _(u'Reporter'), 'author': _(u'Author'),
  29 + 'tag': _(u'Status'), 'keywords': _(u'Keywords'),
  30 + 'collaborators': _(u'Collaborators'),
  31 + },
37 }, 32 },
38 'changeset': { 33 'changeset': {
39 'icon': 'changeset', 34 'icon': 'changeset',
40 - 'fields': [  
41 - 'title', 'author', 'description', 'repository_name',  
42 - 'created', 'modified',  
43 - ], 35 + 'name': _(u'Changeset'),
  36 + 'fields': {'author': _(u'Author'), 'repository_name': _(u'Repository')},
44 }, 37 },
45 'user': { 38 'user': {
46 'icon': 'user', 39 'icon': 'user',
47 - 'fields': [  
48 - 'title', 'description', 'username', 'name',  
49 - 'email', 'institution', 'role', 'google_talk', 'webpage',  
50 - ], 40 + 'name': _(u'User'),
  41 + 'fields': {'username': _(u'Username'), 'name': _(u'Name'), 'institution': _(u'Institution'), 'role': _(u'Role')},
51 }, 42 },
52 } 43 }
53 - types = self.form.cleaned_data['type'] 44 +
  45 + try:
  46 + type_chosen = self.form.cleaned_data.get('type')
  47 + except AttributeError:
  48 + type_chosen = ''
  49 +
54 return dict( 50 return dict(
55 - types=types.split(),  
56 - types_str=types, 51 + filters=types.get(type_chosen),
  52 + type_chosen=type_chosen,
57 order_data=settings.ORDERING_DATA 53 order_data=settings.ORDERING_DATA
58 ) 54 )
src/templates/search/search.html
@@ -17,6 +17,45 @@ @@ -17,6 +17,45 @@
17 <div id="filters" class="hidden-xs hidden-sm col-md-2 col-lg-2"> 17 <div id="filters" class="hidden-xs hidden-sm col-md-2 col-lg-2">
18 <h3>{% trans "Filters" %}</h3> 18 <h3>{% trans "Filters" %}</h3>
19 19
  20 + {% if filters %}
  21 + <ul class="unstyled-list">
  22 + <li class="selected" title="{% trans "Remove filter" %}">
  23 + <span class="glyphicon glyphicon-remove"></span>
  24 + <a href="{% pop_from_get type=type_chosen %}">
  25 + <span class="glyphicon glyphicon-{{ filters.icon }}"></span>
  26 + {{ filters.name }}
  27 + </a>
  28 + </li>
  29 + </ul>
  30 + <hr />
  31 + <form role="form">
  32 + <input type="hidden" name="q" value="{{ request.GET.q }}" />
  33 + <input type="hidden" name="type" value="{{ type_chosen }}" />
  34 +
  35 + {% for field_lookup, field_display in filters.fields.items %}
  36 + <div class="form-group">
  37 + <label for="{{ field_lookup }}">{{ field_display }}</label>
  38 + {% ifequal field_lookup "list" %}
  39 + <select name="{{ field_lookup }}" class="form-control" multiple>
  40 + {% for value, option in form.fields.list.choices %}
  41 + <option value="{{ value }}">{{ option }}</option>
  42 + {% endfor %}
  43 + </select>
  44 + {% else %}
  45 + <div class="input-group">
  46 + <span class="input-group-addon">
  47 + <input type="checkbox" name="{{ field_lookup }}_check">
  48 + </span>
  49 + <input type="text" class="form-control" placeholder="{{ field_display }}" name="{{ field_lookup }}" value="">
  50 + </div>
  51 + {% endifequal %}
  52 + </div>
  53 + {% endfor %}
  54 + <input type="submit" class="btn btn-default pull-right" value="{% trans 'Filter' %}" />
  55 + </form>
  56 + <br /><hr />
  57 + {% endif %}
  58 +
20 <h4>{% trans "Sort by" %}</h4> 59 <h4>{% trans "Sort by" %}</h4>
21 <ul class="unstyled-list"> 60 <ul class="unstyled-list">
22 {% for option, dict_order in order_data.items %} 61 {% for option, dict_order in order_data.items %}
@@ -33,30 +72,32 @@ @@ -33,30 +72,32 @@
33 {% endfor %} 72 {% endfor %}
34 </ul> 73 </ul>
35 74
36 - <h4>{% trans "Types" %}</h4> 75 + {% if not request.GET.type %}
  76 + <h4>{% trans "Types" %}</h4>
37 77
38 - <ul class="unstyled-list">  
39 - <li>  
40 - <span class="glyphicon glyphicon-file"></span>  
41 - <a href="{% append_to_get type='wiki' %}">{% trans "Wiki" %}</a>  
42 - </li>  
43 - <li>  
44 - <span class="glyphicon glyphicon-envelope"></span>  
45 - <a href="{% append_to_get type='thread' %}">{% trans "Discussion" %}</a>  
46 - </li>  
47 - <li>  
48 - <span class="glyphicon glyphicon-tag"></span>  
49 - <a href="{% append_to_get type='ticket' %}">{% trans "Ticket" %}</a>  
50 - </li>  
51 - <li>  
52 - <span class="glyphicon glyphicon-align-right"></span>  
53 - <a href="{% append_to_get type='changeset' %}">{% trans "Changeset" %}</a>  
54 - </li>  
55 - <li>  
56 - <span class="glyphicon glyphicon-user"></span>  
57 - <a href="{% append_to_get type='user' %}">{% trans "User" %}</a>  
58 - </li>  
59 - </ul> 78 + <ul class="unstyled-list">
  79 + <li>
  80 + <span class="glyphicon glyphicon-file"></span>
  81 + <a href="{% append_to_get type='wiki' %}">{% trans "Wiki" %}</a>
  82 + </li>
  83 + <li>
  84 + <span class="glyphicon glyphicon-envelope"></span>
  85 + <a href="{% append_to_get type='thread' %}">{% trans "Discussion" %}</a>
  86 + </li>
  87 + <li>
  88 + <span class="glyphicon glyphicon-tag"></span>
  89 + <a href="{% append_to_get type='ticket' %}">{% trans "Ticket" %}</a>
  90 + </li>
  91 + <li>
  92 + <span class="glyphicon glyphicon-align-right"></span>
  93 + <a href="{% append_to_get type='changeset' %}">{% trans "Changeset" %}</a>
  94 + </li>
  95 + <li>
  96 + <span class="glyphicon glyphicon-user"></span>
  97 + <a href="{% append_to_get type='user' %}">{% trans "User" %}</a>
  98 + </li>
  99 + </ul>
  100 + {% endif %}
60 </div> 101 </div>
61 102
62 <div class="col-lg-10"> 103 <div class="col-lg-10">