Quickly find contents in SENAITE by pressing the configured hotkey
(Ctrl-Space by default) and start typing.
The spotlight is a React component that consumes the shared React instance
exposed by senaite.core. It searches the configured catalogs on the server
and narrows, sorts and highlights the results on the client. A command palette
allows navigating to or triggering registered actions directly.
See the screencast how to use it: https://www.youtube.com/watch?v=AIA5atToc-c
The search term supports a few inline tokens:
/opens the command palette and lists all available commands. Type after the slash to filter them, e.g./add.<prefix>:<term>scopes the search to a single catalog, e.g.s:watersearches only the catalog whose prefix iss(see the Catalogs setting).is:<state>filters by workflow state, e.g.CA20 is:receivedfinds items matchingCA20that are in thereceivedstate. Typingis:opens an autocomplete of the available states (scoped to the active catalog when a prefix is used, otherwise the union of all catalogs). The state is matched on whole, underscore-delimited segments of the catalog's review states (soreceivedmatchessample_receivedandverifiedmatches bothverifiedandto_be_verified, butactivedoes not matchinactive).
Tokens can be combined, e.g. s:CA20 is:received. The same tokens also work in
the search box of the standalone search page.
The spotlight has its own control panel at @@spotlight-controlpanel,
reachable from the SENAITE control panel ("Spotlight Settings") and from the
settings link inside the spotlight itself (shown to users with the
senaite.core: Manage Bika permission). The following settings are available:
- Hotkey: Keyboard shortcut to toggle the overlay, e.g.
Control+Space,Meta+korControl+Shift+f. - Maximum results / Minimum characters / Search debounce: Tune the search behavior.
- Highlight matches: Highlight the matching parts of the search term.
- Catalogs: A grid of the catalogs to search. Every installed SENAITE
catalog is listed here automatically (see Catalog auto-discovery below).
Each row has a
catalog,label, optionalprefix(scopes a search to a single catalog, e.g. typings:water),portal_types,index,sort_on,sort_orderandenabled. - Commands: A grid of command palette actions. Each row has an
id,title,icon,url(may contain the${portal_url}placeholder), an optionalpermission(the command is only shown to users holding it) andkeywords.
Every installed SENAITE catalog is added to the search scope automatically.
Discovery finds all catalog tools that provide the ISenaiteCatalogObject
marker (implemented by senaite.core's BaseCatalog, and so inherited by
every add-on catalog), which means installing an add-on such as
senaite.storage makes its catalog searchable without any configuration.
Discovered catalogs show up as rows in the Catalogs grid, so the control panel always lists all catalogs. From there you can:
- Uncheck Enabled to exclude a catalog from the search.
- Set a Label shown in the scope bar, or a Prefix for scoped searches
(e.g.
s:water). - Reorder the rows to change the order of the scope tabs.
The internal bookkeeping catalogs (analyses, audit log, import logs, attachments) ship as disabled rows, so they stay out of the search by default while remaining one checkbox away. Saving the control panel persists the list; catalogs installed afterwards keep appearing automatically.
The settings are stored in the registry under the senaite.app.spotlight
prefix. Catalogs need no manual entry thanks to auto-discovery, but add-ons
can still contribute command palette actions (or pre-seed a catalog's label
or prefix) by shipping their own registry.xml that appends to the list
fields with purge="false":
<registry>
<records interface="senaite.app.spotlight.controlpanel.ISpotlightControlPanel"
prefix="senaite.app.spotlight">
<value key="commands" purge="false">
<element>
<value key="command_id">my-action</value>
<value key="title">My Action</value>
<value key="url">${portal_url}/my-view</value>
</element>
</value>
</records>
</registry>The spotlight search calls an multi adapter to get the search results.
This adapter needs to implement the ISpotlightSearchAdapter and adapts the
context and the request. It must be implemented that it returns a dictionary
containing the search results when calling it.
The results dictionary has to provide at least a list of items, where each
item is a dictionary containing the following data:
{
"id": id,
"title": title,
"title_or_id": title or id,
"description": description,
"url": url,
"parent_title": parent_title,
"parent_url": parent_url,
"icon": icon,
}A simple implementation looks like this:
dummy_item = {
"id": "test",
"title": "Test Item",
"title_or_id": "Test Item",
"description": "A search result item",
"url": "",
"parent_title": "",
"parent_url": "",
"icon": "",
}
@implementer(ISpotlightSearchAdapter)
class MySpotlightSearchAdapter(object):
"""Spotlight Search Adapter
"""
def __init__(self, context, request):
self.context = context
self.request = request
def __call__(self):
items = [dummy_item]
return {
"count": len(items),
"items": items,
}And is registered like this:
<!-- A custom Spotlight Search Adapter -->
<adapter
for="*
.interfaces.IMyBrowserLayer"
factory=".adapters.MySpotlightSearchAdapter" />Note that the custom adapter needs to be more specific than the default adapter. Therefore, adapting it either to your custom browser layer or to a specific content type interface.
The JavaScript code for senaite.app.spotlight is built via
Webpack. To setup the development environment, go to
the root of this package install the required dependencies with yarn:
$ yarn installNote: You need to have node installed.
The React source code is located at webpack/app and is built into
src/senaite/app/spotlight/static/js.
After this, you can start watching for changes in the code files:
$ yarn watchWhen you are done, you can create a production build of the JavaScript with this command:
$ yarn buildSENAITE.APP.SPOTLIGHT Copyright (C) RIDING BYTES & NARALABS
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.