This is the official documentation of the @forestadmin/agent Node.js agent.
In Forest Admin, pages that show lists of records have a free-text search bar on top of them.
Search modes
2 search modes are supported: "normal" and "extended".
All searches start by being a "normal" search.
If the records users are looking for are not found, it is possible to trigger an "extended" search from the footer.
Default behavior
Natively, the search behavior is to seek value occurrences within columns of the Collection (in normal mode), and columns of the Collections of direct relations (in extended mode).
By default, Forest Admin will search only in specific columns, depending on their type:
Customization
If you want to make a column searchable, you must define the right operator to allow the search to be performed. Please refer to the Operators to support table to know which operator to define.
Alternatively, you may want to change how the search behaves in your admin panel.
For instance:
search only on the columns that are relevant to your use case.
use full-text indexes (i.e. Postgres tsquery and tsvector, Algolia, Elastic search, ...)
To customize the search behavior, you must define a handler that returns a ConditionTree.
Extending the default search
The context received by the function replaceSearch can have access to the default search behavior and extend it:
agent.customizeCollection('people', collection => {collection.replaceSearch((searchString, extendedMode, context) => {// This function in the context gives access to the default search behavior// including the advanced searchreturncontext.generateSearchFilter(searchString, {// Include fields from the first level of relations when true extended: extendedMode,// Remove these fields from the default search fields excludeFields: ['gender'],// Add these fields to the default search field includeFields: ['address:street'],// Replace the list of default searched field by these fields// onlyFields: [], }); });});
The condition tree returned by generateSearchFilter can be combined with other custom conditions:
constproductReferenceRegexp= /^[a-f]{16}$/i;constbarCodeRegexp= /^[0-9]{10}$/i;agent.customizeCollection('products', collection => {collection.replaceSearch(async (searchString, extendedMode, context) => {// User is searching using a product reference.if (productReferenceRegexp.test(searchString))returncontext.generateSearchFilter(searchString, { onlyFields: ['reference'], });// User is search a barcodeif (barCode.test(searchString))returncontext.generateSearchFilter(searchString, { onlyFields: ['barCode'], });// User is searching something else, let's search in the product name onlyif (!extendedMode)returncontext.generateSearchFilter(searchString, { onlyFields: ['name'] });// In "extended" mode, we search on name, description and brand namereturncontext.generateSearchFilter(searchString, { onlyFields: ['name','description','brand:name'], }); });});
Calling an external API
If your data is indexed using a SaaS, an external store, or a full-text index, you can call it in the search handler.