Skip to content

exposing the setView, getView, and listSavedViews api [NOT FOR MERGE YET]#177

Closed
kaung001 wants to merge 2 commits intomasterfrom
ken/expose_codemode
Closed

exposing the setView, getView, and listSavedViews api [NOT FOR MERGE YET]#177
kaung001 wants to merge 2 commits intomasterfrom
ken/expose_codemode

Conversation

@kaung001
Copy link
Copy Markdown

exposing the setView, getView, and listSavedViews api for code mode in os+

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 14, 2026

⚠️ No Changeset found

Latest commit: ebf7516

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@diegopinate
Copy link
Copy Markdown
Collaborator

diegopinate commented Apr 14, 2026

Please provide more details as to what you are trying to achieve. Some questions that would be good to answer in your PR description:

  1. What is Code Mode?
  2. How is it being used in OS+?
  3. Why is this change needed in the saved-views-react packages and isn't application specific?

Also, make sure to look at some of our already written logic for creating view states off of saved views here:

applySavedView.ts
createViewState.ts

* Lists all saved views accessible via the client supplied to {@link initViewOperations}.
* Returns an array of `{ id, displayName }` objects, or an empty array if no client is set.
*/
export async function listSavedViews(): Promise<{ id: string; displayName: string }[]> {
Copy link
Copy Markdown

@adrianclinansmith adrianclinansmith Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe listSavedViews can be done from the backend with IModelDb.Views..

See queryViewDefinitionProps and getViewStateProps.

We only need to query the frontend when we want the current state of the viewport, but the saved views are stored in the iModel, which is on the backend.

The way it's done now: backend calls frontend -> frontend calls backend -> backend receives backend value

Copy link
Copy Markdown
Collaborator

@diegopinate diegopinate Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are 2 types of "views" that are used in applications:

  1. iModel Views: Contained in the iModel as you explain
  2. Saved Views: Created dynamically and stored in the saved views API

Using IModelDb.Views only would result in the first one.

@jean-luc-deziel
Copy link
Copy Markdown

Please provide more details as to what you are trying to achieve. Some questions that would be good to answer in your PR description:

1. What is Code Mode?

2. How is it being used in OS+?

3. Why is this change needed in the saved-views-react packages and isn't application specific?

Also, make sure to look at some of our already written logic for creating view states off of saved views here:

applySavedView.ts createViewState.ts

Hi, this PR is an experimental implementation to give access to Bentley Copilot to the saved view widget. We need an API to be able to interact programmatically with saved views from the copilot. And we want that API to reside in the same repo as the widget for 2 reasons

  • keep the API in sync with the widget
  • We won't have to duplicate that API in every app that integrates Bentley Copilot

We have still a bit of work to do before we communicate with you our exact plans.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a small “view operations” API surface to @itwin/saved-views-react to support code-mode usage in OS+, allowing callers to read the active view, set the active view (from either a saved view id or ViewStateProps), and list saved views (via an injected client).

Changes:

  • Added viewOperations.ts with initViewOperations, getActiveView, setView, and listSavedViews.
  • Re-exported the new APIs (and ViewOperationsClient type) from the package entrypoint.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
packages/saved-views-react/src/viewOperations.ts Introduces new public API for reading/setting the active viewport view and listing saved views via an injected client.
packages/saved-views-react/src/index.ts Exposes the new view operations API from the main package export.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +18 to +22
export interface ViewOperationsClient {
getSavedViewDataById: (args: { savedViewId: string }) => Promise<SavedViewData>;
/** Optional: list all saved views as `{ id, displayName }` pairs for name-based lookup. */
listSavedViews?: () => Promise<{ id: string; displayName: string }[]>;
}
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

listSavedViews returns { id, displayName }, but this package consistently uses savedViewId (see SavedView.savedViewId). This inconsistency forces consumers to special-case this API and increases the chance of mixing up different kinds of ids. Consider returning { savedViewId, displayName } (e.g., Pick<SavedView, "savedViewId" | "displayName">[]) and update the JSDoc to match.

Copilot uses AI. Check for mistakes.
Comment on lines +95 to +99
const className = props.viewDefinitionProps.classFullName.toLowerCase();
if (className.includes("drawing"))
return DrawingViewState.createFromProps(props, vp.iModel);
if (className.includes("sheet"))
return SheetViewState.createFromProps(props, vp.iModel);
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

View type detection via classFullName.toLowerCase().includes("drawing"|"sheet") is brittle and can misclassify custom/derived view classes whose names contain those substrings. Prefer exact checks against DrawingViewState.classFullName / SheetViewState.classFullName / SpatialViewState.classFullName (and fall back to SpatialViewState if unknown) to make this deterministic.

Suggested change
const className = props.viewDefinitionProps.classFullName.toLowerCase();
if (className.includes("drawing"))
return DrawingViewState.createFromProps(props, vp.iModel);
if (className.includes("sheet"))
return SheetViewState.createFromProps(props, vp.iModel);
const className = props.viewDefinitionProps.classFullName;
if (className === DrawingViewState.classFullName)
return DrawingViewState.createFromProps(props, vp.iModel);
if (className === SheetViewState.classFullName)
return SheetViewState.createFromProps(props, vp.iModel);
if (className === SpatialViewState.classFullName)
return SpatialViewState.createFromProps(props, vp.iModel);

Copilot uses AI. Check for mistakes.
Comment on lines +63 to +67
export async function setView(viewIdOrProps: string | ViewStateProps): Promise<boolean> {
const vp = getActiveViewport();
if (!vp)
return false;

Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setView collapses multiple failure modes (no active viewport, missing client, client fetch failure, invalid props, view load failure, etc.) into a single false return and also swallows the underlying error. This makes it hard for callers to diagnose/configure failures. Consider either throwing (consistent with other exported APIs like applySavedView/createViewState) or returning a discriminated result that includes an error/reason code.

Copilot uses AI. Check for mistakes.
Comment on lines +47 to +53
/**
* Lists all saved views accessible via the client supplied to {@link initViewOperations}.
* Returns an array of `{ id, displayName }` objects, or an empty array if no client is set.
*/
export async function listSavedViews(): Promise<{ id: string; displayName: string }[]> {
return _client?.listSavedViews?.() ?? [];
}
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSDoc says listSavedViews returns an empty array only "if no client is set", but the implementation also returns [] when a client is set without listSavedViews implemented (_client?.listSavedViews?.() ?? []). Please either update the doc to reflect this behavior or change the implementation to fail loudly when listSavedViews is unavailable.

Copilot uses AI. Check for mistakes.
@diegopinate
Copy link
Copy Markdown
Collaborator

Please provide more details as to what you are trying to achieve. Some questions that would be good to answer in your PR description:

1. What is Code Mode?

2. How is it being used in OS+?

3. Why is this change needed in the saved-views-react packages and isn't application specific?

Also, make sure to look at some of our already written logic for creating view states off of saved views here:
applySavedView.ts createViewState.ts

Hi, this PR is an experimental implementation to give access to Bentley Copilot to the saved view widget. We need an API to be able to interact programmatically with saved views from the copilot. And we want that API to reside in the same repo as the widget for 2 reasons

  • keep the API in sync with the widget
  • We won't have to duplicate that API in every app that integrates Bentley Copilot

We have still a bit of work to do before we communicate with you our exact plans.

I want to clarify that this package is our public saved views UI components and clients for the Saved Views API, and it's not a place for experimental or internal code.

@kaung001 kaung001 marked this pull request as draft April 16, 2026 19:48
@kaung001 kaung001 closed this Apr 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants