Skip to content

Commit

Permalink
Merge pull request #241 from oarepo/miroslavsimek/be-494-refactor-cus…
Browse files Browse the repository at this point in the history
…tom-fields-to-uiresource-component

Refactored custom fields handling to a component
  • Loading branch information
Alzpeta authored Oct 21, 2024
2 parents db8c927 + 7d6da06 commit 46871f2
Show file tree
Hide file tree
Showing 15 changed files with 101 additions and 43 deletions.
2 changes: 2 additions & 0 deletions oarepo_ui/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@
"RecordsUIResource",
"UIResourceConfig",
"RecordsUIResourceConfig",
"PermissionsComponent",
"BabelComponent"
)
8 changes: 4 additions & 4 deletions oarepo_ui/resources/components/__init__.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
from .base import UIResourceComponent
from .babel import BabelComponent
from .base import UIResourceComponent
from .bleach import AllowedHtmlTagsComponent
from .communities import AllowedCommunitiesComponent
from .files import FilesComponent
from .permissions import PermissionsComponent
from .communities import AllowedCommunitiesComponent

__all__ = (
"UIResourceComponent",
"PermissionsComponent",
"AllowedHtmlTagsComponent",
"BabelComponent",
"FilesComponent",
"AllowedCommunitiesComponent"
)
"AllowedCommunitiesComponent",
)
2 changes: 1 addition & 1 deletion oarepo_ui/resources/components/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Dict, TYPE_CHECKING
from typing import TYPE_CHECKING, Dict

from flask_principal import Identity
from invenio_records_resources.services.records.results import RecordItem
Expand Down
2 changes: 1 addition & 1 deletion oarepo_ui/resources/components/bleach.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from flask import current_app
from invenio_config.default import ALLOWED_HTML_TAGS, ALLOWED_HTML_ATTRS
from invenio_config.default import ALLOWED_HTML_ATTRS, ALLOWED_HTML_TAGS

from .base import UIResourceComponent

Expand Down
7 changes: 2 additions & 5 deletions oarepo_ui/resources/components/communities.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@

from flask_principal import Identity
from invenio_communities.communities.records.api import Community
from invenio_records_resources.services.errors import PermissionDeniedError
from oarepo_runtime.i18n import lazy_gettext as _


from .base import UIResourceComponent
from invenio_records_resources.services.errors import (
PermissionDeniedError,
)


class AllowedCommunitiesComponent(UIResourceComponent):
Expand Down Expand Up @@ -105,8 +102,8 @@ def user_has_permission(self, identity, community, action):
)

def check_user_permissions(self, community_id, workflow, identity, action):
from oarepo_workflows.proxies import current_oarepo_workflows
from oarepo_workflows.errors import InvalidWorkflowError
from oarepo_workflows.proxies import current_oarepo_workflows

if workflow not in current_oarepo_workflows.record_workflows:
raise InvalidWorkflowError(
Expand Down
35 changes: 35 additions & 0 deletions oarepo_ui/resources/components/custom_fields.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from typing import Dict

from flask_principal import Identity
from invenio_records_resources.services.records.results import RecordItem

from oarepo_ui.resources.components import UIResourceComponent


class CustomFieldsComponent(UIResourceComponent):
def form_config(
self,
*,
api_record: RecordItem = None,
record: Dict = None,
data: Dict = None,
identity: Identity,
form_config: Dict,
args: Dict,
view_args: Dict,
ui_links: Dict = None,
extra_context: Dict = None,
**kwargs,
):
if hasattr(self.resource.config, "custom_fields"):
form_config["custom_fields"] = self.resource.config.custom_fields(
identity=identity,
api_record=api_record,
record=record,
data=data,
form_config=form_config,
args=args,
view_args=view_args,
ui_links=ui_links,
extra_context=extra_context,
)
2 changes: 1 addition & 1 deletion oarepo_ui/resources/components/permissions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .base import UIResourceComponent
from ...proxies import current_oarepo_ui
from .base import UIResourceComponent


class PermissionsComponent(UIResourceComponent):
Expand Down
50 changes: 31 additions & 19 deletions oarepo_ui/resources/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from typing import TYPE_CHECKING, Iterator

import deepmerge
from flask import abort, g, redirect, request, Response
from flask import Response, abort, g, redirect, request
from flask_principal import PermissionDenied
from flask_resources import (
Resource,
Expand All @@ -30,14 +30,17 @@
from werkzeug.exceptions import Forbidden

from oarepo_ui.utils import dump_empty
from .signposting import response_header_signposting

from .components.custom_fields import CustomFieldsComponent
from .signposting import response_header_signposting
from .templating.data import FieldData

if TYPE_CHECKING:
from .components import UIResourceComponent

#
import logging

# Resource
#
from ..proxies import current_oarepo_ui
Expand All @@ -48,6 +51,8 @@
UIResourceConfig,
)

log = logging.getLogger(__name__)

request_export_args = request_parser(
from_conf("request_export_args"), location="view_args"
)
Expand All @@ -64,10 +69,26 @@ class UIComponentsMixin:
#
# Pluggable components
#
config: UIResourceConfig

@property
def components(self) -> Iterator["UIResourceComponent"]:
"""Return initialized service components."""

# TODO: just for deprecation, will be removed later
for c in self.config.components or []:
if isinstance(c, CustomFieldsComponent):
break
else:
log.warning(
"CustomFieldsComponent not found in components, adding it to be backwards compatible."
)
if not self.config.components:
self.config.components = []
if isinstance(self.config.components, tuple):
self.config.components = list(self.config.components)
self.config.components.append(CustomFieldsComponent)

return (c(self) for c in self.config.components or [])

def run_components(self, action, *args, **kwargs):
Expand Down Expand Up @@ -240,9 +261,6 @@ def _detail(self, *, is_preview=False):
args=resource_requestctx.args,
view_args=resource_requestctx.view_args,
ui_links=ui_links,
custom_fields=self._get_custom_fields(
api_record=api_record, resource_requestctx=resource_requestctx
),
is_preview=is_preview,
)

Expand All @@ -260,10 +278,14 @@ def _detail(self, *, is_preview=False):
"is_preview": is_preview,
}

response = Response(current_oarepo_ui.catalog.render(
render_method,
**render_kwargs,
), mimetype="text/html", status=200)
response = Response(
current_oarepo_ui.catalog.render(
render_method,
**render_kwargs,
),
mimetype="text/html",
status=200,
)
response._api_record = api_record
return response

Expand Down Expand Up @@ -464,10 +486,6 @@ def edit(self):
g.identity, updateUrl=api_record.links.get("self", None)
)

form_config["custom_fields"] = self._get_custom_fields(
api_record=api_record, resource_requestctx=resource_requestctx
)

form_config["ui_model"] = self.ui_model

ui_links = self.expand_detail_links(identity=g.identity, record=api_record)
Expand Down Expand Up @@ -521,9 +539,6 @@ def edit(self):
d=FieldData(record, self.ui_model),
)

def _get_custom_fields(self, **kwargs):
return self.config.custom_fields(identity=g.identity, **kwargs)

def _get_form_config(self, identity, **kwargs):
return self.config.form_config(identity=identity, **kwargs)

Expand All @@ -541,9 +556,6 @@ def create(self):
form_config = self._get_form_config(
g.identity, createUrl=f"/api{self.api_service.config.url_prefix}"
)
form_config["custom_fields"] = self._get_custom_fields(
resource_requestctx=resource_requestctx
)

form_config["ui_model"] = self.ui_model

Expand Down
2 changes: 1 addition & 1 deletion oarepo_ui/resources/signposting.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def inner(*args, **kwargs):
if not hasattr(response, "_api_record"):
return response

signposting_link = response._api_record.links['self']
signposting_link = response._api_record.links["self"]
response.headers.update(
{
"Link": f'<{signposting_link}> ; rel="linkset" ; type="application/linkset+json"', # noqa
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = oarepo-ui
version = 5.2.14
version = 5.2.15
description = UI module for invenio 3.5+
long_description = file: README.md
long_description_content_type = text/markdown
Expand Down
12 changes: 6 additions & 6 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ def extra_entry_points():
def app_config(app_config):
app_config["I18N_LANGUAGES"] = [("cs", "Czech")]
app_config["BABEL_DEFAULT_LOCALE"] = "en"
app_config[
"RECORDS_REFRESOLVER_CLS"
] = "invenio_records.resolver.InvenioRefResolver"
app_config[
"RECORDS_REFRESOLVER_STORE"
] = "invenio_jsonschemas.proxies.current_refresolver_store"
app_config["RECORDS_REFRESOLVER_CLS"] = (
"invenio_records.resolver.InvenioRefResolver"
)
app_config["RECORDS_REFRESOLVER_STORE"] = (
"invenio_jsonschemas.proxies.current_refresolver_store"
)

# for ui tests
app_config["APP_THEME"] = ["semantic-ui"]
Expand Down
3 changes: 2 additions & 1 deletion tests/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@

from oarepo_ui.resources import (
BabelComponent,
PermissionsComponent,
RecordsUIResource,
RecordsUIResourceConfig, PermissionsComponent,
RecordsUIResourceConfig,
)
from oarepo_ui.resources.components.bleach import AllowedHtmlTagsComponent
from oarepo_ui.resources.config import TemplatePageUIResourceConfig
Expand Down
3 changes: 2 additions & 1 deletion tests/test_create.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
from invenio_config.default import ALLOWED_HTML_TAGS, ALLOWED_HTML_ATTRS

from invenio_config.default import ALLOWED_HTML_ATTRS, ALLOWED_HTML_TAGS


def test_create(
Expand Down
3 changes: 2 additions & 1 deletion tests/test_edit.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
from invenio_config.default import ALLOWED_HTML_TAGS, ALLOWED_HTML_ATTRS

from invenio_config.default import ALLOWED_HTML_ATTRS, ALLOWED_HTML_TAGS


def test_edit(
Expand Down
11 changes: 10 additions & 1 deletion tests/test_ui_resource_config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from invenio_access.permissions import system_identity
from invenio_config.default import ALLOWED_HTML_TAGS, ALLOWED_HTML_ATTRS
from invenio_config.default import ALLOWED_HTML_ATTRS, ALLOWED_HTML_TAGS


def test_ui_resource_form_config(app, test_record_ui_resource):
Expand Down Expand Up @@ -52,4 +52,13 @@ def test_ui_resource_form_config(app, test_record_ui_resource):
"can_update_files": False,
"can_view": False,
},
custom_fields={
"ui": [
{"fields": [{"field": "bbb", "ui_widget": "Input"}], "section": "B"},
{
"fields": [{"field": "nested_cf.aaa", "ui_widget": "Input"}],
"section": "A",
},
]
},
)

0 comments on commit 46871f2

Please sign in to comment.