Commit 2d13baf3ff9a0372e07cc2a8f7b28cb2cbee6454
1 parent
006fe4a1
Exists in
master
and in
39 other branches
Showing
3 changed files
with
146 additions
and
68 deletions
Show diff stats
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"> |