@sinequa/atomic

Preview

Showing a document with its highlights — the two views of the highlight data, and why the iframe needs a cookie.

A preview is a cached rendition of a document, prepared by the server so it can be displayed and highlighted in a browser. One call gives you the URL to embed and the highlight data to build a panel from.

one call
const preview = await client.api.preview.get(record.id, query);

Concept — the preview cache

The server converts a document once — a PDF, an email, a spreadsheet — into a cached HTML rendition and keeps it under a cacheId. The preview you show is that rendition, not the original file, which is why the highlights can be positioned in it.

What comes back

Prop

Type

Two views of the same data, for two jobs. Grouped by category, you build a panel of entity filters. Listed by location, you step through occurrences — "next mention of Alice" — because each entry carries its start, length and its positionInCategories.

A preview panel

Embed the rendition, list the highlight categories
src/preview.ts
import { createAtomicClient, sysLang } from "@sinequa/atomic";
import type { PreviewData, Query } from "@sinequa/atomic";

const client = createAtomicClient({
  app: "<your-app>",
  backendUrl: "https://<your-sinequa-server>",
});

await client.initializeConfig();
await client.auth.login();

export async function openPreview(recordId: string, query: Query) {
  const preview = await client.api.preview.get(recordId, query);

  showDocument(preview);
  showCategories(preview);

  return preview;
}

function showDocument(preview: PreviewData) {
  const frame = document.querySelector("iframe")!;

  // The iframe cannot send an Authorization header: it relies on the session
  // cookie. A blank preview on a token-authenticated deployment is that.
  frame.src = preview.documentCachedContentUrl;
}

function showCategories(preview: PreviewData) {
  for (const [name, category] of Object.entries(preview.highlightsPerCategory ?? {})) {
    // Labels are multilingual strings; decode before displaying.
    const label = sysLang(category.categoryDisplayLabel ?? name, navigator.language);
    console.log(`${label}: ${category.values.length} value(s)`);
  }
}

/** Occurrences in document order, for "next mention" navigation. */
export function occurrencesOf(preview: PreviewData, value: string) {
  return preview.highlightsPerLocation
    .filter((location) => location.values.includes(value))
    .sort((a, b) => a.start - b.start);
}

Pitfalls

What's next

On this page