diff options
| author | Étienne Loks <etienne.loks@iggdrasil.net> | 2018-07-11 23:38:14 +0200 | 
|---|---|---|
| committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2018-08-13 18:26:03 +0200 | 
| commit | a5593d66ea541dfbcd2597f81dcbc51965c51cfc (patch) | |
| tree | e778fa93380d0244bfd8d115143996bad51612aa /ishtar_common | |
| parent | 05495e0b37da09deb7b7d2e5629112a046042836 (diff) | |
| download | Ishtar-a5593d66ea541dfbcd2597f81dcbc51965c51cfc.tar.bz2 Ishtar-a5593d66ea541dfbcd2597f81dcbc51965c51cfc.zip | |
Manage alerts
Diffstat (limited to 'ishtar_common')
| -rw-r--r-- | ishtar_common/static/js/ishtar.js | 32 | ||||
| -rw-r--r-- | ishtar_common/templates/base.html | 1 | ||||
| -rw-r--r-- | ishtar_common/templates/blocks/DataTables.html | 20 | ||||
| -rw-r--r-- | ishtar_common/templates/ishtar/blocks/base_shortcut_menu.html | 4 | ||||
| -rw-r--r-- | ishtar_common/templates/ishtar/wizard/search.html | 8 | ||||
| -rw-r--r-- | ishtar_common/urls.py | 6 | ||||
| -rw-r--r-- | ishtar_common/utils.py | 3 | ||||
| -rw-r--r-- | ishtar_common/views.py | 50 | ||||
| -rw-r--r-- | ishtar_common/views_item.py | 17 | ||||
| -rw-r--r-- | ishtar_common/wizards.py | 22 | 
10 files changed, 149 insertions, 14 deletions
| diff --git a/ishtar_common/static/js/ishtar.js b/ishtar_common/static/js/ishtar.js index a71450fab..60840bcf8 100644 --- a/ishtar_common/static/js/ishtar.js +++ b/ishtar_common/static/js/ishtar.js @@ -38,7 +38,10 @@ function manage_async_link(event){  function get_next_table_id(){}  function get_previous_table_id(){} +var datatable_submit_search = function() {}; +  var shortcut_url = ''; +var alert_url = '';  var datatables_i18n;  var current_modal; @@ -222,6 +225,7 @@ function load_shortcut_menu(opened){          cache: false,          success:function(html){              init_shortcut_menu(html); +            load_alerts();              if(opened){                  $("#dropdown-toggle-shortcut-menu").click();              } @@ -232,6 +236,34 @@ function load_shortcut_menu(opened){      });  } +var load_alerts = function(){ +    if (!alert_url) return; +    $('.modal-progress').modal('show'); +    $.ajax({ +        url: alert_url, +        cache: false, +        success:function(json){ +            $('.modal-progress').modal('hide'); +            var html = ""; +            for (idx in json["alerts"]){ +                var b = json["alerts"][idx]; +                var url = "/bookmark/" + b["query_id"] + "/" ; +                html += '<a class="badge badge-secondary" href="' + url + '">'; +                html += b["label"]; +                html += ' <span class="badge badge-light">'; +                html += b["number"]; +                html += '</span>'; +                html += '</a> '; +            } +            $("#alert-list").html(html); +        }, +        error:function(XMLHttpRequest, textStatus, errorThrows){ +            close_wait(); +        }, +        dataType: 'json' +    }); +} +  function dynamic_load(url, target){      $.ajax({          url: url, diff --git a/ishtar_common/templates/base.html b/ishtar_common/templates/base.html index 40e30706c..72c6a9b65 100644 --- a/ishtar_common/templates/base.html +++ b/ishtar_common/templates/base.html @@ -30,6 +30,7 @@      {{EXTRA_JS|safe}}      <script type='text/javascript'>      var shortcut_url = '{% url "shortcut-menu" %}'; +    var alert_url = '{% url "alert-list" %}';      var get_file_url = '{% url "get-file-shortcut" %}';      var get_operation_url = '{% url "get-operation-shortcut" %}';      var get_contextrecord_url = '{% url "get-contextrecord-shortcut" %}'; diff --git a/ishtar_common/templates/blocks/DataTables.html b/ishtar_common/templates/blocks/DataTables.html index 0ae6ba7d0..c3ca16395 100644 --- a/ishtar_common/templates/blocks/DataTables.html +++ b/ishtar_common/templates/blocks/DataTables.html @@ -99,8 +99,9 @@ $('#modal_grid_{{name}}').on('hide.bs.modal', function (e) {  var query_vars = new Array({{col_idx|safe}});  var selItems_{{sname}} = new Array(); -jQuery(document).ready(function(){ -  jQuery("#search_{{name}}").click(function (){ + + +datatable_submit_search = function(){      $("#id_search_vector").removeClass('input-progress');      if ($('.modal-progress').length > 0){          $('.modal-progress').modal('show'); @@ -137,11 +138,22 @@ jQuery(document).ready(function(){          $('.modal-progress').modal('hide');      }      return false; -  }); +}; + + + +jQuery(document).ready(function(){ +  jQuery("#search_{{name}}").click(datatable_submit_search); + +  var base_source = "{{source}}"; + +  if (default_search_vector){ +    base_source += "?search_vector=" + default_search_vector; +  }    datatable_options = {      "ajax": { -        "url": "{{source}}", +        "url": base_source,          "dataSrc": function (json) {              manage_pinned_search("{{name}}", json);              return json.rows; diff --git a/ishtar_common/templates/ishtar/blocks/base_shortcut_menu.html b/ishtar_common/templates/ishtar/blocks/base_shortcut_menu.html index 6faf37670..77ef9804b 100644 --- a/ishtar_common/templates/ishtar/blocks/base_shortcut_menu.html +++ b/ishtar_common/templates/ishtar/blocks/base_shortcut_menu.html @@ -8,7 +8,9 @@      <span class="navbar-toggler-icon"></span>  </button>  {% endcomment %} -<div class="navbar-collapse collapse justify-content-end"> +<div class="navbar-collapse collapse justify-content-between"> +    <span id="alert-list"> +    </span>      <ul class="navbar-nav" id="navbar-shortcut">        <li class="nav-item">            <ol class="breadcrumb"> diff --git a/ishtar_common/templates/ishtar/wizard/search.html b/ishtar_common/templates/ishtar/wizard/search.html index eebd58d89..a7a6faec7 100644 --- a/ishtar_common/templates/ishtar/wizard/search.html +++ b/ishtar_common/templates/ishtar/wizard/search.html @@ -5,6 +5,14 @@  {% endblock %}  {% block content %}  <h3>{{wizard_label}}</h3> +{% if default_search_vector %} +<script type="text/javascript"> +    var default_search_vector = "{{default_search_vector|safe}}".replace(/''/g, '"'); +    $(document).ready(function() { +        $("#id_search_vector").val(default_search_vector.replace(/''/g, '"')); +    }); +</script> +{% endif %}  {% comment %}  <nav aria-label="breadcrumb" role="navigation"> diff --git a/ishtar_common/urls.py b/ishtar_common/urls.py index 44ebd0f93..ee1b3805e 100644 --- a/ishtar_common/urls.py +++ b/ishtar_common/urls.py @@ -128,8 +128,10 @@ urlpatterns = [          views.SearchQueryEdit.as_view(),          name='save-search-query'),      url(r'^bookmarks/(?P<app_label>[a-z-]+)/(?P<model>[a-z-]+)/$', -        views.BookmarkList.as_view(), -        name='bookmark-list'), +        views.BookmarkList.as_view(), name='bookmark-list'), +    url(r'^bookmark/(?P<pk>[0-9]+)/$', +        views.get_bookmark, name='bookmark'), +    url(r'^alerts/$', views.AlertList.as_view(), name='alert-list'),      url(r'^success(?:/(?P<context>[a-z-]+))?/$',          TemplateView.as_view(template_name="ishtar/forms/success.html"),          name='success'), diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index 34d170892..0e5dd286a 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -794,7 +794,8 @@ def create_default_json_fields(model):          ) -def get_urls_for_model(model, views, own=False, autocomplete=False): +def get_urls_for_model(model, views, own=False, autocomplete=False, +                       ):      """      Generate get and show url for a model      """ diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 1f8b46fd6..c713b9972 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -21,6 +21,7 @@ import csv  import datetime  import json  import logging +import importlib  import unicodedata  import unicodecsv @@ -1676,6 +1677,19 @@ document_deletion_wizard = wizards.DocumentDeletionWizard.as_view(      url_name='document_deletion',) +def get_bookmark(request, pk): +    try: +        sq = models.SearchQuery.objects.get( +            pk=pk, +            profile__person__ishtaruser__user_ptr=request.user) +    except models.SearchQuery.DoesNotExist: +        raise Http404() +    slug = sq.content_type.model_class().SLUG +    return redirect( +        reverse(slug + '_search') + "?bookmark={}".format(sq.pk) +    ) + +  class SearchQueryMixin(object):      """      Manage content type and profile init @@ -1736,3 +1750,39 @@ class BookmarkList(SearchQueryMixin, JSONResponseMixin, LoginRequiredMixin,              'bookmarks': [                  {'label': sq.label, 'query': sq.query} for sq in q.all()]          } + + +class AlertList(JSONResponseMixin, LoginRequiredMixin, +                TemplateView): +    def dispatch(self, request, *args, **kwargs): +        if not request.user.pk: +            raise Http404() +        try: +            self.profile = models.UserProfile.objects.get( +                current=True, person__ishtaruser__user_ptr=request.user) +        except models.UserProfile.DoesNotExist: +            # no current profile +            raise Http404() +        return super(AlertList, self).dispatch(request, *args, **kwargs) + +    def get_data(self, context): +        q = models.SearchQuery.objects.filter( +            profile=self.profile, +            is_alert=True +        ) +        alerts = [] +        for sq in q.all(): +            model = sq.content_type.model_class() +            module = model.__module__.split('.')[0] +            views = importlib.import_module(module + '.views') +            get_view = getattr(views, "get_" + model.SLUG) +            nb = get_view( +                self.request, +                query={'search_vector': sq.query}, +                count=True +            ) +            alerts.append( +                {'label': sq.label, 'query_id': sq.pk, +                 'number': nb} +            ) +        return {'alerts': alerts} diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py index 854c91ce5..85ef5339a 100644 --- a/ishtar_common/views_item.py +++ b/ishtar_common/views_item.py @@ -12,7 +12,6 @@ from tempfile import NamedTemporaryFile  from django.conf import settings  from django.contrib.gis.geos import GEOSException -from django.contrib.postgres.search import SearchQuery  from django.contrib.staticfiles.templatetags.staticfiles import static  from django.core.exceptions import ObjectDoesNotExist  from django.core.urlresolvers import reverse, NoReverseMatch @@ -821,14 +820,22 @@ def get_item(model, func_name, default_name, extra_request_keys=[],                         (hasattr(field, 'rel') and field.rel and '__pk' or ''))                        for field in associated_fields]))          request_keys.update(my_extra_request_keys) -        request_items = request.method == 'POST' and request.POST \ -                        or request.GET + +        if "query" in dct: +            request_items = dct["query"] +        elif request.method == 'POST': +            request_items = request.POST +        else: +            request_items = request.GET + +        count = dct.get('count', False)          # pager          try:              row_nb = int(request_items.get('length'))          except (ValueError, TypeError):              row_nb = DEFAULT_ROW_NUMBER +          dct_request_items = {}          # filter requested fields @@ -839,6 +846,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[],              if key.startswith('searchprefix_'):                  key = key[len('searchprefix_'):]              dct_request_items[key] = request_items[k] +          request_items = dct_request_items          dct = my_base_request @@ -985,6 +993,9 @@ def get_item(model, func_name, default_name, extra_request_keys=[],              items = items.extra(**extra)          items = items.distinct() + +        if count: +            return items.count()          # print(items.query)          if search_vector:  # for serialization diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index 4a55345d2..b1e0c7fd2 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -1413,9 +1413,25 @@ class SearchWizard(IshtarWizard):          context = super(SearchWizard, self).get_context_data(form)          self.request.session['CURRENT_ACTION'] = self.get_wizard_name()          current_step = self.steps.current -        context.update({'current_step': self.form_list[current_step], -                        'is_search': True, -                        'wizard_label': self.get_label()}) +        bookmark = self.request.GET.get('bookmark', None) +        default_search_vector = None +        if bookmark: +            try: +                app_label = self.model.__module__.split('.')[0] +                sq = models.SearchQuery.objects.get( +                    pk=bookmark, +                    content_type__app_label=app_label, +                    content_type__model=self.model.SLUG, +                    profile__person__ishtaruser__user_ptr=self.request.user +                ) +                default_search_vector = sq.query.replace('"', "''") +            except models.SearchQuery.DoesNotExist: +                pass +        context.update({ +            'current_step': self.form_list[current_step], +            'is_search': True, 'wizard_label': self.get_label(), +            'default_search_vector': default_search_vector +        })          return context | 
