Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vocabulary item view #347

Open
wants to merge 41 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
d77a180
register new route
karkraeg May 13, 2024
0b5aaaa
Implemented first Admin view based on mock API
karkraeg May 14, 2024
4d3365b
add copyright
karkraeg May 14, 2024
f7404c0
remove WIP import
karkraeg May 14, 2024
009be0a
remove more imports
karkraeg May 14, 2024
fb36717
provide API endpoint with aggregated counts for all types of vocabula…
karkraeg May 16, 2024
c0377de
add missing invenio-administration dependency
karkraeg May 17, 2024
dd1420d
Add and update docstrings
SarahW91 May 17, 2024
ebd3363
dirty commit, added resources
karkraeg May 22, 2024
9bf7e2a
fix imports and cleanup
karkraeg May 22, 2024
ff50270
cleanup
karkraeg May 23, 2024
8965685
overwrite api endpoint
karkraeg May 23, 2024
f405b4b
Fixes after review. Take out additional list view for now until it is…
SarahW91 May 24, 2024
3601b15
Fixed formatting and doc strings.
SarahW91 May 24, 2024
b2a3c93
Fixed formatting
SarahW91 May 24, 2024
0fc61ae
vocabulary types: Implement query functionality
SarahW91 May 28, 2024
43f25da
vocabulary types: Show count in list view
SarahW91 May 28, 2024
9de7fd2
vocabulary types: Implement sorting
SarahW91 May 28, 2024
a5e1f90
vocabulary type endpoint: fix formatting
SarahW91 Jun 13, 2024
78bec3d
vocabulary types endpoint: split implementation for service, config a…
SarahW91 Jun 13, 2024
fe43685
services: fix service proxy
karkraeg Jun 14, 2024
edfdf53
vocabulary types administration: Fix sidebar menu name and remove cre…
SarahW91 Jun 17, 2024
22f7835
vocabulary types administration: Add Uni Münster copyright notice.
SarahW91 Jun 17, 2024
5657042
vocabulary types administration tests: Use correct service for tests
SarahW91 Jun 17, 2024
2555b8e
Merge branch 'master' into all_vocabularies_endpoint
SarahW91 Jun 19, 2024
842f5c3
vocabulary types: cleanup
SarahW91 Jun 24, 2024
6c79b8b
vocabulary types items: add vocabulary items list view
SarahW91 Jun 25, 2024
ba10dcb
vocabulary types items: account for different sort options on differe…
SarahW91 Jun 25, 2024
b0a4bb7
vocabulary types items: add display fields for items
SarahW91 Jun 25, 2024
f210d7c
vocabulary types items: add subject column
SarahW91 Jun 25, 2024
9056ac3
Merge branch 'inveniosoftware:master' into vocabulary_item_view
SarahW91 Jun 26, 2024
1cbf807
Capitalize vocabulary type name in items view
SarahW91 Jun 25, 2024
8cf3e43
vocabulary item list view: Fixed formatting and pydocstyle
SarahW91 Jun 26, 2024
99f299d
vocabulary types: remove schema property from VocabularyTypeService
SarahW91 Jun 25, 2024
7475321
vocabulary types: remove unused read response handler from Vocabulari…
SarahW91 Jun 25, 2024
9d4ccbb
vocabulary types: rename route and response handler of VocabulariesAd…
SarahW91 Jun 25, 2024
9a2a0d7
vocabulary item list view: Avoid code duplication by overwriting get …
SarahW91 Jul 4, 2024
c9f79e8
vocabulary item list view: make view ui customizable via config.py
SarahW91 Jul 16, 2024
75240e9
vocabulary item list view: add resource name to config
SarahW91 Jul 16, 2024
8147305
Merge branch 'master' into vocabulary_item_view
SarahW91 Jul 16, 2024
f6ba1dc
formatting: run isort and black
SarahW91 Jul 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 98 additions & 5 deletions invenio_vocabularies/administration/views/vocabularies.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
# -*- 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
# modify it under the terms of the MIT License; see LICENSE file for more
# 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):
Expand Down Expand Up @@ -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):
Copy link
Contributor

@kpsherva kpsherva Jul 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you considered inheriting from both Details and List views?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not yet. Could you explain how that might help with our issues?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would ensure less ambiguity on where the methods are actually coming from, this class now only imitates the interface of AdminResourceDetails view in order to use some of its frontend functionalities, while it does not actually inherit from the class itself. It might create divergence on the implementation of these "virtually" inherited methods the code it will be harder to maintain.
So to answer your question, it does not solve immediate problems but prevents ambiguity in the future

"""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"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to suggest using class factory pattern here instead of moving it to a static dict config in the configuration variable. I understand the dict is imitating the AdminView class interface but if it is not really a class, then we diverge of the pattern of implementation of the administration module


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/<pid_value>"

# 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"
127 changes: 127 additions & 0 deletions invenio_vocabularies/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
),
}
4 changes: 4 additions & 0 deletions invenio_vocabularies/services/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ class VocabularyTypeSearchOptions(SearchOptions):
title=_("ID"),
fields=["id"],
),
"count": dict(
title=_("Number of entries"),
fields=["count"],
),
}

sort_default = "id"
Expand Down
5 changes: 2 additions & 3 deletions invenio_vocabularies/services/results.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down