diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2018-10-01 15:10:07 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2018-10-24 12:06:08 +0200 |
commit | e55d8d335b682f86439457c577c95b1768543f22 (patch) | |
tree | 8d6e00ce0a1a19b41869b6b6b2ebc5afbb133b64 /ishtar_common | |
parent | 179b51b530687a6d81c1434d13d12c02afe7abff (diff) | |
download | Ishtar-e55d8d335b682f86439457c577c95b1768543f22.tar.bz2 Ishtar-e55d8d335b682f86439457c577c95b1768543f22.zip |
Manage site and warehouse in shortcut menu - Many fixes on pin
Diffstat (limited to 'ishtar_common')
-rw-r--r-- | ishtar_common/forms_common.py | 27 | ||||
-rw-r--r-- | ishtar_common/models.py | 61 | ||||
-rw-r--r-- | ishtar_common/static/js/ishtar.js | 44 | ||||
-rw-r--r-- | ishtar_common/views.py | 25 | ||||
-rw-r--r-- | ishtar_common/views_item.py | 154 |
5 files changed, 238 insertions, 73 deletions
diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py index 9be147871..1da4ac35f 100644 --- a/ishtar_common/forms_common.py +++ b/ishtar_common/forms_common.py @@ -46,6 +46,10 @@ from forms import FinalForm, FormSet, reverse_lazy, name_validator, \ FormSetWithDeleteSwitches, IshtarForm, get_data_from_formset from ishtar_common.utils import is_downloadable, clean_session_cache +from archaeological_operations.models import Operation +from archaeological_context_records.models import ContextRecord +from archaeological_finds.models import Find + def get_town_field(label=_(u"Town"), required=True): help_text = _( @@ -1208,11 +1212,34 @@ class DocumentSelect(TableSelect): additional_information = forms.CharField( label=_(u"Additional informations")) duplicate = forms.NullBooleanField(label=_(u"Has a duplicate")) + operation = forms.IntegerField( + label=_(u"Operation"), required=False, + widget=widgets.JQueryAutoComplete( + reverse_lazy('autocomplete-operation'), + associated_model=Operation), + validators=[models.valid_id(Operation)]) + context_record = forms.IntegerField( + label=_(u"Context record"), required=False, + widget=widgets.JQueryAutoComplete( + reverse_lazy('autocomplete-contextrecord'), + associated_model=ContextRecord), + validators=[models.valid_id(ContextRecord)]) + find = forms.IntegerField( + label=_(u"Find"), required=False, + widget=widgets.JQueryAutoComplete( + reverse_lazy('autocomplete-find'), + associated_model=Find), + validators=[models.valid_id(Find)]) TYPES = [ FieldType('source_type', models.SourceType), ] + PROFILE_FILTER = { + 'context_record': ['context_record'], + 'find': ['find'], + } + class DocumentFormSelection(forms.Form): SEARCH_AND_SELECT = True diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 5be06fd32..0a00fc108 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -294,11 +294,13 @@ class OwnPerms(object): sorted(owns, key=lambda x: x[0][label_key])) @classmethod - def get_owns(cls, user, replace_query={}, limit=None, values=None, - get_short_menu_class=False): + def get_owns(cls, user, replace_query=None, limit=None, values=None, + get_short_menu_class=False, menu_filtr=None): """ Get Own items """ + if not replace_query: + replace_query = {} if hasattr(user, 'is_authenticated') and not user.is_authenticated(): returned = cls.objects.filter(pk__isnull=True) if values: @@ -3636,6 +3638,30 @@ class Document(OwnPerms, ImageModel, FullSearch, Imported): pgettext_lazy("key for text search", u"has-duplicate"), 'duplicate' ), + 'operation': ( + pgettext_lazy("key for text search", u"operation"), + 'operations__cached_label__iexact' + ), + 'context_record': ( + pgettext_lazy("key for text search", u"context-record"), + 'context_records__cached_label__iexact' + ), + 'find': ( + pgettext_lazy("key for text search", u"find"), + 'finds__cached_label__iexact' + ), + 'file': ( + pgettext_lazy("key for text search", u"file"), + 'files__cached_label__iexact' + ), + 'site': ( + pgettext_lazy("key for text search", u"site"), + 'sites__cached_label__iexact' + ), + 'warehouse': ( + pgettext_lazy("key for text search", u"warehouse"), + 'warehouses__name__iexact' + ), } for v in ALT_NAMES.values(): for language_code, language_lbl in settings.LANGUAGES: @@ -3644,6 +3670,37 @@ class Document(OwnPerms, ImageModel, FullSearch, Imported): deactivate() objects = ExternalIdManager() + RELATED_MODELS_ALT = [ + 'finds', 'context_records', 'operations', 'sites', 'files', + 'warehouses', 'treatments', 'treatment_files', + ] + RELATIVE_SESSION_NAMES = [ + ('find', 'finds__pk'), + ('contextrecord', 'context_records__pk'), + ('operation', 'operations__pk'), + ('site', 'sites__pk'), + ('file', 'files__pk'), + ('warehouse', 'warehouses__pk'), + ('treatment', 'treatments__pk'), + ('treatmentfile', 'treatment_files__pk'), + ] + + UP_MODEL_QUERY = { + "operation": (pgettext_lazy("key for text search", u"operation"), + 'cached_label'), + "contextrecord": (pgettext_lazy("key for text search", + u"context-record"), 'cached_label'), + "file": (pgettext_lazy("key for text search", u"file"), 'cached_label'), + "find": (pgettext_lazy("key for text search", u"find"), 'cached_label'), + "site": (pgettext_lazy("key for text search", u"site"), 'cached_label'), + "warehouse": (pgettext_lazy("key for text search", u"warehouse"), + 'cached_label'), + "treatment": (pgettext_lazy("key for text search", u"treatment"), + 'cached_label'), + "treatmentfile": (pgettext_lazy("key for text search", + u"treatment-file"), 'cached_label'), + } + title = models.TextField(_(u"Title"), blank=True, default='') associated_file = models.FileField( upload_to=get_image_path, blank=True, null=True, max_length=255) diff --git a/ishtar_common/static/js/ishtar.js b/ishtar_common/static/js/ishtar.js index 2ff9e07a7..6013afc27 100644 --- a/ishtar_common/static/js/ishtar.js +++ b/ishtar_common/static/js/ishtar.js @@ -128,6 +128,12 @@ function init_shortcut_fields(){ load_opened_shortcut_menu ); }); + $("#current_site").change(function(){ + $.post('/' + url_path + 'update-current-item/', + {item:'site', value:$("#current_site").val()}, + load_opened_shortcut_menu + ); + }); $("#current_contextrecord").change(function(){ $.post('/' + url_path + 'update-current-item/', {item:'contextrecord', value:$("#current_contextrecord").val()}, @@ -140,6 +146,12 @@ function init_shortcut_fields(){ load_opened_shortcut_menu ); }); + $("#current_warehouse").change(function(){ + $.post('/' + url_path + 'update-current-item/', + {item:'warehouse', value:$("#current_warehouse").val()}, + load_opened_shortcut_menu + ); + }); $("#current_treatment").change(function(){ $.post('/' + url_path + 'update-current-item/', {item:'treatment', value:$("#current_treatment").val()}, @@ -171,6 +183,14 @@ function init_advanced_shortcut_fields(){ load_opened_shortcut_menu ); }); + $('#id_site-shortcut').change(function(){ + $("#id_select_site-shortcut").attr( + 'title', $('#id_select_site-shortcut').val()); + $.post('/' + url_path + 'update-current-item/', + {item: "site", value:$("#id_site-shortcut").val()}, + load_opened_shortcut_menu + ); + }); $('#id_contextrecord-shortcut').change(function(){ $("#id_select_contextrecord-shortcut").attr( 'title', $('#id_select_contextrecord-shortcut').val()); @@ -187,6 +207,30 @@ function init_advanced_shortcut_fields(){ load_opened_shortcut_menu ); }); + $('#id_warehouse-shortcut').change(function(){ + $("#id_select_warehouse-shortcut").attr( + 'title', $('#id_select_warehouse-shortcut').val()); + $.post('/' + url_path + 'update-current-item/', + {item: "warehouse", value:$("#id_warehouse-shortcut").val()}, + load_opened_shortcut_menu + ); + }); + $('#id_treatment-shortcut').change(function(){ + $("#id_select_treatment-shortcut").attr( + 'title', $('#id_select_treatment-shortcut').val()); + $.post('/' + url_path + 'update-current-item/', + {item: "treatment", value:$("#id_treatment-shortcut").val()}, + load_opened_shortcut_menu + ); + }); + $('#id_treatmentfile-shortcut').change(function(){ + $("#id_select_treatmentfile-shortcut").attr( + 'title', $('#id_select_treatmentfile-shortcut').val()); + $.post('/' + url_path + 'update-current-item/', + {item: "treatmentfile", value:$("#id_treatmentfile-shortcut").val()}, + load_opened_shortcut_menu + ); + }); } function display_info(msg){ diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 8214f22d7..55b5fce1e 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -52,7 +52,8 @@ from archaeological_finds.forms import DashboardTreatmentForm, \ DashboardTreatmentFileForm from archaeological_finds.models import Find, Treatment, TreatmentFile from archaeological_operations.forms import DashboardForm as DashboardFormOpe -from archaeological_operations.models import Operation +from archaeological_operations.models import Operation, ArchaeologicalSite +from archaeological_warehouse.models import Warehouse from ishtar_common import forms_common as forms from ishtar_common import wizards from ishtar_common.forms import FinalForm, FinalDeleteForm @@ -62,8 +63,8 @@ from ishtar_common.utils import clean_session_cache, CSV_OPTIONS, \ get_field_labels_from_path, get_random_item_image_link, shortify from ishtar_common.widgets import JQueryAutoComplete -from views_item import CURRENT_ITEM_KEYS, check_permission, display_item, \ - get_item, new_item, show_item +from views_item import CURRENT_ITEM_KEYS, CURRENT_ITEM_KEYS_DICT, \ + check_permission, display_item, get_item, new_item, show_item logger = logging.getLogger(__name__) @@ -250,8 +251,12 @@ def shortcut_menu(request): if profile.files: CURRENT_ITEMS.append((_(u"Archaeological file"), File)) CURRENT_ITEMS.append((_(u"Operation"), Operation)) + if profile.archaeological_site: + CURRENT_ITEMS.append((profile.get_site_label(), ArchaeologicalSite)) if profile.context_record: CURRENT_ITEMS.append((_(u"Context record"), ContextRecord)) + if profile.warehouse: + CURRENT_ITEMS.append((_(u"Warehouse"), Warehouse)) if profile.find: CURRENT_ITEMS.append((_(u"Find"), Find)) if profile.warehouse: @@ -323,7 +328,7 @@ def shortcut_menu(request): continue current_items.append(pk) selected = pk == current - item_label = shortify(item['cached_label'], 60) + item_label = shortify(item[lbl_key], 60) if selected: cls = shortmenu_class new_selected_item = pk @@ -365,8 +370,7 @@ def get_current_items(request): def unpin(request, item_type): - if item_type not in ('find', 'contextrecord', 'operation', 'file', - 'treatment', 'treatmentfile'): + if item_type not in CURRENT_ITEM_KEYS_DICT.keys(): logger.warning("unpin unknow type: {}".format(item_type)) return HttpResponse('nok') request.session['treatment'] = '' @@ -378,9 +382,15 @@ def unpin(request, item_type): request.session['find'] = '' if item_type == 'find': return HttpResponse('ok') + request.session['warehouse'] = '' + if item_type == 'warehouse': + return HttpResponse('ok') request.session['contextrecord'] = '' if item_type == 'contextrecord': return HttpResponse('ok') + request.session['site'] = '' + if item_type == 'site': + return HttpResponse('ok') request.session['operation'] = '' if item_type == 'operation': return HttpResponse('ok') @@ -401,16 +411,19 @@ def update_current_item(request, item_type=None, pk=None): request.session['SHORTCUT_SEARCH'] = 'all' currents = get_current_items(request) + # re-init when descending item are not relevant if item_type == 'file' and currents['file'] and currents['operation'] and \ currents['operation'].associated_file != currents['file']: request.session["operation"] = '' currents['operation'] = None + if item_type in ('operation', 'file') and currents['contextrecord'] and \ (not request.session.get("operation", None) or currents['contextrecord'].operation != currents['operation']): request.session["contextrecord"] = '' currents['contextrecord'] = None + from archaeological_finds.models import Find if item_type in ('contextrecord', 'operation', 'file') and \ currents['find'] and \ diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py index 98dcd3d4c..d068fb554 100644 --- a/ishtar_common/views_item.py +++ b/ishtar_common/views_item.py @@ -35,10 +35,11 @@ from menus import Menu import models from archaeological_files.models import File -from archaeological_operations.models import Operation +from archaeological_operations.models import Operation, ArchaeologicalSite from archaeological_context_records.models import ContextRecord from archaeological_finds.models import Find, FindBasket, Treatment, \ TreatmentFile +from archaeological_warehouse.models import Warehouse logger = logging.getLogger(__name__) @@ -46,7 +47,9 @@ ENCODING = settings.ENCODING or 'utf-8' CURRENT_ITEM_KEYS = (('file', File), ('operation', Operation), + ('site', ArchaeologicalSite), ('contextrecord', ContextRecord), + ('warehouse', Warehouse), ('find', Find), ('treatmentfile', TreatmentFile), ('treatment', Treatment)) @@ -440,15 +443,16 @@ def _search_manage_search_vector(model, dct, exc_dct, request_keys): if 'search_vector' not in dct: return dct, exc_dct - # remove inside parenthesis - search_vector = \ - dct['search_vector'].replace(u'(', u'').replace(u')', u'').strip() + search_vector = dct['search_vector'] parentheses_groups = _parse_parentheses(search_vector) search_query, extra_dct, extra_exc_dct = _parse_parentheses_groups( parentheses_groups, request_keys) dct.update(extra_dct) exc_dct.update(extra_exc_dct) if search_query: + # remove inside parenthesis + search_query = \ + search_query.replace(u'(', u'').replace(u')', u'').strip() dct['extras'].append( {'where': [model._meta.db_table + ".search_vector @@ (to_tsquery(%s, %s)) = true"], @@ -760,6 +764,64 @@ def _construct_query(relation_types, dct, or_reqs, and_reqs): return query +def _manage_default_search(dct, request, model, default_name, my_base_request, + my_relative_session_names): + # an item is selected in the default menu + pinned_search = "" + if default_name in request.session and \ + request.session[default_name]: + value = request.session[default_name] + if 'basket-' in value: + try: + dct = {"basket__pk": + request.session[default_name].split('-')[-1]} + pinned_search = unicode(FindBasket.objects.get( + pk=dct["basket__pk"])) + except FindBasket.DoesNotExist: + pass + else: + try: + dct = {"pk": request.session[default_name]} + pinned_search = u'"{}"'.format( + model.objects.get(pk=dct["pk"]) + ) + except model.DoesNotExist: + pass + elif dct == (my_base_request or {}): + if not hasattr(model, 'UP_MODEL_QUERY'): + logger.warning( + "**WARN get_item**: - UP_MODEL_QUERY not defined for " + "'{}'".format(model)) + else: + # a parent item may be selected in the default menu + for name, key in my_relative_session_names: + if name in request.session and request.session[name] \ + and 'basket-' not in request.session[name] \ + and name in CURRENT_ITEM_KEYS_DICT: + up_model = CURRENT_ITEM_KEYS_DICT[name] + try: + dct.update({key: request.session[name]}) + up_item = up_model.objects.get(pk=dct[key]) + if up_item.SLUG not in model.UP_MODEL_QUERY: + logger.warning( + "**WARN get_item**: - {} not in " + "UP_MODEL_QUERY for {}'".format( + up_item.SLUG, + model)) + else: + req_key, up_attr = model.UP_MODEL_QUERY[ + up_item.SLUG] + pinned_search = u'{}="{}"'.format( + req_key, + getattr(up_item, up_attr) + ) + break + except up_model.DoesNotExist: + pass + + return dct, pinned_search + + def _format_val(val): if val is None: return u"" @@ -931,7 +993,11 @@ def get_item(model, func_name, default_name, extra_request_keys=[], exc_and_reqs, exc_or_reqs = [], [] if full == 'shortcut': - dct['cached_label__icontains'] = request.GET.get('term', None) + if model.SLUG == "warehouse": + key = 'name__icontains' + else: + key = 'cached_label__icontains' + dct[key] = request.GET.get('term', None) try: old = 'old' in request_items and int(request_items['old']) @@ -955,62 +1021,13 @@ def get_item(model, func_name, default_name, extra_request_keys=[], pinned_search = "" if 'submited' not in request_items and full != 'shortcut': - # default search - # an item is selected in the default menu - if default_name in request.session and \ - request.session[default_name]: - value = request.session[default_name] - if 'basket-' in value: - try: - dct = {"basket__pk": - request.session[default_name].split('-')[-1]} - pinned_search = unicode(FindBasket.objects.get( - pk=dct["basket__pk"])) - except FindBasket.DoesNotExist: - pass - else: - try: - dct = {"pk": request.session[default_name]} - pinned_search = u'"{}"'.format( - model.objects.get(pk=dct["pk"]) - ) - except model.DoesNotExist: - pass - elif dct == (my_base_request or {}): - if not hasattr(model, 'UP_MODEL_QUERY'): - logger.warning( - "**WARN get_item**: - UP_MODEL_QUERY not defined for " - "'{}'".format(model.__class__)) - else: - # a parent item may be selected in the default menu - for name, key in my_relative_session_names: - if name in request.session and request.session[name] \ - and 'basket-' not in request.session[name] \ - and name in CURRENT_ITEM_KEYS_DICT: - up_model = CURRENT_ITEM_KEYS_DICT[name] - try: - dct.update({key: request.session[name]}) - up_item = up_model.objects.get(pk=dct[key]) - if up_item.short_class_name not in \ - model.UP_MODEL_QUERY: - logger.warning( - "**WARN get_item**: - {} not in " - "UP_MODEL_QUERY for {}'".format( - up_item.short_class_name, - model)) - else: - req_key, up_attr = model.UP_MODEL_QUERY[ - up_item.short_class_name] - pinned_search = u'{}="{}"'.format( - req_key, - getattr(up_item, up_attr) - ) - break - except up_model.DoesNotExist: - pass - if (not dct or data_type == 'csv') \ - and func_name in request.session: + if data_type == 'csv' and func_name in request.session: dct = request.session[func_name] + else: + # default search + dct, pinned_search = _manage_default_search( + dct, request, model, default_name, my_base_request, + my_relative_session_names) else: request.session[func_name] = dct @@ -1092,7 +1109,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[], if count: return items.count() - # print(items.query) + # print(unicode(items.query).encode('utf-8')) if search_vector: # for serialization dct['search_vector'] = search_vector @@ -1130,8 +1147,12 @@ def get_item(model, func_name, default_name, extra_request_keys=[], query_table_cols[idx] = \ model.CONTEXTUAL_TABLE_COLS[contxt][col] if full == 'shortcut': - query_table_cols = ['cached_label'] - table_cols = ['cached_label'] + if model.SLUG == "warehouse": + query_table_cols = ['name'] + table_cols = ['name'] + else: + query_table_cols = ['cached_label'] + table_cols = ['cached_label'] # manage sort tables manual_sort_key = None @@ -1328,8 +1349,11 @@ def get_item(model, func_name, default_name, extra_request_keys=[], if hasattr(model, 'COL_LINK') and k in model.COL_LINK: value = link_ext_template.format(value, value) res[k] = value - if full == 'shortcut' and 'cached_label' in res: - res['value'] = res.pop('cached_label') + if full == 'shortcut': + if 'cached_label' in res: + res['value'] = res.pop('cached_label') + elif 'name' in res: + res['value'] = res.pop('name') rows.append(res) if full == 'shortcut': data = json.dumps(rows) |