diff --git a/invenio_vocabularies/administration/views/vocabularies.py b/invenio_vocabularies/administration/views/vocabularies.py index 81304dc7..9af9ca88 100644 --- a/invenio_vocabularies/administration/views/vocabularies.py +++ b/invenio_vocabularies/administration/views/vocabularies.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (C) 2020-2024 CERN. +# Copyright (C) 2020-2021 CERN. # Copyright (C) 2024 Uni Münster. # # Invenio-Vocabularies is free software; you can redistribute it and/or @@ -8,10 +8,11 @@ # details. """Vocabularies admin interface.""" -from invenio_administration.views.base import ( - AdminResourceEditView, - AdminResourceListView, -) +from functools import partial + +from flask import current_app +from invenio_administration.views.base import AdminResourceListView +from invenio_search_ui.searchconfig import FacetsConfig, SortConfig, search_app_config class VocabulariesListView(AdminResourceListView): @@ -42,3 +43,95 @@ class VocabulariesListView(AdminResourceListView): search_config_name = "VOCABULARIES_TYPES_SEARCH" search_facets_config_name = "VOCABULARIES_TYPES_FACETS" search_sort_config_name = "VOCABULARIES_TYPES_SORT_OPTIONS" + + +class VocabularyDetailsListView(AdminResourceListView): + """Configuration for vocabularies list view.""" + + def get_api_endpoint(self, pid_value=None): + """Overwrite get_api_endpoint to accept pid_value.""" + if pid_value in current_app.config.get( + "VOCABULARIES_CUSTOM_VOCABULARY_TYPES", [] + ): + return f"/api/{pid_value}" + else: + return f"/api/vocabularies/{pid_value}" + + def init_search_config(self, **kwargs): + """Build search view config.""" + pid_value = kwargs.get("pid_value", "") + custom_search_config = current_app.config[self.search_config_name].get( + pid_value + ) + + if custom_search_config: + available_sort_options = current_app.config[self.search_sort_config_name] + available_facets = current_app.config.get(self.search_facets_config_name) + + return partial( + search_app_config, + config_name=self.get_search_app_name(**kwargs), + available_facets=available_facets, + sort_options=available_sort_options, + endpoint=self.get_api_endpoint(**kwargs), + headers=self.get_search_request_headers(**kwargs), + sort=SortConfig( + available_sort_options, + custom_search_config["sort"], + custom_search_config["sort_default"], + custom_search_config["sort_default_no_query"], + ), + facets=FacetsConfig(available_facets, custom_search_config["facets"]), + ) + else: + return super().init_search_config(**kwargs) + + def get(self, **kwargs): + """GET view method.""" + parent_context = super().get_context(**kwargs) + + pid_value = kwargs.get("pid_value", "") + vocab_admin_cfg = current_app.config["VOCABULARIES_ADMINISTRATION_CONFIG"] + + custom_config = vocab_admin_cfg.get(pid_value) + + if custom_config: + parent_context.update(custom_config) + else: + parent_context.update( + {"title": f"{pid_value.capitalize()} vocabulary items"} + ) + + return self.render(**parent_context) + + name = "vocabulary-type-items" + url = "/vocabulary-types/" + + # INFO name of the resource's list view name, enables navigation between items view and types view. + list_view_name = "vocabulary-types" + + resource_config = "vocabulary_admin_resource" + search_request_headers = {"Accept": "application/json"} + + pid_path = "id" + resource_name = "title['en']" + + # INFO only if disabled() (as a function) it's not in the sidebar, see https://github.com/inveniosoftware/invenio-administration/blob/main/invenio_administration/menu/menu.py#L54 + disabled = lambda _: True + + template = "invenio_administration/search.html" + + display_delete = False + display_create = False + display_edit = True + display_search = True + + # TODO: It would ne nicer to use the title's translation in the currently selected language and fall back to English if this doesn't exist + item_field_list = { + "title['en']": {"text": "Title [en]", "order": 0}, + "created": {"text": "Created", "order": 1}, + } + + search_config_name = "VOCABULARIES_TYPES_ITEMS_SEARCH" + search_facets_config_name = "VOCABULARIES_TYPES_ITEMS_FACETS" + search_sort_config_name = "VOCABULARIES_TYPES_ITEMS_SORT_OPTIONS" diff --git a/invenio_vocabularies/config.py b/invenio_vocabularies/config.py index 27ac282d..dad012e4 100644 --- a/invenio_vocabularies/config.py +++ b/invenio_vocabularies/config.py @@ -154,3 +154,130 @@ "sort": ["name", "count"], } """Vocabulary type search configuration.""" + +VOCABULARIES_TYPES_ITEMS_SORT_OPTIONS = { + "name": dict( + title=_("Name"), + fields=["id"], + ), + "title": dict( + title=_("Title"), + fields=["title"], + ), + "subject": dict( + title=_("Subject"), + fields=["subject"], + ), +} +"""Definitions of available Vocabulary type items sort options. """ + +VOCABULARIES_TYPES_ITEMS_SEARCH = { + "affiliations": { + "facets": [], + "sort": ["name"], + "sort_default": "name", + "sort_default_no_query": "name", + }, + "awards": { + "facets": [], + "sort": ["name"], + "sort_default": "name", + "sort_default_no_query": "name", + }, + "funders": { + "facets": [], + "sort": ["name"], + "sort_default": "name", + "sort_default_no_query": "name", + }, + "names": { + "facets": [], + "sort": ["name"], + "sort_default": "name", + "sort_default_no_query": "name", + }, + "subjects": { + "facets": [], + "sort": ["subject"], + "sort_default": "subject", + "sort_default_no_query": "subject", + }, + "facets": [], + "sort": ["title"], + "sort_default": "title", + "sort_default_no_query": "title", +} +"""Vocabulary type item search configurations per type and for generic vocabularies.""" + +VOCABULARIES_ADMINISTRATION_CONFIG = { + "affiliations": dict( + title="Affiliations vocabulary items", + fields={ + "name": {"text": "Name", "order": 0}, + "created": {"text": "Created", "order": 1}, + }, + display_search=True, + display_create=False, + display_delete=False, + display_edit=True, + display_read=True, + pid_path="id", + resource_name="name", + ), + "awards": dict( + title="Awards vocabulary items", + fields={ + "name": {"text": "Name", "order": 0}, + "created": {"text": "Created", "order": 1}, + }, + display_search=True, + display_create=False, + display_delete=False, + display_edit=True, + display_read=True, + pid_path="id", + resource_name="name", + ), + "funders": dict( + title="Funders vocabulary items", + fields={ + "name": {"text": "Name", "order": 0}, + "created": {"text": "Created", "order": 1}, + }, + display_search=True, + display_create=False, + display_delete=False, + display_edit=True, + display_read=True, + pid_path="id", + resource_name="name", + ), + "names": dict( + title="Names vocabulary items", + fields={ + "name": {"text": "Name", "order": 0}, + "created": {"text": "Created", "order": 1}, + }, + display_search=True, + display_create=False, + display_delete=False, + display_edit=True, + display_read=True, + pid_path="id", + resource_name="name", + ), + "subjects": dict( + title="Subjects vocabulary items", + fields={ + "subject": {"text": "Subject", "order": 0}, + "created": {"text": "Created", "order": 1}, + }, + display_search=True, + display_create=False, + display_delete=False, + display_edit=True, + display_read=True, + pid_path="id", + resource_name="subject", + ), +} diff --git a/invenio_vocabularies/services/config.py b/invenio_vocabularies/services/config.py index e4fba25a..e43ca1ad 100644 --- a/invenio_vocabularies/services/config.py +++ b/invenio_vocabularies/services/config.py @@ -96,6 +96,10 @@ class VocabularyTypeSearchOptions(SearchOptions): title=_("ID"), fields=["id"], ), + "count": dict( + title=_("Number of entries"), + fields=["count"], + ), } sort_default = "id" diff --git a/invenio_vocabularies/services/results.py b/invenio_vocabularies/services/results.py index 877270ea..5d0d4c04 100644 --- a/invenio_vocabularies/services/results.py +++ b/invenio_vocabularies/services/results.py @@ -92,9 +92,8 @@ def _custom_vocabulary_statistics(self): def _generic_vocabulary_statistics(self): # Opensearch query for generic vocabularies - config: RecordServiceConfig = ( - current_service.config - ) # TODO: Where to get the config from here? current_service is None + config: RecordServiceConfig = current_service.config + search_opts = config.search search = search_opts.search_cls( diff --git a/setup.cfg b/setup.cfg index eb426a95..95b9809f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -59,6 +59,7 @@ flask.commands = vocabularies = invenio_vocabularies.cli:vocabularies invenio_administration.views = vocabularies_list = invenio_vocabularies.administration.views.vocabularies:VocabulariesListView + vocabulary_types_details = invenio_vocabularies.administration.views.vocabularies:VocabularyDetailsListView invenio_base.apps = invenio_vocabularies = invenio_vocabularies:InvenioVocabularies invenio_base.api_apps =