Git Product home page Git Product logo

viewer's Introduction

iTwin Viewer

Copyright © Bentley Systems, Incorporated. All rights reserved.

The iTwin Viewer is a configurable iTwin.js viewer. This monorepo contains the iTwin Viewer npm packages, as well as sample applications to provide examples of their usage. Each package in the repository contains a README with specific information pertaining to the package.

Name Folder Description Version
@itwin/viewer-react packages/modules/viewer-react Contains the base iTwin Viewer React component npm version
@itwin/desktop-viewer-react packages/modules/desktop-viewer-react Contains the desktop version of the iTwin Viewer React component npm version
@itwin/web-viewer-react packages/modules/web-viewer-react Contains the web version of the iTwin Viewer React component npm version
@itwin/cra-template-web-viewer packages/templates/cra-template-web-viewer CRA Template that contains the iTwin Web Viewer npm version
@itwin/cra-template-desktop-viewer packages/templates/cra-template-desktop-viewer CRA Template that contains the iTwin Desktop Viewer npm version

Contributing

For information on how to contribute to this project, please read CONTRIBUTING.

viewer's People

Contributors

a-gagnon avatar achrysaetos avatar anduong249 avatar aruniverse avatar ben-polinsky avatar calebmshafer avatar dustinlebsock avatar gerardasb avatar guillar1 avatar gytiscepk avatar hl662 avatar imodeljs-admin avatar jake-screen avatar johnnyd710 avatar kckst8 avatar mdastous-bentley avatar michaelbelousov avatar raplemie avatar samejima-san avatar saskliutas avatar smmr-dn avatar spap975 avatar stefanretief avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

viewer's Issues

"Snap Modes" not having expected effect

The "Snap Modes" menu is not having the expected effect on tools. This behavior is different than what is observed in Design Review.

Steps:

  • Open viewer app with default ui or Frontstage Sample.
  • Start "Measure Tool"
  • Open "Snap Mode" menu
  • Select a different mode than "keypoints"

Expected:

  • The measure tool snap will respect the snap mode selected in the "Snap Mode" menu.

Observed:

  • The measure tool snap will continue to snap to keypoints.

Setup GitHub releases

Begin to use the Releases tab to log our changes for each release. We should automate this as much as possible, potentially taking advantage of rush change logs where applicable

Viewer application failing to run built version of app

Initially reported by @am-work-1 and also reported by EarthCam

When working with a viewer application, it works properly when starting in dev mode, by running npm start. When running npm run build and then trying to serve the built application, the application will succeed at building but fail when running. The error that occurs is that SparseTree.ts from components-react fails to load properly. The application will will get to the end of the index.tsx file before throwing the error seen below.

minify-error

It was found that the issue is occurring when the viewer does not use tree-widget from @itwin/viewer-components-react. If tree-widget is initialized, the above error does not occur.

From investigation by @saskliutas, If tree-widget from viewer-components-react is commented out it tries to remove all unused code from the final bundle. Code from components-react that is related to ControlledTree is then removed. However, there are some leftover code that is causing this error.
It has been found that unless the user initializes tree-widget from viewer-components, then the minimizer from react-scripts does not remove code related to ControlledTree from the bundle and everything works fine.

Reproducible steps:

  1. create a new viewer application with npx create-react-app@latest my-app-name --template @itwin/web-viewer --scripts-version @bentley/react-scripts
  2. Set up .env file according to the README.md
  3. run npm run build
  4. run serve -s build, will work properly
  5. In App.tsx, comment out code related to TreeWidget and its UI provider
  6. run npm run build
  7. run serve -s build, will start up, but fail before loading any components

Currently known ways to workaround:
Modify node_modules/@bentley/react-scripts/config/webpack.config.js by adding module: true to the terserOptions object
path

terser_option

Another way is by setting the environment variable of "DISABLE_TERSER" to true, this allows the built application to run properly. This can be set in the command line, or in the .env file
env_screenshot

Preferring configuration over process.env parameters for initialization

Many of iTwinjs classes depend on process.env parameters to initialize variables. E.g. urlPrefix for buddi urls. This approach initializes the vairables at the build time itself.
At 2.19.x it used to accept the parameters using config.
We need similar way of specifying the configuration at runtime.
e.g. following initialization code in itwin viewer react
https://github.com/iTwin/viewer/blob/master/packages/modules/viewer-react/src/services/BaseInitializer.ts (line 214)

It forces developer to create separate builds for separate environments. It is particularly true for the static websites. Due to this dev teams can not follow the **build once, deploy everywhere** practice. This impacts almost all iTwin packages.

Secondly if we build any other component wrapping iTwinjs component (e.g. Mendix widget). Then the widget becomes environment specific. So if developer needs to take the widget and use in a test app in test environment, it would still point to the imodel in production environment as the widget built will not have the env prefix. This can put limitations on testing our component while integrating them in other platforms

Default tools gone with 3.2.0

Hi,

I recentley upgrated from 3.1 to 3.2, and I just noticed default tools are no longer there with my itwin viewer.

Previously (3.1):
Capture

Now (3.2) :
image

Is there something that I missed for the upgrade ?
Thanks
Jiayi

@itwin/error-handling-react missing dependency

@itwin/error-handling-react package depends on @itwin/core-react because it imports sass styles from there. However @itwin/core-react is not in the dependencies of @itwin/error-handling-react. If you happen to use error handling package independently, then sass transpiling fails because of unresolvable imports.

no way to create a sign in frontstage without first loading a snapshot model

looking at this line of BaseViewer, the viewer won't load unless IModelApp's authorizationClient is authorized, which won't
happen until either:

I am trying to migrate an application from the older @bentley/itwin-viewer-react, but I was using a custom default frontstage to handle authenticating users, which is no longer possible. Is it possible to re-enable the previous behavior?

Add additional initialization callback

Weigh pros/cons of moving onIModelAppInit to after total initialization. Failing that, add another callback when all deps are initialized.

From @ali Aslam

"We want to do all our initializations in onIModelAppInit, but it seems the event is called very early before the ui/presentation initialization. Some of our initialization that depends on presentation being initialized fails in this callback.

Is it possible to introduce a third event or to change the location of onIModelAppInit firing position to end of BaseInitializer.initialize (here)? Or maybe you can notify using a new ‘onImodelJsInitialized’ prop which gets set when initialization is finished (like here)."

Angular Viewer

Create a basic Viewer sample with Angular. Can use this repo as a model. The goal is to have a new repo (viewer-sample-angular) in the iTwin org that provides an example of a simple viewport, similar to the Typescript sample, that is built with Angular components. Should use the latest version and tools (13? + CLI?)

[web-viewer-react] How to specify the root container when loading an ITwin

We have integrated an ITwin in our site but it is not the only element on the page. It's part of a dashboard. However when we load the ITwin , a class is added to body and some styles outside of the ITwin container are altered (fonts, background colors, etc).

I tried to search the documentation but could not find an example where the IModel root can be set to a div in the page instead of the body and how to isolate styles from the rest of the app. Is this possible and if yes, how can we do this?

Here are the version of the dependencies we use:

 "dependencies": {
    "@apollo/client": "^3.5.10",
    "@bentley/icons-generic": "^1.0.34",
    "@itwin/appui-abstract": "^3.2.4",
    "@itwin/appui-layout-react": "^3.2.4",
    "@itwin/appui-react": "^3.2.4",
    "@itwin/browser-authorization": "^0.5.1",
    "@itwin/components-react": "^3.2.4",
    "@itwin/core-bentley": "^3.2.4",
    "@itwin/core-common": "^3.2.4",
    "@itwin/core-frontend": "^3.2.4",
    "@itwin/core-geometry": "^3.2.4",
    "@itwin/core-i18n": "^3.2.4",
    "@itwin/core-markup": "^3.2.4",
    "@itwin/core-orbitgt": "^3.2.4",
    "@itwin/core-quantity": "^3.2.4",
    "@itwin/core-react": "^3.2.4",
    "@itwin/core-telemetry": "^3.2.4",
    "@itwin/imodel-components-react": "^3.2.4",
    "@itwin/imodels-access-frontend": "^1.0.2",
    "@itwin/imodels-client-management": "^1.1.0",
    "@itwin/itwinui-react": "^1.40.1",
    "@itwin/presentation-common": "^3.2.4",
    "@itwin/presentation-frontend": "^3.2.4",
    "@itwin/property-grid-react": "^0.7.1",
    "@itwin/reality-data-client": "^0.9.0",
    "@itwin/tree-widget-react": "^0.4.7",
    "@itwin/web-viewer-react": "^3.0.3",
    "@itwin/webgl-compatibility": "^3.2.4",
    "@svgr/webpack": "4.3.3",
    "bootstrap": "^4.6.1",
    "debug": "^4.3.4",
    "file-saver": "^2.0.5",
    "graphql": "^16.5.0",
    "history": "^4.10.1",
    "jwt-decode": "^3.1.2",
    "oidc-client": "^1.11.5",
    "react": "^17.0.2",
    "react-bootstrap": "^1.6.3",
    "react-dom": "^17.0.2",
    "react-full-screen": "^1.1.1",
    "react-redux": "^7.2.6",
    "typescript": "^4.7.4"
  },

Allow multiple RPC interfaces to be registered across multiple backends

The current API today is mostly centered around registering a single backend for use by all of the RPCs that would be registered to the iModelApp.

We need to update that to start thinking about how we let people register an RPC, or group of RPCs, with a specific backend url and allow multiple to be configured

react eslint error

Start apps/web-viewer-test. Error appears:

ERROR in [eslint] Plugin "react" was conflicted between "package.json » ../../../common/scripts/.eslintrc.ts.json » ./.eslintrc.ts.base.json » plugin:react/recommended" and "BaseConfig » .../source/viewer/common/temp/node_modules/.pnpm/eslint-config-react-app@****

Regression in how the React Viewer determines that it needs to re-render between versions 3.0.0 and 3.1.0.

The Issue
If the React Viewer component has a sibling component that causes the parent component to re-render, then the Viewer also re-renders even though no new props were provided to the Viewer.

My guess is that on each re-render, the Viewer thinks its props are being recalculated if those variables/functions are not memoized or constant.

The Version & Package
This issue was observed with the package @itwin/web-viewer-react on version 3.1.2. I was able to reproduce the behavior in version 3.1.0 as well. However, the behavior is not present in versions 2.x nor version 3.0.0.

How to Reproduce
Create a new iTwin Viewer application on version 3.1.x. In the top-level App component that renders the Viewer, add a sibling to the Viewer that causes some state change so that the parent re-renders (the state change should not change any state that the viewer consumes).

If you change the @itwin/web-viewer-react version to 3.0.0, you will notice that the Viewer application will no longer re-render when its sibling changes state.

What was Expected
It is expected that the Viewer would behave the same as in previous versions (3.0.0 and 2.x) when determining if it should render. In version 3.1.x, it seems that all of the props to the Viewer need to be memoized. This was not the case in previous versions.

Examples
I have put together 3 quick sandboxes to highlight the issue:

  1. A sandbox showing the unusual behavior in version 3.1.2: https://www.itwinjs.org/sandbox/AlfonsoMartello/3.x-Viewer-Rerender-Regression
  2. A sandbox with identical code showing different behavior in version 2.x (the expected behavior): https://www.itwinjs.org/sandbox/AlfonsoMartello/2.x-Viewer-Rerender-Regression
  3. A sandbox in version 3.1.2 showing a change that makes the behavior the same as in version 2.x:
    https://www.itwinjs.org/sandbox/AlfonsoMartello/3.x-Viewer-Rerender-Constant

Below is a gif of the expected behavior (this is from an app using version 3.0.0):
2e9be4e1-6b14-435b-9ac8-bb2561c47514

Below is a gif of the unexpected behavior (this is from an app using version 3.1.0):
ac768f7a-8130-44ed-8508-0f7b3552589b

Enhancement to configure a redux middleware

Currently we have some table components that we would like to use as a UI Widget provider. But these components are using redux thunk. Can a support to configure a redux middleware also be provided?

Maximum call stack size exceeded when realityDataAccess is supplied

The viewer doesn't work anymore when realityDataAccess is supplied :

const realityDataAccessClient = useMemo(
    (): RealityDataAccessClient => {
        const realityDataClientOptions: RealityDataClientOptions = {
            baseUrl: "https://" + process.env.IMJS_URL_PREFIX + "api.bentley.com/realitydata",
            authorizationClient: authClient
        };
        return new RealityDataAccessClient(realityDataClientOptions);
    },[authClient],
);
<Viewer
    authClient={props.authClient}
    blankConnection={{
        name: "Test",
        location: Cartographic.fromDegrees({longitude: -75.686694, latitude: 40.065757, height: 0}),
        extents: new Range3d(-1000, -1000, -100, 1000, 1000, 100),
        iTwinId: process.env.IMJS_PROJECT_ID
    }}
    enablePerformanceMonitors={false}
    realityDataAccess={props.realityDataAccessClient}                        
/>

bug

Removing
authorizationClient: authClient
from reality data access client initialization seems to fix the error.

Environment :
@itwin/web-viewer-react version: 3.1.1
iTwinJs : 3.4.6

Might be related to #224 ?

expose defaultFrontstageProvider Id

I would like to request the exposure of the defaultFrontstageProvider.id in viewer-react/src/hooks/useFrontstages.js file. Currently, our codebase relies on checking the frontstage Id to determine if it is the default one. However, it appears that the defaultFrontstageProvider.id is subject to change in the 4.x version.

To avoid future manual modifications and ensure a consistent frontstage Id, it would be greatly beneficial if the default frontstage Id could be exposed as a constant in the useFrontstages.js file.

Thank you for considering this request.

Default packages used by visualizer do not follow semantic versioning

Followed instructions at: https://developer.bentley.com/tutorials/web-application-quick-start/

  1. Executed: npx create-react-app your-app-name --template @itwin/web-viewer --scripts-version @bentley/react-scripts

  2. Configured client id, etc.

  3. Update any of the following packages to a new minor version (which should not include breaking changes)

@itwin/browser-authorization 0.5.1 → 0.8.0
causes build to fail due to breaking change:

Attempted import error: 'BrowserAuthorizationCallbackHandler' is not exported from '@itwin/browser-authorization' (imported as 'BrowserAuthorizationCallbackHandler').

TS2305: Module '"@itwin/browser-authorization"' has no exported member 'BrowserAuthorizationCallbackHandler'.
7 | import "./index.scss";
8 |

9 | import { BrowserAuthorizationCallbackHandler } from "@itwin/browser-authorization";
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
10 | import React from "react";
11 | import ReactDOM from "react-dom";
12 |

@itwin/property-grid-react 0.5.5 → 0.9.0
causes npm install to fail due to new dependency on iTwin v4 package (a -dev dependency!)

npm ERR! code ETARGET
npm ERR! notarget No matching version found for @itwin/appui-react@^4.0.0-dev.13.
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.

@itwin/tree-widget-react 0.4.7 → 0.8.0
causes npm install to fail due to new dependency on iTwin v4 package (a -dev dependency!)

npm ERR! code ETARGET
npm ERR! notarget No matching version found for @itwin/appui-react@^4.0.0-dev.13.
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.

Changes to minor version should not break applications: MINOR version when you add functionality in a backwards compatible manner - see: https://semver.org/

Changing dependencies to point to the next major version must have a major version change as well, going from a 0.5.5 to a 0.9.0 should not do this.

Finally, referring to a -dev version, which is not available, is a bad practice.

Add a viewId prop

If provided, use it to set the view. Potentially need a source here to support briefcase viewstate vs View State service viewstate vs ??? viewstate

Potentially support it as a query parameter in the CRA template as well

Update default walk tool

"I just noticed that we are now back to using the old walk tool by default in the iTwinViewer. Was that intentional?

The “new” walk tool uses WASD keys for forward, back, left, right and mouse to look around.
The “old” walk tool uses the mouse to walk front to back and look side to side and ctrl-mouse to look around.

In my opinion, the newer tool is much easier to use."

thanks @Josh-Schifter for reporting

Maximum call stack size exceeded when localization is supplied

Mounting this MyViewerComponent produces the following error:

import { ITwinLocalization } from "@itwin/core-i18n";
import { Viewer } from "@itwin/web-viewer-react";

function MyViewerComponent(): ReactElement {
  const [localization] = useState(() => new ITwinLocalization());
  return (
    <Viewer
      authClient={authClient}
      enablePerformanceMonitors={true}
      iTwinId={iTwinId}
      iModelId={iModelId}
      localization={localization}
    />
  );
}
Uncaught RangeError: Maximum call stack size exceeded
    at Function.keys (<anonymous>)
    at isEqual6 (index.ts:43:24)
    at isEqual6 (index.ts:53:26)
    at isEqual6 (index.ts:53:26)
    at isEqual6 (index.ts:53:26)
    at isEqual6 (index.ts:53:26)
    at isEqual6 (index.ts:53:26)
    at isEqual6 (index.ts:53:26)
    at isEqual6 (index.ts:53:26)
    at isEqual6 (index.ts:53:26)

When localization is not supplied through props, this error doesn't reproduce.

Environment:

  • @itwin/web-viewer-react version: 3.1.1
  • iTwin.js version: 3.4.5

Add automated e2e tests to test apps

We should write playwright tests (I see no reason to reach for Cypress at this point) for the various test-viewer apps. We can run the tests in CI and catch improper changes before they're merged.

Switching to Frontstage with Blank iModelConnection does not cause the active iModel Connection to be blank

When a Frontstage is declared, the viewState and iModelConnection can be passed as arguments. Passing a blank view state and a blank iModelConnection causes the view to appear blank. I would have expected the active iModelConnection to be reported as blank as well. However, UiFramework.getIModelConnection() still reports the iModelConnection as not being blank.

A sandbox demonstrating this behavior can be found here: https://www.itwinjs.org/sandboxes/AlfonsoMartello/Blank-iModel-Connection-Frontstage-Issue.

Note: The sandbox is currently using [email protected], but I was able to reproduce this behvaiour in an iTwin Viewer application using [email protected].

tree view search chaotic animations

please redirect me if this is not the correct place for this (maybe the widget has its own repository)

I am seeing the following kinds of chaotic movement when the tree view animations are running. The framerate in the gifs does not represent the framerate seen by the user, which appears to happen every refresh so probably 60fps, whereas the gifs appear much slower (although still unnatural)

This one occurs in the default state of the viewer when starting, every frame it goes back and forth where to position the search
icon and overflow bars appear:
1aevuu9m64

This one occurs when there is overflow of the visibility icons and you try to open+close a search:
FV81mAPptF
This one really does not capture the maybe 20 frames of chaos that occur while it is closing

I can provide my application for reproducing if necessary.

better handle initialization errors

The useWebViewerInitializer hook assumes that the "initialized" promise is defined in the WebInitializer class. The issue is if a user has already initialized IModelApp, it will not be defined, due to no "else" condition here:

if (!IModelApp.initialized && !this._initializing) {

this results in a "cannot find "then" of undefined" error instead of returning the promise if this._initializing and rejecting the promise with a meaningful error (let the user know to use the useWebViewerInitializer hook instead of calling IModelApp.startup themselves) if IModelApp.Initialized.

the same could occur in the desktop package's DesktopInitializer class, so it should be fixed in both.

add .npmignore to modules we publish

take a look at https://github.com/iTwin/viewer/runs/6692137123?check_suite_focus=true#step:4:1899
no need for us to publish the test files
add a .npmignore to every module we publish (web/desktop/base viewer pkgs), should publish everything but the tests

sample file looks like:

# start off ignoring everything, and then add back only the files we want
*
!*.md

!lib/**/*.d.ts
!lib/**/*.d.ts.map
!lib/**/*.js
!lib/**/*.js.map

lib/**/tests/

should be able to run npx pkgfiles to see what gets published

allow specifying that you want a briefcase when giving the desktop viewer an iTwinId+iModelId

The existing local briefcase support on desktop seems to require that you download a briefcase yourself and pass its file path to the viewer.

Would it be possible to add a new optional prop to the desktop viewer that requests that the iTwinId and iModelId are used to check the cache for or download the briefcase for you and give you a briefcase connection instead of a checkpoint connection on the frontend?

Add remaining ui providers to the Viewer CLI

Currently, the Viewer CLI will add ui providers for the Tree View and Property Grid based on responses from the user. It should also add the ViewerNavigationToolsProvider, ViewerContentToolsProvider, and ViewerStatusbarItemsProvider when the "intermediate" or "advanced" template is selected. This configuration should go in the "ui.mjs" file (dependencies if needed) as well as the advanced.ts and intermediate.ts files in the extensions folder.

The CLI is currently in the "cli" branch in the "create-itwin-viewer" module

Providing a frontstage provider with "requiresIModelConnection: true" will always create a new connection

When providing a frontstage with "requiresIModelConnection: true" will always close the current connection and open a new one, regardless if the contextID or iModelId are the same. Omitting "requiresIModelConnection: true" and providing a frontstage after the viewer has opened a conenction will never update the viewer's current frontstage.

Example: We need to provide a frontstage that will get a viewstate from oniModelConnected callback, with "requireIModelConnection: true"
Load viewer with contextId and iModelId
onIModelConnected callback will call a method to get viewstate.
Viewstate is provided to frontstage in constructor call
frontstage array including new frontstate and "requiresIModelConnection: true" is provided to viewer
Viewer will close current iModel Connection, and open new connection, calling onIModelConnection callback
Repeat steps 3-6.

[viewer] expose option to hide tool settings

when you bootstrap a new viewer app via the template and if you disable everything so you get the base viewer, you still get the tool settings. update the default frontstage we use to hide that by default

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.