Skip to content

Commit

Permalink
feat: introduce dynamicComponents loader
Browse files Browse the repository at this point in the history
  • Loading branch information
mirekys committed Feb 29, 2024
1 parent 320da39 commit 604206e
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 13 deletions.
9 changes: 3 additions & 6 deletions oarepo_ui/resources/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,8 @@ class RecordsUIResourceConfig(UIResourceConfig):
api_service = None
"""Name of the API service as registered inside the service registry"""

search_app_id = None
"""Namespace of the app used for rendering the search ui"""

form_app_id = None
"""Namespace of the app used for rendering forms"""
application_id = 'Default'
"""Namespace of the React app components related to this resource."""

templates = {
"detail": None,
Expand Down Expand Up @@ -185,6 +182,6 @@ def form_config(self, identity=None, **kwargs):

return dict(
custom_fields=self.custom_fields,
overridableIdPrefix = f"{self.form_app_id or 'Default'}.Form",
overridableIdPrefix = f"{self.application_id.capitalize()}.Form",
**kwargs,
)
4 changes: 2 additions & 2 deletions oarepo_ui/resources/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ def search(self):
g.identity, pagination, resource_requestctx.args
)

overridable_id_prefix = f"{self.config.search_app_id or 'Default'}.Search"
overridable_id_prefix = f"{self.config.application_id.capitalize()}.Search"

defaultComponents = {}
if hasattr(self.config, 'search_app_result_item') and self.config.search_app_result_item:
Expand Down Expand Up @@ -257,7 +257,7 @@ def search(self):

search_config = partial(self.config.search_app_config, **search_options)

search_app_config = search_config(app_id=self.config.search_app_id)
search_app_config = search_config(app_id=self.config.application_id.capitalize())

return current_oarepo_ui.catalog.render(
self.get_jinjax_macro(
Expand Down
4 changes: 2 additions & 2 deletions oarepo_ui/theme/assets/semantic-ui/js/oarepo_ui/forms/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ export function createFormAppInit({
<Router>
<OverridableContext.Provider value={overrideStore.getAll()}>
<FormConfigProvider value={config}>
<Overridable id={`${overridableIdPrefix}.FormApp.layout`}>
<Overridable id={`${overridableIdPrefix}.layout`}>
<Container fluid>
<p>
Provide your form components here by overriding
component id "FormApp.layout"
component id "{`${overridableIdPrefix}.layout`}"
</p>
</Container>
</Overridable>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export const overridableComponentIds = [
"ActiveFilters.element",
"AutocompleteSearchBar.element",
"BucketAggregation.element",
"BucketAggregationContainer.element",
"Count.Element",
"Error.element",
"Pagination.element",
"ResultsGrid.container",
"ResultsGrid.item",
"ResultsList.container",
"ResultsList.item",
"ResultsLoader.element",
"ResultsMultiLayout.element",
"ResultsPerPage.element",
"SearchApp.facets",
"SearchApp.layout",
"SearchApp.resultOptions",
"SearchApp.results",
"SearchApp.resultsPane",
"SearchApp.searchbar",
"SearchBar.element",
"SearchFilters.Toggle.element",
"SearchHelpLinks",
"Sort.element",
"SortBy.element",
"SortOrder.element",
];
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React from "react";
import { SearchApp } from "@js/invenio_search_ui/components";
import { loadComponents } from "@js/invenio_theme/templates";
import _camelCase from "lodash/camelCase";
import ReactDOM from "react-dom";
import { parametrize } from "react-overridable";
import { overridableComponentIds } from "./constants";
import { dynamicLoadComponents } from "../util";
import { loadComponents } from "@js/invenio_theme/templates";

import {
ActiveFiltersElement,
Expand Down Expand Up @@ -71,8 +73,11 @@ export function createSearchAppsInit({
...internalComponentDefaults,
...config.defaultComponents,
...defaultComponentOverrides,
...dynamicLoadComponents(overridableIdPrefix, overridableComponentIds),
};

console.log({components})

loadComponents(overridableIdPrefix, components).then((res) => {
ReactDOM.render(
<ContainerComponent>
Expand Down
35 changes: 35 additions & 0 deletions oarepo_ui/theme/assets/semantic-ui/js/oarepo_ui/util.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import _map from "lodash/map";
import _reduce from "lodash/reduce";
import _capitalize from "lodash/capitalize";
import { importTemplate } from "@js/invenio_theme/templates";

export const getInputFromDOM = (elementName) => {
const element = document.getElementsByName(elementName);
Expand Down Expand Up @@ -48,4 +50,37 @@ export const absoluteUrl = (urlString) => {
export const relativeUrl = (urlString) => {
const {pathname, search} = absoluteUrl(urlString)
return `${pathname}${search}`
}

export async function dynamicLoadComponents(overridableIdPrefix, componentIds) {
const asyncImportTemplate = async (componentId, path) => {
console.log(`Searching for component '${componentId}' in ${path}`)
try {
return {
componentId,
component: await importTemplate(path),
};
} catch (err) {
return null;
}
};

const components = componentIds.map((componentId) => {
const componentFilename = componentId
.split(".")
.map((part) => _capitalize(part))
.join("");
return asyncImportTemplate(
`${overridableIdPrefix}.${componentId}`,
`${overridableIdPrefix}/${componentFilename}.jsx`
);
});

const loadedComponents = await Promise.all(components);
return loadedComponents
.filter((component) => component !== null)
.reduce((res, { componentId, component }) => {
res[componentId] = component;
return res;
}, {});
}
3 changes: 1 addition & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,7 @@ def record_ui_resource(app, record_ui_resource_config, record_service):
@pytest.fixture(scope="module")
def test_record_ui_resource_config():
config = ModelUIResourceConfig()
config.search_app_id = 'Test'
config.form_app_id = 'Test'
config.application_id = 'Test'
return config


Expand Down

0 comments on commit 604206e

Please sign in to comment.