From 88aec52141b33ed7ef1d3aa06871c57f9f94b539 Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Thu, 19 Jan 2017 01:06:09 -0200 Subject: [PATCH 1/6] PEP8 + typo --- kfet/autocomplete.py | 51 ++++--- .../kfet/account_create_autocomplete.html | 2 +- kfet/urls.py | 132 ++++++++++-------- 3 files changed, 95 insertions(+), 90 deletions(-) diff --git a/kfet/autocomplete.py b/kfet/autocomplete.py index 2a24a51e..1ebbbc75 100644 --- a/kfet/autocomplete.py +++ b/kfet/autocomplete.py @@ -1,9 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import (absolute_import, division, - print_function, unicode_literals) -from builtins import * - from django.shortcuts import render from django.http import Http404 from django.db.models import Q @@ -11,6 +7,7 @@ from gestioncof.models import User, Clipper from kfet.decorators import teamkfet_required from kfet.models import Account + @teamkfet_required def account_create(request): if "q" not in request.GET: @@ -25,48 +22,48 @@ def account_create(request): queries = {} search_words = q.split() - queries['kfet'] = Account.objects - queries['users_cof'] = User.objects.filter(Q(profile__is_cof = True)) - queries['users_notcof'] = User.objects.filter(Q(profile__is_cof = False)) - queries['clippers'] = Clipper.objects + queries['kfet'] = Account.objects + queries['users_cof'] = User.objects.filter(Q(profile__is_cof=True)) + queries['users_notcof'] = User.objects.filter(Q(profile__is_cof=False)) + queries['clippers'] = Clipper.objects for word in search_words: queries['kfet'] = queries['kfet'].filter( - Q(cofprofile__user__username__icontains = word) - | Q(cofprofile__user__first_name__icontains = word) - | Q(cofprofile__user__last_name__icontains = word) + Q(cofprofile__user__username__icontains=word) | + Q(cofprofile__user__first_name__icontains=word) | + Q(cofprofile__user__last_name__icontains=word) ) queries['users_cof'] = queries['users_cof'].filter( - Q(username__icontains = word) - | Q(first_name__icontains = word) - | Q(last_name__icontains = word) + Q(username__icontains=word) | + Q(first_name__icontains=word) | + Q(last_name__icontains=word) ) queries['users_notcof'] = queries['users_notcof'].filter( - Q(username__icontains = word) - | Q(first_name__icontains = word) - | Q(last_name__icontains = word) + Q(username__icontains=word) | + Q(first_name__icontains=word) | + Q(last_name__icontains=word) ) - queries['clippers'] = queries['clippers'].filter( - Q(username__icontains = word) - | Q(fullname__icontains = word) + queries['clippers'] = queries['clippers'].filter( + Q(username__icontains=word) | + Q(fullname__icontains=word) ) queries['kfet'] = queries['kfet'].distinct() - usernames = list( \ + usernames = list( queries['kfet'].values_list('cofprofile__user__username', flat=True)) - queries['kfet'] = [ (account, account.cofprofile.user) \ - for account in queries['kfet'] ] + queries['kfet'] = [(account, account.cofprofile.user) + for account in queries['kfet']] - queries['users_cof'] = \ + queries['users_cof'] = \ queries['users_cof'].exclude(username__in=usernames).distinct() - queries['users_notcof'] = \ + queries['users_notcof'] = \ queries['users_notcof'].exclude(username__in=usernames).distinct() - usernames += list( \ + usernames += list( queries['users_cof'].values_list('username', flat=True)) - usernames += list( \ + usernames += list( queries['users_notcof'].values_list('username', flat=True)) queries['clippers'] = \ diff --git a/kfet/templates/kfet/account_create_autocomplete.html b/kfet/templates/kfet/account_create_autocomplete.html index 1185c3a8..1a869c86 100644 --- a/kfet/templates/kfet/account_create_autocomplete.html +++ b/kfet/templates/kfet/account_create_autocomplete.html @@ -7,7 +7,7 @@ {% if kfet %} -
  • Comptes existant
  • +
  • Comptes existants
  • {% for account, user in kfet %}
  • {{ account }} [{{ user|highlight_user:q }}]
  • {% endfor %} diff --git a/kfet/urls.py b/kfet/urls.py index 9b9ebf21..271ed917 100644 --- a/kfet/urls.py +++ b/kfet/urls.py @@ -1,9 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import (absolute_import, division, - print_function, unicode_literals) -from builtins import * - from django.conf.urls import url from django.contrib.auth.decorators import permission_required from kfet import views @@ -12,11 +8,11 @@ from kfet.decorators import teamkfet_required urlpatterns = [ url(r'^$', views.home, - name = 'kfet.home'), + name='kfet.home'), url(r'^login/genericteam$', views.login_genericteam, - name = 'kfet.login.genericteam'), + name='kfet.login.genericteam'), url(r'^history$', views.history, - name = 'kfet.history'), + name='kfet.history'), # ----- # Account urls @@ -24,45 +20,53 @@ urlpatterns = [ # Account - General url(r'^accounts/$', views.account, - name = 'kfet.account'), + name='kfet.account'), url(r'^accounts/is_validandfree$', views.account_is_validandfree_ajax, - name = 'kfet.account.is_validandfree.ajax'), + name='kfet.account.is_validandfree.ajax'), # Account - Create url(r'^accounts/new$', views.account_create, - name = 'kfet.account.create'), + name='kfet.account.create'), url(r'^accounts/new_special$', views.account_create_special, - name = 'kfet.account.create_special'), + name='kfet.account.create_special'), url(r'^accounts/new/user/(?P.+)$', views.account_create_ajax, - name = 'kfet.account.create.fromuser'), - url(r'^accounts/new/clipper/(?P.+)$', views.account_create_ajax, - name = 'kfet.account.create.fromclipper'), + name='kfet.account.create.fromuser'), + url(r'^accounts/new/clipper/(?P.+)$', + views.account_create_ajax, + name='kfet.account.create.fromclipper'), url(r'^accounts/new/empty$', views.account_create_ajax, - name = 'kfet.account.create.empty'), + name='kfet.account.create.empty'), url(r'^autocomplete/account_new$', autocomplete.account_create, - name = 'kfet.account.create.autocomplete'), + name='kfet.account.create.autocomplete'), + + # Account - Search + url(r'^autocomplete/account_search$', autocomplete.account_search, + name='kfet.account.search.autocomplete'), # Account - Read url(r'^accounts/(?P.{3})$', views.account_read, - name = 'kfet.account.read'), + name='kfet.account.read'), # Account - Update url(r'^accounts/(?P.{3})/edit$', views.account_update, - name = 'kfet.account.update'), + name='kfet.account.update'), # Account - Groups url(r'^accounts/groups$', views.account_group, - name = 'kfet.account.group'), + name='kfet.account.group'), url(r'^accounts/groups/new$', - permission_required('kfet.manage_perms')(views.AccountGroupCreate.as_view()), - name = 'kfet.account.group.create'), + permission_required('kfet.manage_perms') + (views.AccountGroupCreate.as_view()), + name='kfet.account.group.create'), url(r'^accounts/groups/(?P\d+)/edit$', - permission_required('kfet.manage_perms')(views.AccountGroupUpdate.as_view()), - name = 'kfet.account.group.update'), + permission_required('kfet.manage_perms') + (views.AccountGroupUpdate.as_view()), + name='kfet.account.group.update'), url(r'^accounts/negatives$', - permission_required('kfet.view_negs')(views.AccountNegativeList.as_view()), - name = 'kfet.account.negative'), + permission_required('kfet.view_negs') + (views.AccountNegativeList.as_view()), + name='kfet.account.negative'), # ----- # Checkout urls @@ -71,34 +75,36 @@ urlpatterns = [ # Checkout - General url('^checkouts/$', teamkfet_required(views.CheckoutList.as_view()), - name = 'kfet.checkout'), + name='kfet.checkout'), # Checkout - Create url('^checkouts/new$', teamkfet_required(views.CheckoutCreate.as_view()), - name = 'kfet.checkout.create'), + name='kfet.checkout.create'), # Checkout - Read url('^checkouts/(?P\d+)$', teamkfet_required(views.CheckoutRead.as_view()), - name = 'kfet.checkout.read'), + name='kfet.checkout.read'), # Checkout - Update url('^checkouts/(?P\d+)/edit$', teamkfet_required(views.CheckoutUpdate.as_view()), - name = 'kfet.checkout.update'), + name='kfet.checkout.update'), - ### Checkout Statements urls + # ----- + # Checkout Statement urls + # ----- # Checkout Statement - General url('^checkouts/statements/$', teamkfet_required(views.CheckoutStatementList.as_view()), - name = 'kfet.checkoutstatement'), + name='kfet.checkoutstatement'), # Checkout Statement - Create url('^checkouts/(?P\d+)/statements/add', teamkfet_required(views.CheckoutStatementCreate.as_view()), - name = 'kfet.checkoutstatement.create'), + name='kfet.checkoutstatement.create'), # Checkout Statement - Update url('^checkouts/(?P\d+)/statements/(?P\d+)/edit', teamkfet_required(views.CheckoutStatementUpdate.as_view()), - name = 'kfet.checkoutstatement.update'), + name='kfet.checkoutstatement.update'), # ----- # Article urls @@ -107,46 +113,46 @@ urlpatterns = [ # Article - General url('^articles/$', teamkfet_required(views.ArticleList.as_view()), - name = 'kfet.article'), + name='kfet.article'), # Article - Create url('^articles/new$', teamkfet_required(views.ArticleCreate.as_view()), - name = 'kfet.article.create'), + name='kfet.article.create'), # Article - Read url('^articles/(?P\d+)$', teamkfet_required(views.ArticleRead.as_view()), - name = 'kfet.article.read'), + name='kfet.article.read'), # Article - Update url('^articles/(?P\d+)/edit$', teamkfet_required(views.ArticleUpdate.as_view()), - name = 'kfet.article.update'), + name='kfet.article.update'), # ----- # K-Psul urls # ----- - url('^k-psul/$', views.kpsul, name = 'kfet.kpsul'), + url('^k-psul/$', views.kpsul, name='kfet.kpsul'), url('^k-psul/checkout_data$', views.kpsul_checkout_data, - name = 'kfet.kpsul.checkout_data'), + name='kfet.kpsul.checkout_data'), url('^k-psul/perform_operations$', views.kpsul_perform_operations, - name = 'kfet.kpsul.perform_operations'), + name='kfet.kpsul.perform_operations'), url('^k-psul/cancel_operations$', views.kpsul_cancel_operations, - name = 'kfet.kpsul.cancel_operations'), + name='kfet.kpsul.cancel_operations'), url('^k-psul/articles_data', views.kpsul_articles_data, - name = 'kfet.kpsul.articles_data'), + name='kfet.kpsul.articles_data'), url('^k-psul/update_addcost$', views.kpsul_update_addcost, - name = 'kfet.kpsul.update_addcost'), + name='kfet.kpsul.update_addcost'), url('^k-psul/get_settings$', views.kpsul_get_settings, - name = 'kfet.kpsul.get_settings'), + name='kfet.kpsul.get_settings'), # ----- # JSON urls # ----- url(r'^history.json$', views.history_json, - name = 'kfet.history.json'), + name='kfet.history.json'), url(r'^accounts/read.json$', views.account_read_json, - name = 'kfet.account.read.json'), + name='kfet.account.read.json'), # ----- @@ -154,24 +160,26 @@ urlpatterns = [ # ----- url(r'^settings/$', - permission_required('kfet.change_settings')(views.SettingsList.as_view()), - name = 'kfet.settings'), + permission_required('kfet.change_settings') + (views.SettingsList.as_view()), + name='kfet.settings'), url(r'^settings/(?P\d+)/edit$', - permission_required('kfet.change_settings')(views.SettingsUpdate.as_view()), - name = 'kfet.settings.update'), + permission_required('kfet.change_settings') + (views.SettingsUpdate.as_view()), + name='kfet.settings.update'), # ----- # Transfers urls # ----- url(r'^transfers/$', views.transfers, - name = 'kfet.transfers'), + name='kfet.transfers'), url(r'^transfers/new$', views.transfers_create, - name = 'kfet.transfers.create'), + name='kfet.transfers.create'), url(r'^transfers/perform$', views.perform_transfers, - name = 'kfet.transfers.perform'), + name='kfet.transfers.perform'), url(r'^transfers/cancel$', views.cancel_transfers, - name = 'kfet.transfers.cancel'), + name='kfet.transfers.cancel'), # ----- # Inventories urls @@ -179,12 +187,12 @@ urlpatterns = [ url(r'^inventaires/$', teamkfet_required(views.InventoryList.as_view()), - name = 'kfet.inventory'), + name='kfet.inventory'), url(r'^inventaires/new$', views.inventory_create, - name = 'kfet.inventory.create'), + name='kfet.inventory.create'), url(r'^inventaires/(?P\d+)$', teamkfet_required(views.InventoryRead.as_view()), - name = 'kfet.inventory.read'), + name='kfet.inventory.read'), # ----- # Order urls @@ -192,15 +200,15 @@ urlpatterns = [ url(r'^orders/$', teamkfet_required(views.OrderList.as_view()), - name = 'kfet.order'), + name='kfet.order'), url(r'^orders/(?P\d+)$', teamkfet_required(views.OrderRead.as_view()), - name = 'kfet.order.read'), + name='kfet.order.read'), url(r'^orders/suppliers/(?P\d+)/edit$', teamkfet_required(views.SupplierUpdate.as_view()), - name = 'kfet.order.supplier.update'), + name='kfet.order.supplier.update'), url(r'^orders/suppliers/(?P\d+)/new-order$', views.order_create, - name = 'kfet.order.new'), + name='kfet.order.new'), url(r'^orders/(?P\d+)/to_inventory$', views.order_to_inventory, - name = 'kfet.order.to_inventory'), + name='kfet.order.to_inventory'), ] From eff37f6c89e76e531d02afd279a77cd377d578b0 Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Thu, 19 Jan 2017 01:42:00 -0200 Subject: [PATCH 2/6] plain text highlighting --- kfet/templatetags/kfet_tags.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/kfet/templatetags/kfet_tags.py b/kfet/templatetags/kfet_tags.py index bb8bce9f..7ab903b3 100644 --- a/kfet/templatetags/kfet_tags.py +++ b/kfet/templatetags/kfet_tags.py @@ -1,22 +1,23 @@ # -*- coding: utf-8 -*- -from __future__ import (absolute_import, division, - print_function, unicode_literals) -from builtins import * - from django import template from django.utils.html import escape from django.utils.safestring import mark_safe -from django.core.cache import cache from kfet.models import Settings import re register = template.Library() + +@register.filter() def highlight_text(text, q): q2 = "|".join(q.split()) pattern = re.compile(r"(?P%s)" % q2, re.IGNORECASE) - return mark_safe(re.sub(pattern, r"\g", text)) + return mark_safe( + re.sub(pattern, + r"\g", + escape(text))) + @register.filter(is_safe=True) def highlight_user(user, q): @@ -24,7 +25,8 @@ def highlight_user(user, q): text = "%s %s (%s)" % (user.first_name, user.last_name, user.username) else: text = user.username - return highlight_text(escape(text), q) + return highlight_text(text, q) + @register.filter(is_safe=True) def highlight_clipper(clipper, q): @@ -32,7 +34,8 @@ def highlight_clipper(clipper, q): text = "%s (%s)" % (clipper.fullname, clipper.username) else: text = clipper.username - return highlight_text(escape(text), q) + return highlight_text(text, q) + @register.filter() def ukf(balance, is_cof): From e7956f3b62e54bc0c4ae529d489408e328301355 Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Thu, 19 Jan 2017 12:36:40 -0200 Subject: [PATCH 3/6] Account search w/ autocomplete --- kfet/autocomplete.py | 26 +++++++++++++ .../kfet/account_search_autocomplete.html | 14 +++++++ kfet/templates/kfet/kpsul.html | 39 ++++++++++++++++++- 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 kfet/templates/kfet/account_search_autocomplete.html diff --git a/kfet/autocomplete.py b/kfet/autocomplete.py index 1ebbbc75..1c2b1a75 100644 --- a/kfet/autocomplete.py +++ b/kfet/autocomplete.py @@ -77,3 +77,29 @@ def account_create(request): data['options'] = options return render(request, "kfet/account_create_autocomplete.html", data) + + +def account_search(request): + if "q" not in request.GET: + raise Http404 + q = request.GET.get("q") + words = q.split() + + data = {'q': q} + + for word in words: + query = Account.objects.filter( + Q(cofprofile__user__username__icontains=word) | + Q(cofprofile__user__first_name__icontains=word) | + Q(cofprofile__user__last_name__icontains=word) + ).distinct() + + query = [(account.trigramme, account.cofprofile.user.get_full_name()) + for account in query] + + data['accounts'] = query + options = len(query) + + data['options'] = options + + return render(request, 'kfet/account_search_autocomplete.html', data) diff --git a/kfet/templates/kfet/account_search_autocomplete.html b/kfet/templates/kfet/account_search_autocomplete.html new file mode 100644 index 00000000..22e2cca3 --- /dev/null +++ b/kfet/templates/kfet/account_search_autocomplete.html @@ -0,0 +1,14 @@ +{% load kfet_tags %} + +
      + {% if accounts %} + {% for trigramme, user in accounts %} +
    • {{ user|highlight_text:q }} ({{ trigramme }})
    • + {% endfor %} + {% elif not q %} +
    • Pas de recherche, pas de résultats !
    • + {% else %} +
    • Aucune correspondance trouvée :-(
    • + {% endif %} +
    + diff --git a/kfet/templates/kfet/kpsul.html b/kfet/templates/kfet/kpsul.html index 26c98e55..6178f039 100644 --- a/kfet/templates/kfet/kpsul.html +++ b/kfet/templates/kfet/kpsul.html @@ -4,6 +4,7 @@ {% block extra_head %} + @@ -256,12 +257,48 @@ $(document).ready(function() { buttons += ''; } else { var url_base = '{% url 'kfet.account' %}' - buttons += ''; + buttons += ''; } } account_container.find('.buttons').html(buttons); } + // Search for an account + function searchAccount() { + var content = '
    ' ; + $.dialog({ + title: 'Recherche de compte', + content: content, + backgroundDismiss: true, + animation: 'top', + closeAnimation: 'bottom', + keyboardEnabled: true, + onOpen: function() { + var that=this ; + $('input#search_autocomplete').yourlabsAutocomplete({ + url: '{% url 'kfet.account.search.autocomplete' %}', + minimumCharacters: 2, + id: 'search_autocomplete', + choiceSelector: '.choice', + placeholder: "Chercher un utilisateur K-Fêt", + box: $(".yourlabs-autocomplete"), + }); + $('input#search_autocomplete').bind( + 'selectChoice', + function(e, choice, autocomplete) { + autocomplete.hide() ; + triInput.val(choice.find('.trigramme').text()) ; + triInput.trigger('input') ; + that.close() ; + }); + } + }); + } + + account_container.on('click', '.search', function () { + searchAccount() ; + }) ; + // Clear data function resetAccountData() { account_data = account_data_default; From 016989c4de291dee3b53cf7bdfc55651cbb63647 Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Thu, 19 Jan 2017 22:53:58 -0200 Subject: [PATCH 4/6] search results css --- kfet/static/kfet/css/jconfirm-kfet.css | 21 +++++++++++++++++++ .../kfet/account_search_autocomplete.html | 2 +- kfet/templates/kfet/kpsul.html | 6 +++--- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/kfet/static/kfet/css/jconfirm-kfet.css b/kfet/static/kfet/css/jconfirm-kfet.css index 4269fbcc..0bd53ab7 100644 --- a/kfet/static/kfet/css/jconfirm-kfet.css +++ b/kfet/static/kfet/css/jconfirm-kfet.css @@ -83,3 +83,24 @@ padding-right: 50px; padding-left: 50px; } + +/* Account autocomplete window */ + +#account_results ul { + list-style-type:none; + background:rgba(255,255,255,0.9); + padding:0; +} + +#account_results li { + display:block; + padding:5px 20px; + height:100%; + width:100%; +} + +#account_results .hilight { + background:rgba(200,16,46,0.9); + color:#fff; + text-decoration:none; +} diff --git a/kfet/templates/kfet/account_search_autocomplete.html b/kfet/templates/kfet/account_search_autocomplete.html index 22e2cca3..e18eb1eb 100644 --- a/kfet/templates/kfet/account_search_autocomplete.html +++ b/kfet/templates/kfet/account_search_autocomplete.html @@ -3,7 +3,7 @@
      {% if accounts %} {% for trigramme, user in accounts %} -
    • {{ user|highlight_text:q }} ({{ trigramme }})
    • +
    • {{ user|highlight_text:q }} ({{ trigramme }})
    • {% endfor %} {% elif not q %}
    • Pas de recherche, pas de résultats !
    • diff --git a/kfet/templates/kfet/kpsul.html b/kfet/templates/kfet/kpsul.html index 6178f039..46a3088a 100644 --- a/kfet/templates/kfet/kpsul.html +++ b/kfet/templates/kfet/kpsul.html @@ -265,7 +265,7 @@ $(document).ready(function() { // Search for an account function searchAccount() { - var content = '
      ' ; + var content = '
      ' ; $.dialog({ title: 'Recherche de compte', content: content, @@ -276,12 +276,12 @@ $(document).ready(function() { onOpen: function() { var that=this ; $('input#search_autocomplete').yourlabsAutocomplete({ - url: '{% url 'kfet.account.search.autocomplete' %}', + url: '{% url "kfet.account.search.autocomplete" %}', minimumCharacters: 2, id: 'search_autocomplete', choiceSelector: '.choice', placeholder: "Chercher un utilisateur K-Fêt", - box: $(".yourlabs-autocomplete"), + box: $("#account_results"), }); $('input#search_autocomplete').bind( 'selectChoice', From 832dc0ce1002ff6ee13f829cb13fbc61c849d181 Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Thu, 19 Jan 2017 22:54:11 -0200 Subject: [PATCH 5/6] Search shortcut --- kfet/templates/kfet/kpsul.html | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/kfet/templates/kfet/kpsul.html b/kfet/templates/kfet/kpsul.html index 46a3088a..0646416d 100644 --- a/kfet/templates/kfet/kpsul.html +++ b/kfet/templates/kfet/kpsul.html @@ -299,6 +299,14 @@ $(document).ready(function() { searchAccount() ; }) ; + account_container.on('keydown', function(e) { + if (e.which == 70 && e.ctrlKey) { + // Ctrl + F : universal search shortcut + searchAccount() ; + e.preventDefault() ; + } + }); + // Clear data function resetAccountData() { account_data = account_data_default; From 1b0144691f636eff8c1404056a8eb3128b16c2a2 Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Fri, 20 Jan 2017 07:32:11 -0200 Subject: [PATCH 6/6] No need for len of query --- kfet/autocomplete.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/kfet/autocomplete.py b/kfet/autocomplete.py index 1c2b1a75..896eff6e 100644 --- a/kfet/autocomplete.py +++ b/kfet/autocomplete.py @@ -98,8 +98,4 @@ def account_search(request): for account in query] data['accounts'] = query - options = len(query) - - data['options'] = options - return render(request, 'kfet/account_search_autocomplete.html', data)