From 2c6d374e7e50b94045bf67ef196bb188afb71c4d Mon Sep 17 00:00:00 2001 From: Alicia Zangger Date: Fri, 6 Nov 2020 13:53:24 +0100 Subject: [PATCH] issue: fix the translation of the patron profile link * Fixes the translation of the patron profile link in menu by loading the menu at each app request, not only the first time. * Adds the 'request denied' message to the string to translate. * Adds note types (label AND value) to the string to translate. * Closes #1367. * Closes #1319. Co-Authored-by: Alicia Zangger --- .../jsonschemas/holdings/holding-v0.0.1.json | 16 ++-- rero_ils/modules/locations/api.py | 2 +- rero_ils/modules/patrons/views.py | 86 ++++++++++++++++++- 3 files changed, 93 insertions(+), 11 deletions(-) diff --git a/rero_ils/modules/holdings/jsonschemas/holdings/holding-v0.0.1.json b/rero_ils/modules/holdings/jsonschemas/holdings/holding-v0.0.1.json index dd61fa18df..050ec1751a 100644 --- a/rero_ils/modules/holdings/jsonschemas/holdings/holding-v0.0.1.json +++ b/rero_ils/modules/holdings/jsonschemas/holdings/holding-v0.0.1.json @@ -484,35 +484,35 @@ ], "options": [ { - "label": "general note", + "label": "general_note", "value": "general_note" }, { - "label": "staff note", + "label": "staff_note", "value": "staff_note" }, { - "label": "conservation note", + "label": "conservation_note", "value": "conservation_note" }, { - "label": "reception note", + "label": "reception_note", "value": "reception_note" }, { - "label": "claim note", + "label": "claim_note", "value": "claim_note" }, { - "label": "routing note", + "label": "routing_note", "value": "routing_note" }, { - "label": "binding note", + "label": "binding_note", "value": "binding_note" }, { - "label": "acquisition note", + "label": "acquisition_note", "value": "acquisition_note" } ], diff --git a/rero_ils/modules/locations/api.py b/rero_ils/modules/locations/api.py index 106438fbdc..54beae5a30 100644 --- a/rero_ils/modules/locations/api.py +++ b/rero_ils/modules/locations/api.py @@ -163,7 +163,7 @@ def allow_request(cls, item, **kwargs): :return a tuple with True|False and reasons to disallow if False. """ if item and not item.get_location().get('allow_request', False): - return False, ["Item location disallows request."] + return False, [_('Item location disallows request.')] return True, [] def transaction_location_validator(self, location_pid): diff --git a/rero_ils/modules/patrons/views.py b/rero_ils/modules/patrons/views.py index 8e4c0e01be..02aee63f67 100644 --- a/rero_ils/modules/patrons/views.py +++ b/rero_ils/modules/patrons/views.py @@ -19,8 +19,10 @@ from __future__ import absolute_import, print_function +import inspect import re from functools import wraps +from werkzeug.local import LocalProxy from elasticsearch_dsl import Q from flask import Blueprint, abort, current_app, flash, jsonify, \ @@ -28,8 +30,9 @@ from flask_babelex import format_currency from flask_babelex import gettext as _ from flask_login import current_user, login_required -from flask_menu import register_menu +from flask_menu import register_menu, Menu from invenio_i18n.ext import current_i18n +from six import PY3 from werkzeug.exceptions import NotFound from werkzeug.utils import redirect @@ -71,6 +74,81 @@ def is_logged_librarian(*args, **kwargs): return is_logged_librarian +def register_menu_before_app_request(app, path, text, order=0, + endpoint_arguments_constructor=None, + dynamic_list_constructor=None, + active_when=None, + visible_when=None, + **kwargs): + """Decorate endpoints that should be displayed in a menu. + Example:: + @register_menu(app, '.', _('Home')) + def index(): + pass + :param app: Application or Blueprint which owns the + function view. + :param path: Path to this item in menu hierarchy, + for example 'main.category.item'. Path can be an object + with custom __str__ method: it will be converted on first request, + therefore you can use current_app inside this __str__ method. + :param text: Text displayed as link. + :param order: Index of item among other items in the same menu. + :param endpoint_arguments_constructor: Function returning dict of + arguments passed to url_for when creating the link. + :param active_when: Function returning True when the item + should be displayed as active. + :param visible_when: Function returning True when this item + should be displayed. + :param dynamic_list_constructor: Function returning a list of + entries to be displayed by this item. Every object should + have 'text' and 'url' properties/dict elements. This property + will not be directly affect the menu system, but allows + other systems to use it while rendering. + :param kwargs: Additional arguments will be available as attributes + on registered :class:`MenuEntryMixin` instance. + .. versionchanged:: 0.2.0 + The *kwargs* arguments. + """ + def menu_decorator(f): + """Decorator of a view function that should be included in the menu.""" + if isinstance(app, Blueprint): + endpoint = app.name + '.' + f.__name__ + before_first_request = app.before_app_first_request + else: + endpoint = f.__name__ + before_first_request = app.before_first_request + + expected = inspect.getfullargspec(f).args if PY3 else \ + inspect.getargspec(f).args + + @blueprint.before_app_request + def _register_menu_item(): + # str(path) allows path to be a string-convertible object + # that may be useful for delayed evaluation of path + item = current_menu.submenu(str(path)) + # Check which option in kwargs already exists in `item`. + to_delete = [] + for option in kwargs.keys(): + if hasattr(item, option): + to_delete.append(option) + # Delete all existing options in kwargs + for element in to_delete: + del kwargs[element] + item.register( + endpoint, + text, + order, + endpoint_arguments_constructor=endpoint_arguments_constructor, + dynamic_list_constructor=dynamic_list_constructor, + active_when=active_when, + visible_when=visible_when, + expected_args=expected, + **kwargs) + return f + + return menu_decorator + + @api_blueprint.route('/count/', methods=['GET']) @check_permission def number_of_patrons(): @@ -163,7 +241,7 @@ def logged_user(): methods=['GET', 'POST']) @blueprint.route('//patrons/profile') @login_required -@register_menu( +@register_menu_before_app_request( blueprint, 'main.profile.patron_profile', _('%(icon)s Profile', icon=''), @@ -299,3 +377,7 @@ def get_patron_from_pid(patron_pid): def get_location_name_from_pid(location_pid): """Get location from pid.""" return Location.get_record_by_pid(location_pid)['name'] + + +#: Global object that is proxy to the current application menu. +current_menu = LocalProxy(Menu.root)