Skip to content

Commit

Permalink
Update documentation (#83)
Browse files Browse the repository at this point in the history
Update existing and fills in missing documentation for both published
packages. Also fix broken URLs in package.json files.
  • Loading branch information
roluk committed Jun 27, 2024
1 parent 1de46cf commit c490674
Show file tree
Hide file tree
Showing 12 changed files with 146 additions and 25 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

## Packages

[@itwin/saved-views-client](./packages/saved-views-client/)
| Repository | npmjs |
| ----------------------------------------------------------- | --------------------------------------------------------------- |
| [@itwin/saved-views-client](./packages/saved-views-client/) | [link](https://www.npmjs.com/package/@itwin/saved-views-client) |
| [@itwin/saved-views-react](./packages/saved-views-react/) | [link](https://www.npmjs.com/package/@itwin/saved-views-react) |

[@itwin/saved-views-react](./packages/saved-views-react/)

## Development setup

Expand All @@ -22,7 +24,7 @@
npm start
```

* You can now edit TypeScript and CSS source files and the changes will automatically be reflected in the test app.
* You can now edit TypeScript and CSS source files and changes will automatically be reflected in the test app.

## Top-level commands

Expand Down
17 changes: 15 additions & 2 deletions packages/saved-views-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,23 @@ import { ITwinSavedViewsClient } from "@itwin/saved-views-client";

const client = new ITwinSavedViewsClient({
// auth_token should have access to savedviews:read and savedviews:modify OIDC scopes
getAccessToken: async () => "auth_token",
getAccessToken: async () => "<auth_token>",
});

const response = await client.getSavedViewMinimal({ savedViewId: "id" });
const { savedView } = await client.getSavedViewMinimal({ savedViewId: "<saved_view_id>" });
console.log(savedView); /*
{
id: "<saved_view_id>",
displayName: "Saved View",
creationTime: "2024-01-01T10:00:00.000Z",
lastModified: "2024-01-01T10:01:00.000Z",
groupId: undefined,
shared: false,
tags: [...],
savedViewData: { itwin3dView: {...} },
extensions: [...],
_links: {...}
} */
```

## Contributing
Expand Down
2 changes: 1 addition & 1 deletion packages/saved-views-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://github.com/iTwin/saved-views.git",
"directory": "packages/saved-views-client"
},
"homepage": "https://github.com/iTwin/saved-views/packages/saved-views-client",
"homepage": "https://github.com/iTwin/saved-views/tree/master/packages/saved-views-client",
"author": {
"name": "Bentley Systems, Inc.",
"url": "https://www.bentley.com"
Expand Down
53 changes: 51 additions & 2 deletions packages/saved-views-react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,59 @@

## About

A collection of React components for building applications that deal with [Saved Views](https://developer.bentley.com/apis/savedviews/overview/).
A collection of utilities and React components for building iTwin applications that deal with [Saved Views](https://developer.bentley.com/apis/savedviews/overview/).

## Documentation

### [captureSavedViewData](./src/captureSavedViewData.ts)

Captures current viewport state into serializable format. The returned data can later be used to restore viewport's view.

```ts
const { viewData, extensions = [] } = await captureSavedViewData({ viewport });
extensions.push(myCustomExtension(viewport));
console.log({ viewData, extensions }); /*
{
viewData: { itwin3dView: {...} },
extensions: {
{ extensionName: "EmphasizeElements", data: "{...}" },
{ extensionName: "MyCustomExtension", data: "my_custom_extension_data" },
}
} */
```

### [captureSavedViewThumbnail](./src/captureSavedViewThumbnail.ts)

Generates Saved View thumbnail based on what is currently displayed on the viewport.

```ts
const thumbnail = captureSavedViewThumbnail(viewport);
console.log(thumbnail); // "data:image/png;base64,iVBORw0KGoAAAANSUhEUg..."
```

### [applySavedView](./src/applySavedView.ts)

Updates viewport state to match captured Saved View.

```ts
// Capture viewport state
const savedViewData = await captureSavedViewData({ viewport });
// Restore viewport state
await applySavedView(iModel, viewport, savedViewData);
```

### [createViewState](./src/createViewState.ts)

Creates ViewState object out of Saved View data. It provides a lower-level access to view data for advanced use.

```ts
const viewState = await createViewState(iModel, savedViewData.viewData);
await applySavedView(iModel, viewport, savedViewData, { viewState });

// The two lines above are equivalent to
await applySavedView(iModel, viewport, savedViewData);
```

### React components

* [SavedViewTile](./src/SavedViewTile/SavedViewTile.tsx)
Expand Down Expand Up @@ -42,7 +91,7 @@ export function SavedViewsWidget(props) {
}
```

### useSavedViews
### [useSavedViews](./src/useSavedViews.tsx)

[useSavedViews](./src/useSavedViews.tsx) React hook provides basic functionality to jump-start your Saved Views widget. It accepts [`ITwinSavedViewsClient`](./src/SavedViewsClient/ITwinSavedViewsClient.ts) which is used to pull Saved View data and synchronize it back to the [Saved Views service](https://developer.bentley.com/apis/savedviews/overview/).

Expand Down
2 changes: 1 addition & 1 deletion packages/saved-views-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://github.com/iTwin/saved-views.git",
"directory": "packages/saved-views-react"
},
"homepage": "https://github.com/iTwin/saved-views",
"homepage": "https://github.com/iTwin/saved-views/tree/master/packages/saved-views-react",
"author": {
"name": "Bentley Systems, Inc.",
"url": "https://www.bentley.com"
Expand Down
17 changes: 17 additions & 0 deletions packages/saved-views-react/src/SavedView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,24 @@ export interface SavedView {
}

export interface SavedViewExtension {
/** Extension identifier. Saved View cannot contain multiple extensions that share the same `extensionName`. */
extensionName: string;

/**
* Serialized extension data.
*
* @example
* const extension = {
* // Unique identifier makes extension data format portable between applications because it avoids collision
* // with different implementations
* extensionName: "CustomHighlight_$5be36494-ae03-4400-bb80-24ffd9db2a87",
* data: JSON.stringify({
* description: "For illustrative purposes only. We do not provide implementation for this extensionName."
* highlightColor: "#f05599",
* models: ["0x20000000006"],
* }),
* };
*/
data: string;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ import type {
} from "./SavedViewsClient.js";

interface ITwinSavedViewsClientParams {
/** @default "https://api.bentley.com/savedviews" */
getAccessToken: () => Promise<string>;

/**
* Authorization token that grants access to iTwin Saved Views API. The token should be valid for `savedviews:read`
* and `savedviews:modify` OIDC scopes.
*/
baseUrl?: string | undefined;
*/
getAccessToken: () => Promise<string>;

/** @default "https://api.bentley.com/savedviews" */
baseUrl?: string | undefined;
}

export class ITwinSavedViewsClient implements SavedViewsClient {
Expand Down
11 changes: 7 additions & 4 deletions packages/saved-views-react/src/applySavedView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export interface ApplySavedViewSettings {
all?: ApplyStrategy | undefined;

/**
* How to handle captured {@link ViewState} data. The default behavior is to generate a new `ViewState` object and
* apply it to viewport.
* How to handle captured {@link ViewState} data. The default behavior is to generate a new `ViewState` object out of
* {@linkcode SavedView.viewData} and apply it to viewport.
*
* You can optionally provide a pre-made `ViewState` instance to conserve resources. It is usually obtained from
* {@link createViewState} result.
Expand All @@ -34,6 +34,9 @@ export interface ApplySavedViewSettings {
* applySavedView(iModel, viewport1, savedView, { viewState }),
* applySavedView(iModel, viewport2, savedView, { viewState }),
* ]);
*
* @remarks
* When neither `SavedView.viewData` nor `ViewState` is provided, current {@linkcode Viewport.view} is preserved.
*/
viewState?: ApplyStrategy | ViewState | undefined;

Expand Down Expand Up @@ -70,8 +73,8 @@ type ApplyStrategy = "apply" | "reset" | "keep";
* // e.g. when applying the same Saved View to multiple viewports
* const viewState = await createViewState(iModel, savedView);
* await Promise.all([
* applySavedView(iModel, firstViewport, savedView, { viewState }),
* applySavedView(iModel, secondViewport, savedView, { viewState }),
* applySavedView(iModel, viewport1, savedView, { viewState }),
* applySavedView(iModel, viewport2, savedView, { viewState }),
* ]);
*/
export async function applySavedView(
Expand Down
15 changes: 14 additions & 1 deletion packages/saved-views-react/src/captureSavedViewData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,20 @@ interface CaptureSavedViewDataResult {
extensions: SavedViewExtension[] | undefined;
}

/** Captures current viewport state into serializable format. */
/**
* Captures current {@link Viewport} state into serializable format. The returned data can later be used to restore
* viewport's view.
*
* @example
* import { captureSavedViewData, captureSavedViewThumbnail } from "@itwin/saved-views-react";
*
* async function saveViewport(viewport) {
* const { viewData, extensions = [] } = await captureSavedViewData({ viewport });
* const myExtensions = captureMyCustomState(viewport);
* const thumbnail = captureSavedViewThumbnail(viewport);
* return { thumbnail, viewData, extensions: extensions.concat(myExtensions) };
* }
*/
export async function captureSavedViewData(args: CaptureSavedViewDataArgs): Promise<CaptureSavedViewDataResult> {
return {
viewData: await createSavedViewVariant(args.viewport),
Expand Down
9 changes: 8 additions & 1 deletion packages/saved-views-react/src/captureSavedViewThumbnail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@ import type { ImageBuffer } from "@itwin/core-common";
import { getCenteredViewRect, imageBufferToCanvas, type Viewport } from "@itwin/core-frontend";
import { Point2d } from "@itwin/core-geometry";

/** Generates Saved View thumbnail based on what is currently visible in the {@linkcode viewport}. */
/**
* Generates Saved View thumbnail based on what is currently displayed on the {@linkcode viewport}.
* @returns base64-encoded URL string
*
* @example
* const thumbnail = captureSavedViewThumbnail(viewport);
* console.log(thumbnail); // "data:image/png;base64,iVBORw0KGoAAAANSUhEUg..."
*/
export function captureSavedViewThumbnail(viewport: Viewport, width = 280, height = 200): string | undefined {
const thumbnail = getThumbnail(viewport, width, height);
if (!thumbnail) {
Expand Down
26 changes: 21 additions & 5 deletions packages/saved-views-react/src/createViewState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@ import { extractDisplayStyle, extractDisplayStyle3d } from "./translation/displa

export interface ViewStateCreateSettings {
/**
* Normally before {@link createViewState} function returns a {@link ViewState}, its {@linkcode ViewState.load} method
* is called and awaited. You may skip this step if you intend to perform it later.
* Normally {@link createViewState} function invokes and awaits {@linkcode ViewState.load} method before returning.
* You may skip this step if you intend to perform it later.
* @default false
*
* @example
* const viewState = await createViewState(iModel, savedView.viewdata, { skipViewStateLoad: true });
* viewState.categorySelector.addCategories("<additional_category_id>");
* await viewState.load();
*/
skipViewStateLoad?: boolean | undefined;

Expand All @@ -33,14 +38,25 @@ export interface ViewStateCreateSettings {
modelAndCategoryVisibilityFallback?: "visible" | "hidden" | undefined;
}

/**
* Creates {@link ViewState} object out of Saved View data. It provides a lower-level access to view data for advanced
* use.
*
* @example
* const viewState = await createViewState(iModel, savedViewData.viewData);
* await applySavedView(iModel, viewport, savedViewData, { viewState });
*
* // The two lines above are equivalent to
* await applySavedView(iModel, viewport, savedViewData);
*/
export async function createViewState(
iModel: IModelConnection,
savedViewData: ViewData,
viewData: ViewData,
settings: ViewStateCreateSettings = {},
): Promise<ViewState> {
const viewState = await createViewStateVariant(iModel, savedViewData);
const viewState = await createViewStateVariant(iModel, viewData);
if (settings.modelAndCategoryVisibilityFallback === "visible") {
await unhideNewModelsAndCategories(iModel, viewState, savedViewData);
await unhideNewModelsAndCategories(iModel, viewState, viewData);
}

if (!settings.skipViewStateLoad) {
Expand Down
1 change: 1 addition & 0 deletions packages/saved-views-react/src/useSavedViews.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ type SavedViewUpdateProps = WriteableSavedViewProperties & { id: string; };
* the store is performed via {@linkcode SavedViewsClient} interface which could communicate, for instance, with
* [iTwin Saved Views API](https://developer.bentley.com/apis/savedviews/overview/) using `ITwinSavedViewsClient`.
*
* @remarks
* Note on the current implementation limitations. While the result of the first update action is reflected immediately,
* subsequent actions are put in a queue and executed serially. This may cause the UI to feel sluggish when user makes
* changes to Saved Views faster than the Saved Views store can be updated.
Expand Down

0 comments on commit c490674

Please sign in to comment.