diff --git a/invenio_communities/assets/semantic-ui/js/invenio_communities/community/searchComponents/CommunitiesStatusFilter.js b/invenio_communities/assets/semantic-ui/js/invenio_communities/community/searchComponents/CommunitiesStatusFilter.js
new file mode 100644
index 000000000..3a9ac6773
--- /dev/null
+++ b/invenio_communities/assets/semantic-ui/js/invenio_communities/community/searchComponents/CommunitiesStatusFilter.js
@@ -0,0 +1,57 @@
+import { i18next } from "@translations/invenio_rdm_records/i18next";
+
+import React, { Component } from "react";
+
+import { Menu } from "semantic-ui-react";
+import PropTypes from "prop-types";
+
+export class CommunitiesStatusFilter extends Component {
+ render() {
+ const {
+ myCommunitiesOnClick,
+ allCommunitiesOnClick,
+ appID,
+ allCommunitiesSelected,
+ } = this.props;
+
+ return (
+
+ );
+ }
+}
+
+CommunitiesStatusFilter.propTypes = {
+ allCommunitiesOnClick: PropTypes.func.isRequired,
+ myCommunitiesOnClick: PropTypes.func.isRequired,
+ allCommunitiesSelected: PropTypes.bool,
+ appID: PropTypes.string.isRequired,
+};
+
+CommunitiesStatusFilter.defaultProps = {
+ allCommunitiesSelected: true,
+};
diff --git a/invenio_communities/assets/semantic-ui/js/invenio_communities/community/searchComponents/CommunitySelectionSearch.js b/invenio_communities/assets/semantic-ui/js/invenio_communities/community/searchComponents/CommunitySelectionSearch.js
new file mode 100644
index 000000000..aaba13d49
--- /dev/null
+++ b/invenio_communities/assets/semantic-ui/js/invenio_communities/community/searchComponents/CommunitySelectionSearch.js
@@ -0,0 +1,221 @@
+// This file is part of Invenio-RDM
+// Copyright (C) 2024 CERN.
+//
+// Invenio-communities 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 { i18next } from "@translations/invenio_rdm_records/i18next";
+import React, { Component } from "react";
+import { OverridableContext } from "react-overridable";
+import { InvenioSearchApi, ReactSearchKit, SearchBar, buildUID } from "react-searchkit";
+import { Button, Grid } from "semantic-ui-react";
+import PropTypes from "prop-types";
+import {
+ SearchConfigurationContext,
+ SearchAppFacets,
+ SearchAppResultsPane,
+} from "@js/invenio_search_ui/components";
+import { GridResponsiveSidebarColumn } from "react-invenio-forms";
+import { CommunitiesStatusFilter } from "./CommunitiesStatusFilter";
+
+export class CommunitySelectionSearch extends Component {
+ constructor(props) {
+ super(props);
+ const {
+ apiConfigs: { allCommunities },
+ } = this.props;
+
+ this.state = {
+ selectedConfig: allCommunities,
+ sidebarVisible: false,
+ };
+ }
+
+ /**
+ * Namespaces each component object with the specified appID.
+ * This is needed since the `CommunitySelectionSearch` component
+ * uses two search applications with distinct configs (e.g. to search in "All" or "My" communities)
+ */
+ prefixAppID(components, appID) {
+ // iterate components and prefix them with ".appID"
+ return Object.fromEntries(
+ Object.entries(components).map(([key, value]) => [`${appID}.${key}`, value])
+ );
+ }
+
+ render() {
+ const {
+ selectedConfig: {
+ searchApi: selectedSearchApi,
+ appId: selectedAppId,
+ initialQueryState: selectedInitialQueryState,
+ toggleText,
+ },
+ sidebarVisible,
+ } = this.state;
+
+ const {
+ apiConfigs: { allCommunities, myCommunities },
+ autofocus,
+ communitiesStatusFilterEnabled,
+ config,
+ overriddenComponents,
+ } = this.props;
+
+ const searchApi = new InvenioSearchApi(selectedSearchApi);
+
+ const validatedComponents = this.prefixAppID(overriddenComponents, selectedAppId);
+
+ const layoutOptions = {
+ listView: true,
+ gridView: false,
+ };
+
+ const context = {
+ selectedAppId,
+ buildUID: (element) => buildUID(element, "", selectedAppId),
+ ...config,
+ };
+
+ return (
+
+
+
+
+
+ {/* Start burger menu for mobile and tablet only */}
+
+
+ {config.aggs && }
+ {communitiesStatusFilterEnabled && (
+
+ {
+ this.setState({
+ selectedConfig: myCommunities,
+ });
+ }}
+ allCommunitiesOnClick={() => {
+ this.setState({
+ selectedConfig: allCommunities,
+ });
+ }}
+ appID={selectedAppId}
+ allCommunitiesSelected={selectedAppId === allCommunities.appId}
+ />
+
+ )}
+
+
+
+
+
+
+ this.setState({ sidebarVisible: false })}
+ >
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+}
+
+CommunitySelectionSearch.propTypes = {
+ apiConfigs: PropTypes.shape({
+ allCommunities: PropTypes.shape({
+ appId: PropTypes.string.isRequired,
+ initialQueryState: PropTypes.object.isRequired,
+ searchApi: PropTypes.object.isRequired,
+ }),
+ myCommunities: PropTypes.shape({
+ appId: PropTypes.string.isRequired,
+ initialQueryState: PropTypes.object.isRequired,
+ searchApi: PropTypes.object.isRequired,
+ }),
+ }),
+ autofocus: PropTypes.bool,
+ overriddenComponents: PropTypes.object,
+ config: PropTypes.object.isRequired,
+ communitiesStatusFilterEnabled: PropTypes.bool,
+};
+
+CommunitySelectionSearch.defaultProps = {
+ autofocus: true,
+ apiConfigs: {
+ allCommunities: {
+ initialQueryState: { size: 5, page: 1, sortBy: "bestmatch" },
+ searchApi: {
+ axios: {
+ url: "/api/communities",
+ headers: { Accept: "application/vnd.inveniordm.v1+json" },
+ },
+ },
+ appId: "ReactInvenioDeposit.CommunitySelectionSearch.AllCommunities",
+ toggleText: "Search in all communities",
+ },
+ myCommunities: {
+ initialQueryState: { size: 5, page: 1, sortBy: "bestmatch" },
+ searchApi: {
+ axios: {
+ url: "/api/user/communities",
+ headers: { Accept: "application/vnd.inveniordm.v1+json" },
+ },
+ },
+ appId: "ReactInvenioDeposit.CommunitySelectionSearch.MyCommunities",
+ toggleText: "Search in my communities",
+ },
+ },
+ overriddenComponents: {},
+ communitiesStatusFilterEnabled: true,
+};
diff --git a/invenio_communities/assets/semantic-ui/js/invenio_communities/community/searchComponents/index.js b/invenio_communities/assets/semantic-ui/js/invenio_communities/community/searchComponents/index.js
index 069b37493..3c38911f0 100644
--- a/invenio_communities/assets/semantic-ui/js/invenio_communities/community/searchComponents/index.js
+++ b/invenio_communities/assets/semantic-ui/js/invenio_communities/community/searchComponents/index.js
@@ -3,3 +3,5 @@ export { CommunitiesSearchLayout } from "./CommunitiesSearchLayout";
export { ResultsGridItemTemplate } from "./ResultsGridItemTemplate";
export { CommunitiesSearchBarElement } from "./CommunitiesSearchBarElement";
export { CommunitiesEmptySearchResults } from "./CommunitiesEmptySearchResults";
+export { CommunitySelectionSearch } from "./CommunitySelectionSearch";
+export { CommunitiesStatusFilter } from "./CommunitiesStatusFilter";
diff --git a/invenio_communities/assets/semantic-ui/js/invenio_communities/requests/index.js b/invenio_communities/assets/semantic-ui/js/invenio_communities/requests/index.js
index 74838b279..214c22af8 100644
--- a/invenio_communities/assets/semantic-ui/js/invenio_communities/requests/index.js
+++ b/invenio_communities/assets/semantic-ui/js/invenio_communities/requests/index.js
@@ -12,6 +12,7 @@ import {
ContribBucketAggregationElement,
ContribBucketAggregationValuesElement,
ContribSearchAppFacets,
+ SearchResultsBox,
} from "@js/invenio_search_ui/components";
import { overrideStore, parametrize } from "react-overridable";
import {
@@ -21,7 +22,6 @@ import {
import {
RequestsSearchLayout,
RequestsEmptyResultsWithState,
- RequestsResults,
} from "@js/invenio_requests/search";
const domContainer = document.getElementById("communities-request-search-root");
@@ -48,7 +48,7 @@ const defaultComponents = {
[`${appName}.ResultsList.item`]: RequestsResultsItemTemplateWithCommunity,
[`${appName}.ResultsGrid.item`]: () => null,
[`${appName}.SearchApp.layout`]: RequestsSearchLayoutWAppName,
- [`${appName}.SearchApp.results`]: RequestsResults,
+ [`${appName}.SearchApp.results`]: SearchResultsBox,
[`${appName}.SearchBar.element`]: RecordSearchBarElement,
[`${appName}.EmptyResults.element`]: RequestsEmptyResultsWithState,
...defaultContribComponents,
diff --git a/invenio_communities/assets/semantic-ui/js/invenio_communities/subcommunity/SubcommunityResults.js b/invenio_communities/assets/semantic-ui/js/invenio_communities/subcommunity/SubcommunityResults.js
new file mode 100644
index 000000000..f5520ef2f
--- /dev/null
+++ b/invenio_communities/assets/semantic-ui/js/invenio_communities/subcommunity/SubcommunityResults.js
@@ -0,0 +1,75 @@
+// This file is part of Invenio
+// Copyright (C) 2024 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 { InvenioSearchPagination } from "@js/invenio_search_ui/components";
+import { i18next } from "@translations/invenio_requests/i18next";
+import PropTypes from "prop-types";
+import React from "react";
+import { Count, ResultsList, Sort } from "react-searchkit";
+import { Grid, Segment } from "semantic-ui-react";
+
+export const SubcommunityResults = ({
+ sortOptions,
+ paginationOptions,
+ currentResultsState,
+}) => {
+ const { total } = currentResultsState.data;
+ return (
+ total && (
+
+
+
+
+
+
+
+ (
+ <>
+ {i18next.t("{{count}} results found", {
+ count: total,
+ })}
+ >
+ )}
+ />
+
+
+ {sortOptions && (
+ (
+ <>
+
+ {cmp}
+ >
+ )}
+ />
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+ );
+};
+
+SubcommunityResults.propTypes = {
+ sortOptions: PropTypes.object.isRequired,
+ paginationOptions: PropTypes.object.isRequired,
+ currentResultsState: PropTypes.object.isRequired,
+};
diff --git a/invenio_communities/assets/semantic-ui/js/invenio_communities/subcommunity/search.js b/invenio_communities/assets/semantic-ui/js/invenio_communities/subcommunity/search.js
index 9bdbb3782..1dc584eea 100644
--- a/invenio_communities/assets/semantic-ui/js/invenio_communities/subcommunity/search.js
+++ b/invenio_communities/assets/semantic-ui/js/invenio_communities/subcommunity/search.js
@@ -6,47 +6,49 @@
* under the terms of the MIT License; see LICENSE file for more details.
*/
-import { createSearchAppInit } from "@js/invenio_search_ui";
+import React from "react";
+import ReactDOM from "react-dom";
import {
ContribBucketAggregationElement,
ContribBucketAggregationValuesElement,
ContribSearchAppFacets,
+ SearchResultsBox,
} from "@js/invenio_search_ui/components";
-import { overrideStore, parametrize } from "react-overridable";
+import { parametrize } from "react-overridable";
import {
- CommunitiesResults,
CommunitiesSearchBarElement,
- CommunitiesSearchLayout,
CommunityItem,
ResultsGridItemTemplate,
+ CommunitySelectionSearch,
} from "../community";
-const appName = "InvenioSubCommunities.Search";
+import { Container } from "semantic-ui-react";
const ContribSearchAppFacetsWithConfig = parametrize(ContribSearchAppFacets, {
help: false,
});
-const CommunitiesSearchLayoutConfig = parametrize(CommunitiesSearchLayout, {
- appName: appName,
-});
-
-export const defaultComponents = {
- [`${appName}.BucketAggregation.element`]: ContribBucketAggregationElement,
- [`${appName}.BucketAggregationValues.element`]: ContribBucketAggregationValuesElement,
- [`${appName}.SearchApp.facets`]: ContribSearchAppFacetsWithConfig,
- [`${appName}.ResultsList.item`]: CommunityItem,
- [`${appName}.ResultsGrid.item`]: ResultsGridItemTemplate,
- [`${appName}.SearchApp.layout`]: CommunitiesSearchLayoutConfig,
- [`${appName}.SearchBar.element`]: CommunitiesSearchBarElement,
- [`${appName}.SearchApp.results`]: CommunitiesResults,
+export const overriddenComponents = {
+ [`BucketAggregation.element`]: ContribBucketAggregationElement,
+ [`BucketAggregationValues.element`]: ContribBucketAggregationValuesElement,
+ [`SearchApp.facets`]: ContribSearchAppFacetsWithConfig,
+ [`ResultsList.item`]: CommunityItem,
+ [`ResultsGrid.item`]: ResultsGridItemTemplate,
+ [`SearchBar.element`]: CommunitiesSearchBarElement,
+ [`SearchApp.results`]: SearchResultsBox,
};
-const overriddenComponents = overrideStore.getAll();
-// Auto-initialize search app
-createSearchAppInit(
- { ...defaultComponents, ...overriddenComponents },
- true,
- "invenio-search-config",
- true
+const domContainer = document.getElementById("communities-search");
+const config = JSON.parse(domContainer.dataset?.invenioSearchConfig);
+const userAnonymous = JSON.parse(domContainer.dataset?.userAnonymous);
+// eslint-disable-next-line react/no-deprecated
+ReactDOM.render(
+
+
+ ,
+ domContainer
);
diff --git a/invenio_communities/templates/semantic-ui/invenio_communities/details/subcommunity/index.html b/invenio_communities/templates/semantic-ui/invenio_communities/details/subcommunity/index.html
index ee6c0cf3e..ae3c5bad9 100644
--- a/invenio_communities/templates/semantic-ui/invenio_communities/details/subcommunity/index.html
+++ b/invenio_communities/templates/semantic-ui/invenio_communities/details/subcommunity/index.html
@@ -40,8 +40,10 @@