Show Documents without the Chat#
The SDK also shows Squirro documents on their own, without the chat: as a read-only documents API, as a document view, and as a search widget.
The Documents API#
sdk.items is the read-only documents API, through the same proxy, for pages that build their own list: sdk.items.search({ text: 'zebrafish' }, { limit: 10 }), sdk.items.getItem(id), and sdk.items.fetchFile(link) for the bytes of the original file of a document.
The
titleandabstractof every result and document, including the result thatonOpenItemreceives, are plain text: the search highlight tags are removed, and the character references of the abstract, such as&, are decoded. Set them withtextContent, neverinnerHTML, and do not decode them again.A failed request rejects with an
ItemsRequestError, which carries the HTTPstatusand akindthat says what went wrong, such assearch-disabledfor a proxy without search. A search that the proxy refused for one of its limits also carries thecodeof the proxy, and its message names the option. On a script-tag page, checkerror.name === 'ItemsRequestError'. For everykind, see thedocs/chat.mdanddocs/documents.mdfiles in the package.
The Document View#
In React, NeoItemDetail renders the same document view as the overlay, anywhere inside NeoSdkProvider, for example in a side panel of your own:
import { NeoItemDetail } from '@squirro/neo-sdk';
<NeoItemDetail itemId="the-squirro-item-id" pageNumber={2} onClose={() => setOpen(false)} />
It takes these props:
itemId, the document to show.pageNumberandhighlightFragments, as forsdk.openDocument().onClose, which shows a close button. Escape does not call it.className. Size the component from its parent.
The Search Widget#
NeoItems adds a read-only search box and its results, and a result opens in the same document overlay. It needs ALLOW_SEARCH=1 on the proxy, or allowSearch: true. Without it, the widget says that search is turned off.
For example, to search for a fixed term:
import { NeoItems } from '@squirro/neo-sdk';
<NeoItems query="zebrafish" pageSize={10} className="h-96" />
It takes these props:
query, which fills the box and searches. A new value searches again.pageSize, a positive integer, 15 by default.onOpenItem, which receives the result and replaces opening the overlay.strings, to replace its English text.className. Give the widget a height from its parent, since the list scrolls inside it.
To let readers narrow the results, list the facets to filter by, and the orders to offer after Relevance:
<NeoItems
query="zebrafish"
filters={[{ field: 'source', label: 'Source' }, { field: 'source_type', label: 'Type' }]}
sort={[{ label: 'Newest first', field: 'date', order: 'desc' }]}
/>
Each filter is a dropdown of the values of the field, with their counts: 10 by default, and up to 50 with limit. A widget takes at most 8 filters. Values of one field are combined with OR, and the fields with AND. initialFilters picks values up front, and onFiltersChange tells you what the reader picked. The same keys under items in initNeoSdk() set the defaults for every search widget of that instance.
Filter fields are facet names, and an order sorts by date or by one of the filter fields. initialFilters is a convenience for the reader, not access control. For the filter values that cannot match, see the docs/documents.md file in the package.
Because every reader shares the service account, the proxy accepts only searches like the ones that the widget sends, with at most 100 results each and a search text of at most 4,096 characters. itemsQueryLimits on the proxy changes these caps. Keep pageSize at or under the result cap.
Without a Build Step#
On a page without a build step, the same two widgets are the <neo-items> and <neo-item-detail> elements, from the same neo-sdk.js. They take base-url, project-id, auth, the theme attributes, and the theme JSON child exactly like <neo-chat>, and each needs a size:
<script src="/assets/neo-sdk.js" defer></script>
<neo-items id="search" base-url="/api/chat" project-id="YOUR_PROJECT_ID" auth="anonymous" query="zebrafish" page-size="10"></neo-items>
<neo-item-detail
id="report"
base-url="/api/chat"
project-id="YOUR_PROJECT_ID"
auth="anonymous"
item-id="the-squirro-item-id"
page-number="2"
></neo-item-detail>
<style>
neo-items,
neo-item-detail {
display: block;
height: 600px;
}
</style>
<script>
const report = document.getElementById('report');
report.highlightFragments = ['net revenue'];
// Change what they show at any time; they follow their attributes.
document.getElementById('search').setAttribute('query', 'quarterly results');
</script>
<neo-items>takesqueryandpage-size, andfiltersandsortas JSON, for examplefilters='[{"field":"source","label":"Source"}]'. Set itsonOpenItemproperty to handle a click on a result yourself.<neo-item-detail>takesitem-id, which is required, andpage-number, a positive integer. The text to highlight is thehighlightFragmentsproperty, since an attribute cannot hold a list.Changing
query,page-size,filters,sort, oritem-idlater updates the widget in place. A newpage-numberapplies only the next time a document loads.Each element is its own SDK instance. Set
pdfVieweras a property on any of them that shows PDF documents.Each element reports a problem as a
neo-items-errororneo-item-detail-errorevent, with the error inevent.detail. A<neo-item-detail>withoutitem-idshows nothing until you set one. After any other error, such as a missingproject-id, fix it and add the element to the page again.