@athenaintel/react 0.10.38 → 0.10.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -144,13 +144,19 @@ Set `linkClicks={{ interceptAthenaCitations: false }}` to keep Athena citation l
144
144
 
145
145
  ## Standalone Asset Embeds
146
146
 
147
- Use `AthenaAssetEmbed` to render a native Athena asset without chat, thread history, tabs, or the SDK split-pane layout. Full mode supports documents, spreadsheets, and presentations.
147
+ Use `AthenaAssetEmbed` to render a native Athena asset without chat, thread history, tabs, or the SDK split-pane layout. It defaults to the editable, full native asset experience (`readOnly={false}` and `displayMode="full"`). The embed token and the current user must still have edit permission; otherwise Athena renders the asset read-only.
148
148
 
149
149
  ```tsx
150
- import { AthenaAssetEmbed, AthenaProvider } from '@athenaintel/react';
150
+ import { useState } from 'react';
151
+ import {
152
+ AthenaAssetEmbed,
153
+ AthenaProvider,
154
+ type AthenaAssetCitationReference,
155
+ } from '@athenaintel/react';
151
156
 
152
157
  function AssetView() {
153
- const [linkedReference, setLinkedReference] = useState(null);
158
+ const [linkedReference, setLinkedReference] =
159
+ useState<AthenaAssetCitationReference | null>(null);
154
160
 
155
161
  return (
156
162
  <AthenaProvider config={{ token: accessToken }}>
@@ -158,7 +164,7 @@ function AssetView() {
158
164
  <AthenaAssetEmbed
159
165
  assetId="asset_123"
160
166
  displayMode="full"
161
- readOnly
167
+ readOnly={false}
162
168
  onCitationClick={({ reference, sourceAssetId }) => {
163
169
  console.log('Citation clicked', { reference, sourceAssetId });
164
170
  }}
@@ -173,7 +179,7 @@ function AssetView() {
173
179
  assetId={linkedReference.id}
174
180
  reference={linkedReference}
175
181
  displayMode="full"
176
- readOnly
182
+ readOnly={false}
177
183
  />
178
184
  )}
179
185
  </div>
@@ -190,6 +196,39 @@ Pass the callback's complete `reference` to the linked `AthenaAssetEmbed`, rathe
190
196
  `reference.id`. The embed uses the reference anchor to navigate PDFs to the cited page. Updating the
191
197
  reference also navigates when the host opens another citation in the same asset.
192
198
 
199
+ If the host starts with an Athena citation URL/string instead of an
200
+ `onCitationAction` event, parse it and pass the returned `reference` directly to the embed:
201
+
202
+ ```tsx
203
+ import {
204
+ AthenaAssetEmbed,
205
+ parseAthenaCitationLink,
206
+ } from '@athenaintel/react';
207
+
208
+ const citation = parseAthenaCitationLink({
209
+ href: citationString,
210
+ appUrl: 'https://app.athenaintel.com',
211
+ });
212
+
213
+ return citation ? (
214
+ <AthenaAssetEmbed
215
+ assetId={citation.assetId}
216
+ reference={citation.reference}
217
+ displayMode="full"
218
+ readOnly={false}
219
+ />
220
+ ) : null;
221
+ ```
222
+
223
+ For example, this citation opens the PDF directly at page 34:
224
+
225
+ ```text
226
+ https://app.athenaintel.com/dashboard/spaces/?asset_ids=asset_pdf&anchor=page&page=34&excerpt=Term%20debt
227
+ ```
228
+
229
+ The important query parameters are `asset_ids`, `anchor=page`, and `page`. Page ranges and
230
+ positioned citations are also preserved by `parseAthenaCitationLink`.
231
+
193
232
  ## Theming
194
233
 
195
234
  ```tsx
@@ -6,7 +6,7 @@ export interface AthenaAssetEmbedProps extends Omit<IframeHTMLAttributes<HTMLIFr
6
6
  reference?: AthenaAssetCitationReference;
7
7
  /** Defaults to the native full asset experience. */
8
8
  displayMode?: "minimal" | "full";
9
- /** Defaults to true. */
9
+ /** Defaults to false so authorized users can edit the embedded asset. */
10
10
  readOnly?: boolean;
11
11
  expiresInSeconds?: number;
12
12
  citationBehavior?: AthenaAssetCitationBehavior;
@@ -2,9 +2,11 @@ import type { AthenaAssetCitationReference } from './asset-embed-messages';
2
2
  export interface UseAssetEmbedOptions {
3
3
  readOnly?: boolean;
4
4
  expiresInSeconds?: number;
5
- /** Native Olympus surface rendered by the iframe. Defaults to `minimal`. */
5
+ /** Native Olympus surface rendered by the iframe. Defaults to `full`. */
6
6
  displayMode?: 'minimal' | 'full';
7
7
  }
8
+ export declare const DEFAULT_ASSET_EMBED_READ_ONLY = false;
9
+ export declare const DEFAULT_ASSET_EMBED_DISPLAY_MODE: 'full';
8
10
  export interface UseAssetEmbedResult {
9
11
  embedUrl: string | null;
10
12
  isLoading: boolean;
@@ -1,3 +1,4 @@
1
+ import type { AthenaAssetCitationReference } from '../assets/asset-embed-messages';
1
2
  import { type AssetType } from '../assets/asset-panel-store';
2
3
  import type { AthenaCitationLinkHandler, AthenaLinkClickHandler } from '../provider/citation-links';
3
4
  export interface ParsedAthenaCitationLink {
@@ -5,6 +6,8 @@ export interface ParsedAthenaCitationLink {
5
6
  assetId: string;
6
7
  assetIds: string[];
7
8
  assetType: AssetType | null;
9
+ /** Complete target that can be passed directly to AthenaAssetEmbed.reference. */
10
+ reference: AthenaAssetCitationReference;
8
11
  }
9
12
  export declare const parseAthenaCitationLink: ({ href, appUrl, }: {
10
13
  href: string;
package/dist/index.cjs CHANGED
@@ -47521,6 +47521,51 @@ const ASSET_TYPE_ALIASES = {
47521
47521
  word_document: "document"
47522
47522
  };
47523
47523
  const isAthenaSpacesPath = (url) => url.pathname.replace(/\/+$/, "") === "/dashboard/spaces";
47524
+ const getFiniteNumber = (url, key) => {
47525
+ const value = url.searchParams.get(key);
47526
+ if (value === null || value.trim() === "") return null;
47527
+ const parsed = Number(value);
47528
+ return Number.isFinite(parsed) ? parsed : null;
47529
+ };
47530
+ const parseCitationReference = ({
47531
+ url,
47532
+ assetId
47533
+ }) => {
47534
+ const reference2 = { id: assetId };
47535
+ const anchorType = url.searchParams.get("anchor");
47536
+ const page = getFiniteNumber(url, "page");
47537
+ switch (anchorType) {
47538
+ case "page":
47539
+ if (page !== null) reference2.anchor = { type: anchorType, page };
47540
+ break;
47541
+ case "page_range": {
47542
+ const startPage = getFiniteNumber(url, "start_page");
47543
+ const endPage = getFiniteNumber(url, "end_page");
47544
+ if (startPage !== null && endPage !== null) {
47545
+ reference2.anchor = { type: anchorType, startPage, endPage };
47546
+ }
47547
+ break;
47548
+ }
47549
+ case "page_rect": {
47550
+ const x = getFiniteNumber(url, "x");
47551
+ const y = getFiniteNumber(url, "y");
47552
+ const width = getFiniteNumber(url, "width");
47553
+ const height = getFiniteNumber(url, "height");
47554
+ if (page !== null && x !== null && y !== null && width !== null && height !== null) {
47555
+ reference2.anchor = { type: anchorType, page, x, y, width, height };
47556
+ }
47557
+ break;
47558
+ }
47559
+ case "page_text": {
47560
+ const text2 = url.searchParams.get("text");
47561
+ if (page !== null && text2) reference2.anchor = { type: anchorType, page, text: text2 };
47562
+ break;
47563
+ }
47564
+ }
47565
+ const excerpt = url.searchParams.get("excerpt");
47566
+ if (excerpt) reference2.meta = { excerpt };
47567
+ return reference2;
47568
+ };
47524
47569
  const normalizeAssetType = (value) => {
47525
47570
  if (!value) {
47526
47571
  return null;
@@ -47609,7 +47654,8 @@ const parseAthenaCitationLink = ({
47609
47654
  url,
47610
47655
  assetId,
47611
47656
  assetIds,
47612
- assetType: normalizeAssetType(url.searchParams.get("asset_type") ?? url.searchParams.get("type"))
47657
+ assetType: normalizeAssetType(url.searchParams.get("asset_type") ?? url.searchParams.get("type")),
47658
+ reference: parseCitationReference({ url, assetId })
47613
47659
  };
47614
47660
  };
47615
47661
  const isAthenaCitationUrl = ({
@@ -56278,6 +56324,8 @@ function isAthenaAssetCitationClickEvent(value) {
56278
56324
  function isAthenaAssetCitationActionEvent(value) {
56279
56325
  return typeof value === "object" && value !== null && "type" in value && value.type === ATHENA_ASSET_CITATION_ACTION_MESSAGE && "version" in value && value.version === 1 && "action" in value && value.action === "open-in-spaces" && "reference" in value && typeof value.reference === "object" && value.reference !== null && "id" in value.reference && typeof value.reference.id === "string";
56280
56326
  }
56327
+ const DEFAULT_ASSET_EMBED_READ_ONLY = false;
56328
+ const DEFAULT_ASSET_EMBED_DISPLAY_MODE = "full";
56281
56329
  function buildAssetEmbedRequestBody({
56282
56330
  assetId,
56283
56331
  readOnly,
@@ -56511,9 +56559,9 @@ function useAssetEmbed(assetId, options = {
56511
56559
  backendUrl: ""
56512
56560
  }) {
56513
56561
  const {
56514
- readOnly = false,
56562
+ readOnly = DEFAULT_ASSET_EMBED_READ_ONLY,
56515
56563
  expiresInSeconds = 60 * 60 * 24 * 30,
56516
- displayMode = "minimal",
56564
+ displayMode = DEFAULT_ASSET_EMBED_DISPLAY_MODE,
56517
56565
  backendUrl,
56518
56566
  appUrl,
56519
56567
  apiKey,
@@ -56606,8 +56654,8 @@ const AUTH_SYNC_INTERVAL_MS = 6e4;
56606
56654
  const AthenaAssetEmbed = ({
56607
56655
  assetId,
56608
56656
  reference: reference2,
56609
- displayMode = "full",
56610
- readOnly = true,
56657
+ displayMode = DEFAULT_ASSET_EMBED_DISPLAY_MODE,
56658
+ readOnly = DEFAULT_ASSET_EMBED_READ_ONLY,
56611
56659
  expiresInSeconds,
56612
56660
  citationBehavior,
56613
56661
  onCitationClick,