Skip to content

Commit

Permalink
Merge pull request #127 from oarepo/mirekys-search-app-init
Browse files Browse the repository at this point in the history
feat(search): createSearchAppInit utility & dynamic result items
  • Loading branch information
mirekys authored Jan 26, 2024
2 parents ef0bcdc + c6e72b9 commit 48cc74e
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 7 deletions.
6 changes: 5 additions & 1 deletion oarepo_ui/resources/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,11 @@ def search(self):
search_options = dict(
api_config=self.api_service.config,
identity=g.identity,
overrides={"ui_endpoint": self.config.url_prefix, "ui_links": ui_links},
overrides={
"ui_endpoint": self.config.url_prefix,
"ui_links": ui_links,
"defaultComponents": {},
},
)

extra_context = dict()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from "react";
import _get from "lodash/get";
import Overridable, { overrideStore } from "react-overridable";
import { AppContext } from "react-searchkit";

export const FallbackItemComponent = ({ result }) => (
<div>
<h2>{result.id}</h2>
</div>
);

export const DynamicResultsListItem = ({
result,
selector = "$schema",
FallbackComponent = FallbackItemComponent,
}) => {
const { buildUID } = React.useContext(AppContext);
const selectorValue = _get(result, selector);

if (!selectorValue) {
console.warn("Result", result, `is missing value for '${selector}'.`);
return <FallbackComponent result={result} />;
}

return (
<Overridable
id={buildUID("ResultsList.item", selectorValue)}
result={result}
>
<FallbackComponent result={result} />
</Overridable>
);
};

export default DynamicResultsListItem;
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ export { SearchAppResults } from "./SearchAppResults";
export { EmptyResultsElement } from "./EmptyResultsElement";
export { ResultsPerPageLabel } from "./ResultsPerPageLabel";
export { ClearFiltersButton } from "./ClearFiltersButton";
export { DynamicResultsListItem } from "./DynamicResultsListItem"
export * from './util'
82 changes: 82 additions & 0 deletions oarepo_ui/theme/assets/semantic-ui/js/oarepo_ui/search/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
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 {
ActiveFiltersElement,
BucketAggregationElement,
BucketAggregationValuesElement,
CountElement,
EmptyResultsElement,
ErrorElement,
SearchAppFacets,
SearchAppLayout,
SearchAppResultOptions,
SearchAppSearchbarContainer,
SearchFiltersToggleElement,
SearchAppSort,
} from "@js/oarepo_ui/search";



export function createSearchAppInit ({
defaultComponentOverrides,
autoInit = true,
autoInitDataAttr = "invenio-search-config",
multi = true,
ContainerComponent = React.Fragment,
}) {
const initSearchApp = (rootElement) => {
const { appId, ...config } = JSON.parse(
rootElement.dataset[_camelCase(autoInitDataAttr)]
);

const componentPrefix = multi ? `${appId}.` : ''
const SearchAppSearchbarContainerWithConfig = parametrize(SearchAppSearchbarContainer, { appName: appId })
const internalComponentDefaults = {
[`${componentPrefix}ActiveFilters.element`]: ActiveFiltersElement,
[`${componentPrefix}BucketAggregation.element`]: BucketAggregationElement,
[`${componentPrefix}BucketAggregationValues.element`]: BucketAggregationValuesElement,
[`${componentPrefix}Count.element`]: CountElement,
[`${componentPrefix}EmptyResults.element`]: EmptyResultsElement,
[`${componentPrefix}Error.element`]: ErrorElement,
[`${componentPrefix}SearchApp.facets`]: SearchAppFacets,
[`${componentPrefix}SearchApp.layout`]: SearchAppLayout,
[`${componentPrefix}SearchApp.resultOptions`]: SearchAppResultOptions,
[`${componentPrefix}SearchApp.searchbarContainer`]: SearchAppSearchbarContainerWithConfig,
[`${componentPrefix}SearchFilters.Toggle.element`]: SearchFiltersToggleElement,
[`${componentPrefix}SearchApp.sort`]: SearchAppSort,
};

loadComponents(appId, {
...internalComponentDefaults,
...config.defaultComponents,
...defaultComponentOverrides,
}).then((res) => {
ReactDOM.render(
<ContainerComponent>
<SearchApp
config={config}
// Use appName to namespace application components when overriding
{...(multi && { appName: appId })}
/>
</ContainerComponent>,
rootElement
);
});
};

if (autoInit) {
const searchAppElements = document.querySelectorAll(
`[data-${autoInitDataAttr}]`
);
for (const appRootElement of searchAppElements) {
initSearchApp(appRootElement);
}
} else {
return initSearchApp;
}
}
4 changes: 1 addition & 3 deletions oarepo_ui/theme/webpack.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,7 @@
"oarepo_ui_components": "./js/oarepo_ui/custom-components.js",
},
dependencies=dependencies,
devDependencies={
"eslint-plugin-i18next":"^6.0.3"
},
devDependencies={"eslint-plugin-i18next": "^6.0.3"},
aliases={
**aliases,
"@translations/oarepo_ui": "translations/oarepo_ui",
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.0.100
version = 5.0.101
description = UI module for invenio 3.5+
long_description = file: README.md
long_description_content_type = text/markdown
Expand Down
5 changes: 3 additions & 2 deletions tests/templates/TestSearch.jinja
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{#def extra_context, ui_links #}
{#def extra_context, ui_links, search_app_config #}
{
"ui_links": {{ ui_links|tojson|safe }},
"permissions": {{ extra_context.permissions|tojson|safe }},
"dummy_filter": {{ 1|dummy|tojson|safe }}
"dummy_filter": {{ 1|dummy|tojson|safe }},
"search_config": {{ search_app_config|tojson|safe }}
}


11 changes: 11 additions & 0 deletions tests/test_search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import json


def test_default_components(
app, record_ui_resource, simple_record, client_with_credentials, fake_manifest
):
with client_with_credentials.get(f"/simple-model/") as c:
txt = json.loads(c.text)
search_config = txt["search_config"]

assert search_config['defaultComponents'] == {}

0 comments on commit 48cc74e

Please sign in to comment.