Skip to content

TRE Web User Interface

This project contains a React-based web UI which covers the core aspects of a TRE, for researchers and workspace owners.

Chosen UI Stack + Components

The UI is built upon several popular web frameworks: - React v18 (created via create-react-app, with all build configurations left as defaults) - Typescript - React Router v6 for client side routing - Fluent UI Fluent UI Docs - MSAL v2: AAD authentication msal-react docs

Folder structure

├── app                    - Root of the React application
│   ├── build              - Location of compiled files after build process
│   ├── public             - Location for static HTML to bootstrap the app
│   ├── src                - All .tsx components
│   ├── index.tsx          - Entry point for the app
│   ├── App.tsx            - Wrapper and routing for the app
│   └── config.source.json - JSON file to be used as source file for autogenerated config

AuthN + AuthZ

For further details on the auth setup, see Auth.

As stated above, AAD is used for Authentication and Authorization. There are 3 AAD apps involved here: - TRE UX. This is the app that the user authenticates against. Once authenticated, the client will request an access token for the TRE Api. - TRE Api. In the access token response from this app we get the user's role membership for TRE-level roles (TREAdmin / TREUser). Based on these role memberships, aspects of the UI will be made available. If the user is in a TREAdmin role, they will see buttons to create workspaces for instance. When the user navigates into a Workspace, the client will request an access token for that Workspace App. - Workspace App(s). Each TRE workspace will have a workspace app registration. The Application Id URI for each workspace app is stored in the Workspace resource object in Cosmos, and the client uses this URI to gain an access token for that particular workspace.

Workspace app registrations may be reused across multiple workspaces in development scenarios. From this access token we can find the Workspace-level roles the user is in (WorkspaceOwner / WorkspaceResearcher). These are in turn used to show/hide features of the UI.

React Contexts

The React Context API is a clean way to handle a limited amount of global state, and is used for a few scenarios in this project: - TRE Roles Context: A context provides details of the base TRE roles a user is in, which can be consumed anywhere throughout the app - Workspace Context: Tracks the currently selected Workspace, and the roles the user is in for that Workspace. This context is used for nested components to be able to authenticate against the correct AAD App via workspaceCtx.workspaceApplicationIdURI. - Create Form Context: A context to control the Create / Update form behaviour. - Notifications Context: Tracks all the in-progress operations currently running. For each operation, the Notifications panel also uses this context to broadcast Component 'actions' which are subscribed to by downstream components. This way, a resource component does not have to track it's own changes, and can be 'told' by the Notifications Context whether it should refresh / lock etc.

Custom Hooks

Hooks are used throughout the project, and a couple of custom hooks were written to abstract common logic: - useAuthApiCall: A way to encapsulate an authenticated fetch request and provide a simple interface for downstream components to use. - useComponentManager: This hook subscribes to changes broadcast from the Notifications panel, via the context. A component can simply add this hook to start subscribing to changes and react accordingly.


The UI is deployed as part of the tre-deploy make target (unless you set deploy_ui=false under tre defaults section in your config.yaml file).

To re-deploy just the UI (after an initial deploy), run make build-and-deploy-ui from the root of the dev container. This will: - Use the environment variables from your deployment to create a config.json file for the UI - Build the source code, via yarn build - Deploy the code to Azure blob storage, where it will be statically served behind the App Gateway that also fronts the APi.