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

global: react-searchkit integration #76

Merged
merged 12 commits into from
May 15, 2020
4 changes: 4 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
Changes
=======

Version 2.0.0a1 (released 2020-05-15)

- Adds React-Searchkit application for use with Semantic UI theme.

Version 1.2.0 (released 2020-03-13)

- Drops support for Python 2.7
Expand Down
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ recursive-include invenio_search_ui *.mo
recursive-include invenio_search_ui *.po
recursive-include invenio_search_ui *.pot
recursive-include invenio_search_ui *.scss
recursive-include tests *.html
recursive-include tests *.py
prune examples/static/node_modules
5 changes: 0 additions & 5 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ API Docs
.. automodule:: invenio_search_ui.ext
:members:

Bundles
-------

.. automodule:: invenio_search_ui.bundles
:members:

Views
-----
Expand Down
3 changes: 0 additions & 3 deletions invenio_search_ui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,7 @@
.. code-block:: python

from invenio_assets import InvenioAssets
from invenio_search_ui.bundles import js
ext_assets = InvenioAssets(app)
ext_assets.env.register('invenio_search_ui_search_js', js)
<NpmBundle ...>

Before we initialize the Invenio-Search-UI extension, we need to have some
REST API endpoints configured to expose our records. For more detailed
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* This file is part of Invenio.
* Copyright (C) 2020 CERN.
*
* Invenio is free software; you can redistribute it and/or modify it
* under the terms of the MIT License; see LICENSE file for more details.
*/

import PropTypes from "prop-types";
import React, { Component } from "react";
import {
Count,
LayoutSwitcher,
Pagination,
ResultsMultiLayout,
Sort,
} from "react-searchkit";
import { Grid } from "semantic-ui-react";

export class Results extends Component {
render() {
const { sortValues, currentResultsState } = this.props;
const { total } = currentResultsState.data;
return total ? (
<Grid relaxed>
<Grid.Row verticalAlign="middle">
<Grid.Column width={7}>
<Count label={(cmp) => <>{cmp} result(s) found</>} />
<br />
</Grid.Column>
<Grid.Column width={6} textAlign="right">
{sortValues && (
<Sort values={sortValues} label={(cmp) => <>sort by {cmp}</>} />
)}
</Grid.Column>
<Grid.Column width={3} textAlign="right">
<LayoutSwitcher defaultLayout="list" />
</Grid.Column>
</Grid.Row>
<Grid.Row>
<Grid.Column>
<ResultsMultiLayout />
</Grid.Column>
</Grid.Row>
<Grid.Row verticalAlign="middle" textAlign="center">
<Grid.Column>
<Pagination />
</Grid.Column>
</Grid.Row>
</Grid>
) : null;
}
}

Results.propTypes = {
sortValues: PropTypes.array,
};

Results.defaultProps = {
sortValues: [],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* This file is part of Invenio.
* Copyright (C) 2020 CERN.
*
* Invenio is free software; you can redistribute it and/or modify it
* under the terms of the MIT License; see LICENSE file for more details.
*/

import PropTypes from "prop-types";
import React, { Component } from "react";
import { OverridableContext, overrideStore } from "react-overridable";
import {
BucketAggregation,
EmptyResults,
Error,
InvenioSearchApi,
ReactSearchKit,
ResultsLoader,
withState,
} from "react-searchkit";
import { Container, Grid } from "semantic-ui-react";
import { Results } from "./Results";
import SearchBar from "./SearchBar";

const OnResults = withState(Results);

export class SearchApp extends Component {
render() {
const { appName, config } = this.props;
const searchApi = new InvenioSearchApi({
axios: {
url: config.api,
withCredentials: true,
},
headers: { Accept: config.mimetype },
});

return (
<OverridableContext.Provider value={overrideStore.getAll()}>
<ReactSearchKit searchApi={searchApi} appName={appName}>
<Container>
<Grid relaxed padded>
<Grid.Row>
<Grid.Column width={4} />
<Grid.Column width={12}>
<SearchBar />
</Grid.Column>
</Grid.Row>
</Grid>
<Grid relaxed padded>
<Grid.Row columns={2}>
<Grid.Column width={4}>
{config.aggs.map((agg) => (
<BucketAggregation
key={agg.title}
title={agg.title}
agg={{
field: agg.field,
aggName: agg.aggName,
}}
/>
))}
</Grid.Column>
<Grid.Column width={12}>
<ResultsLoader>
<EmptyResults />
<Error />
<OnResults sortValues={config.sort_options} />
</ResultsLoader>
</Grid.Column>
</Grid.Row>
</Grid>
</Container>
</ReactSearchKit>
</OverridableContext.Provider>
);
}
}

SearchApp.propTypes = {
config: PropTypes.shape({
api: PropTypes.string,
mimetype: PropTypes.string,
aggs: PropTypes.array,
sort_options: PropTypes.array,
}).isRequired,
appName: PropTypes.string,
};

SearchApp.defaultProps = {
config: {
api: "",
mimetype: "",
aggs: [],
sort_options: [],
},
appName: null,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* This file is part of Invenio.
* Copyright (C) 2020 CERN.
*
* Invenio is free software; you can redistribute it and/or modify it
* under the terms of the MIT License; see LICENSE file for more details.
*/

import _get from "lodash/get";
import _truncate from "lodash/truncate";
import React from "react";
import { overrideStore } from "react-overridable";
import { Card, Item, Label } from "semantic-ui-react";

const SearchUIResultsListItem = ({ result, index }) => {
const metadata = result.metadata;
return (
<Item key={index} href={_get(result, "links.html", "#")}>
<Item.Content>
<Item.Header>{metadata.title}</Item.Header>
<Item.Description>
{_truncate(
metadata.contributors
.map((contributor) => contributor.name)
.join("; "),
{ length: 200 }
)}
</Item.Description>
<Item.Extra>
{metadata.keywords.map((keyword, idx) => (
<Label key={idx}>{keyword}</Label>
))}
</Item.Extra>
</Item.Content>
</Item>
);
};

const SearchUIResultsGridItem = ({ result, index }) => {
const metadata = result.metadata;
return (
<Card fluid key={index} href={_get(result, "links.html", "#")}>
<Card.Content>
<Card.Header>{metadata.title}</Card.Header>
<Card.Description>
{_truncate(
metadata.contributors
.map((contributor) => contributor.name)
.join("; "),
{ length: 200 }
)}
</Card.Description>
</Card.Content>
<Card.Content extra>
{metadata.keywords.map((keyword, idx) => (
<Label key={idx}>{keyword}</Label>
))}
</Card.Content>
</Card>
);
};

overrideStore.add("ResultsList.item", SearchUIResultsListItem);
overrideStore.add("ResultsGrid.item", SearchUIResultsGridItem);
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* This file is part of Invenio.
* Copyright (C) 2020 CERN.
*
* Invenio is free software; you can redistribute it and/or modify it
* under the terms of the MIT License; see LICENSE file for more details.
*/

import React, { Component } from "react";
import { SearchBar as ReactSearchKitSearchBar } from "react-searchkit";
import ReactDOM from "react-dom";
import PropTypes from "prop-types";

export default class SearchBar extends Component {
render() {
const domElement = document.getElementById(this.props.elementId);
if (domElement) {
domElement.innerHTML = "";
return ReactDOM.createPortal(<ReactSearchKitSearchBar />, domElement);
}
return <ReactSearchKitSearchBar />;
}
}

SearchBar.propTypes = {
elementId: PropTypes.string,
};

SearchBar.defaultProps = {
elementId: "header-search-bar",
};
22 changes: 22 additions & 0 deletions invenio_search_ui/assets/semantic-ui/js/invenio_search_ui/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* This file is part of Invenio.
* Copyright (C) 2020 CERN.
*
* Invenio is free software; you can redistribute it and/or modify it
* under the terms of the MIT License; see LICENSE file for more details.
*/

import React from "react";
import ReactDOM from "react-dom";
import { SearchApp } from "./SearchApp";

export function initSearchApp(elementId, config) {
const rootElement = document.getElementById(elementId);
const appName = rootElement.getAttribute("data-name");
return ReactDOM.render(
<SearchApp config={config} appName={appName} />,
rootElement
);
}

window.initSearchApp = initSearchApp;
59 changes: 0 additions & 59 deletions invenio_search_ui/bundles.py

This file was deleted.

Loading