https://github.com/cuba-platform/rich-search-addon
Global Search CUBA Platform application component that will provide user ability to search many types of objects in one search field.
https://github.com/cuba-platform/rich-search-addon
apache2 cuba-component cuba-platform search
Last synced: 12 months ago
JSON representation
Global Search CUBA Platform application component that will provide user ability to search many types of objects in one search field.
- Host: GitHub
- URL: https://github.com/cuba-platform/rich-search-addon
- Owner: cuba-platform
- License: apache-2.0
- Created: 2018-03-21T09:30:19.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2024-12-27T08:43:42.000Z (over 1 year ago)
- Last Synced: 2024-12-27T09:29:12.266Z (over 1 year ago)
- Topics: apache2, cuba-component, cuba-platform, search
- Language: Java
- Homepage:
- Size: 1.26 MB
- Stars: 2
- Watchers: 6
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# Rich Search
- [Overview](#overview)
- [Installation](#installation)
- [From the Marketplace](#from-the-marketplace)
- [By Coordinates](#by-coordinates)
- [Quick Start](#quick-start)
- [Data Model](#data-model)
- [Usage](#usage)
- [Known Issues](#known-issues)
## Overview
The add-on is designed to search for various types of objects using a single field. This out-of-the-box solution enables searching by application menu items.
You can configure your application to search for entities including related ones as well as entity attributes.
Key features:
- A single field for searching.
- Customizable search strategy.

See [sample application](https://github.com/cuba-platform/rich-search-addon-demo) using this add-on.
# Installation
The add-on can be added to your project in one of the ways described below. Installation from the Marketplace is the simplest way. The last version of the add-on compatible with the used version of the platform will be installed.
Also, you can install the add-on by coordinates choosing the required version of the add-on from the table.
In case you want to install the add-on by manual editing or by building from sources see the complete add-ons installation guide in [CUBA Platform documentation](https://doc.cuba-platform.com/manual-latest/manual.html#app_components_usage).
## From the Marketplace
1. Open your application in CUBA Studio. Check the latest version of CUBA Studio on the [CUBA Platform site](https://www.cuba-platform.com/download/previous-studio/).
2. Go to *CUBA -> Marketplace* in the main menu.

3. Find the Rich Search add-on there.

4. Click *Install* and apply the changes.
The add-on corresponding to the used platform version will be installed.
## By coordinates
1. Open your application in CUBA Studio. Check the latest version of CUBA Studio on the [CUBA Platform site](https://www.cuba-platform.com/download/previous-studio/).
2. Go to *CUBA -> Marketplace* in the main menu.
3. Click the icon in the upper-right corner.

4. Paste the add-on coordinates in the corresponding field as follows:
`com.haulmont.addon.search:search-global:`
where `` is compatible with the used version of the CUBA platform.
| Platform Version | Add-on Version |
|------------------|----------------|
| 7.2.X | 1.6.0 |
| 7.1.X | 1.5.0 |
| 7.0.X | 1.4.0 |
| 6.10.X | 1.3.0 |
| 6.9.X | 1.2.0 |
| 6.8.X | 1.0.3 |
5. Click *Install* and apply the changes. The add-on will be installed to your project.
# Quick Start
1. Override the main screen via the Studio interface.
1. Add the following code to `ext-mainwindow.xml`:
**For horizontal menu layout**
```xml
```
**For vertical menu layout**
```xml
```
# Data Model
### Search Field
Search Field provides one or several search strategies that are called for each search query.
### Search Strategy
Search Strategy defines which objects should be returned as a result of the current search request.
### SearchEntry
SearchEntry is an interface designed to work with search result objects. Each SearchEntry has an id, caption
and the name of a search strategy that it belongs to specified.
### DefaultSearchEntry
DefaultSearchEntry defines the default implementation of SearchEntry.
### SearchContext
SearchContext provides the context dependent data for the search mechanism, e.g. a user session, additional params.
### HeaderEntry
HeaderEntry implements a header for grouping strategy results.
# Usage
Let us consider an example of how the component can be of use. Start by searching for a system user. The component finds
the required user and opens User Editor.
The system performs search by login. In order to configure the component, use the following code:
```java
LoadContext lc = LoadContext.create(User.class);
lc.setQueryString("select u from sec$User u where u.loginLowerCase like concat('%',:loginLowerCase,'%')")
.setParameter("loginLowerCase", query.toLowerCase());
```
The sections below present several options to define search strategies.
### Using A Spring Bean As Search Strategy
**Spring bean**:
```java
@Component("search_UsersSearchStrategy")
public class UsersSearchStrategy implements SearchStrategy {
@Override
public List load(SearchContext context, String query) {
LoadContext lc = LoadContext.create(User.class);
lc.setQueryString("select u from sec$User u where u.loginLowerCase like concat('%',:loginLowerCase,'%')")
.setParameter("loginLowerCase", query.toLowerCase());
return dataManager.loadList(lc).stream()
.map(user -> new DefaultSearchEntry(user.getId().toString(), user.getCaption(), name()))
.collect(Collectors.toList());
}
@Override
public void invoke(SearchContext context, SearchEntry value) {
LoadContext lc = LoadContext.create(User.class)
.setId(UuidProvider.fromString(value.getId()));
User user = dataManager.load(lc);
AppUI.getCurrent().getTopLevelWindow().openEditor(user, WindowManager.OpenType.NEW_TAB);
}
@Override
public String name() {
return "usersSearchStrategy";
}
}
```
**XML screen config**:
```xml
...
...
...
...
```
**Localization**
Add the following entry to the main message pack as it is given below:
```text
searchStrategy.{strategyName} = Strategy name
```
Example:
```text
searchStrategy.usersSearchStrategy = Users
```
### Using Controller Methods
**XML screen config**:
```xml
...
...
...
...
```
**Screen controller**:
```java
public class MyWindowController extends AbstractWindow {
@Inject
protected DataManager dataManager;
public List search(SearchContext context, String query) {
LoadContext lc = LoadContext.create(User.class);
lc.setQueryString("select u from sec$User u where u.loginLowerCase like concat('%',:loginLowerCase,'%')")
.setParameter("loginLowerCase", query.toLowerCase());
return dataManager.loadList(lc).stream()
.map(user -> new DefaultSearchEntry(user.getId().toString(), user.getCaption(), "usersSearchStrategy"))
.collect(Collectors.toList());
}
public void invoke(SearchContext context, SearchEntry searchEntry) {
LoadContext lc = LoadContext.create(User.class)
.setId(UuidProvider.fromString(searchEntry.getId()));
User user = dataManager.load(lc);
AppUI.getCurrent().getTopLevelWindow().openEditor(user, WindowManager.OpenType.NEW_TAB);
}
}
```
### Using Programmatic Strategy
**Screen controller**:
```java
public class MyWindowController extends AbstractWindow {
@Inject
protected DataManager dataManager;
@Inject
protected RichSearch search;
@Override
public void init(Map params) {
super.init(params);
search.addStrategy("usersSearchStrategy", query -> {
LoadContext lc = LoadContext.create(User.class);
lc.setQueryString("select u from sec$User u where u.loginLowerCase like concat('%',:loginLowerCase,'%')")
.setParameter("loginLowerCase", query.toLowerCase());
return dataManager.loadList(lc).stream()
.map(user -> new DefaultSearchEntry(user.getId().toString(), user.getCaption(), "usersSearchStrategy"))
.collect(Collectors.toList());
}, searchEntry -> {
LoadContext lc = LoadContext.create(User.class)
.setId(UuidProvider.fromString(searchEntry.getId()));
User user = dataManager.load(lc);
AppUI.getCurrent().getTopLevelWindow().openEditor(user, WindowManager.OpenType.NEW_TAB);
});
}
}
```
The result is:

## Known issues
1. The available amount of input should be accounted for each strategy separately (no task, to be discussed).
1. It is required to add an XML declaration for specific strategy parameters (no task, to be discussed).
1. It is required to add keyboard shortcuts for the component and its settings (no task, to be discussed).