ReactJS

Warning

This article describes the setup for the v2 of the VSETH Frontend components. v2 is currently work in progress. You can see updates here:
https://gitlab.ethz.ch/groups/vseth/0403-isg/-/milestones/1

"Write once, run anywhere"

The goal of the frontend architecture and its related packages is to enforce a consistent frontend design while making it as easy as possible for developers to develop applications rapidly. It defines a rough structure that is consistent between all the different groups of VSETH but also allows groups to customize applications that they want to deploy. That means that if a group wants an instance of an application it's as easy as changing one environment variable to apply the custom theme of that group if the application is built on the VSETH frontend framework. At the same time the architecture makes it very easy to develop applications that can be customized in that way because most application developers won't have to handle theming by themselves.

The customization can be done gradually so that each it is very easy to integrate your group. That means that you can just upload your logo and inherit the theme of one of your parent groups, but if you want to you can also invest more time to ensure that the applications look exactly like you want them to look like by writing a custom theme.

As one might have already noticed the frontend architecture heavily depends on the people api which it uses to access the the organizational structure of VSETH which plays an essential role. The main resource types are all resolved by inheritance: If e.g. a group like vseth-1116-vis-vs-q doesn't specify a logo the static server will check if vseth-1116-vis-vs defined a logo, if that's not the case it will traverse the tree until it reaches the root node or an asset that matches the requested asset type is found. That means that if you don't specify an asset the corresponding asset of VSETH will be used most of the time.

Currently assets are not merged but assets completely overwrite that asset for all groups in their subtree: If you customize any value in your theme config all the other values will default to the VSETH global default instead of inheriting the value of the parent node. That means you currently only get the choice of either having a completely custom theme or inheriting the theme config from the parent node. The VSETH group is special in that way because it's the only node that is merged into your configuration.

Unstructured assets like images (currently logo and signet) are currently stored in the repository of the static server and structured data (like the theme data) is stored in asset nodes attached to groups and served by people-api.

Changing the theme of your group

  1. Visit fe.vseth.ethz.ch and change the theme values to your liking
  2. Download the generated config `.yaml` file
  3. Create a new issue with your file and the groupId of your group.
  4. Visit asset-inspector.ethz.ch and test your icon and signet using your newly created theme.
  5. Create an issue on static with your logo and signet

FAQ

I want to write a custom theme because the default configuration options don't meet our requirements. Where should I start?

  1. Start to learn SASS if you haven't already.
  2. Look at some of the existing custom themes.
  3. Create a new branch and create a merge request when you are done.

Package + Repo Overview

@vseth/components

The @vseth/components package is the central package that exports react components which can be used in vseth applications. By itself the components are not styled and you will need to import @vseth/npm-vseth-theme in some way. Certain aspects of theming will be handled by @vseth/components module if they need js support. One of the main aspects that have to be handled in that way is the logo component that loads the correct logo depending on the globId that is set in the surrounding VSETHContext component. If no globId is set it will search for a tag with the id vseth-context-data from which it can pull the required data.

The @vseth/components package is only build only when components are changed and everything that has to handle theming is done at runtime. It also provides the developer with information about the provided globId through some custom hooks and components. No rebuild is necessary when a theme changes. The files in dist are not required to be hosted on a static server and the module should always be included through npm so that semantic versioning can be used.

@vseth/npm-vseth-theme

The @vseth/npm-vseth-theme package exports css files that handle the styling of @vseth/components. The class names are static and theme-independent and can be used in a static context as well, the structure is similar to bootstrap. The application also handles theming: During a build the build script connects to people-api via gRPC to get the effective theming configuration of each globId that has some necessary information associated with it. Using the theme configuration a scss file is generated that imports the main theme, but overwrites certain variables that can be set.

The theming configuration also allows a group to specify a custom theme directory that should be used instead of the main scss source. This feature can be used to further customize the look and feel of a groups theme. The build script generates various css files for each globId with a theme asset and writes them to the dist folder. The theme package has to rebuild when a theme changes.

static.vseth.ethz.ch

The static server provides a structured interface to assets associated with each globId that exists. Assets like logo and signet are stored in the static repo itself and are hosted accordingly. Because logo, signet and theme are resolved depending on the tree structure the static server has to connect to people-api using gRPC.

It also mirrors the newest @vseth/npm-vseth-theme version so that the correct css file is served.

Based on a request and the tree structure of the VSETH groups it resolves which theme / logo it has to respond with. These responses are cached in a file structure that resembles the structure of the API so that the following requests can be hosted by a static file server. As theme data and the tree structure itself can change the static server also periodically removes the cached data and refetches the tree from people-api.

Use cases for frontend developers

It's recommended to use the provided react components, but we are also working on a static version so that you can integrate some common components into small server-side rendered applications. The collection of static components is thought to enhance existing small applications, for any application that requires some sort of user interaction you should probably use the react components.

If you are developing a new application it is recommended to use one of the existing templates which makes it very easy to integrate into the VSETH infrastructure.

The diagram on the top probably looks more complicated than it needs to be. For most applications you will only have to care about three things:

  1. Loading a theme css file
  2. Import the component library
  3. Ensure that the server injects the correct groupId

We also do not recommend creating components with custom CSS as this may limit your compatibility with all existing themes. In the event that you need a custom component, we hope that the utility classes that all the themes are required to provide can help you build your component.

Further details can be found in the front-end documentation: http://fe.vseth.ethz.ch.

React Applications associated with a single group

Applications that are associated with a single group can link to both the theme and the component library statically.

Surround your <App/> with a global <VSETHContext globId={some-glob-id}>[...]</VSETHContext>. This configures the component library so that the correct logo / signet is displayed in the navbar.

Don't forget to also import the theme you want to use in your index.html: <link rel="stylesheet" href="http://static.vseth.ethz.ch/groups/some-glob-id/theme.css" id="vseth-theme"/>

React Applications that can be deployed to multiple groups

React applications that can be deployed to multiple groups need to handle theming. You will need to setup your server in a way so that it accepts a globId environment variable that is used to inject the globId (%globId%) in two places:

  1. <link rel="stylesheet" href="http://static.vseth.ethz.ch/groups/%globId%/theme.css" id="vseth-theme"/>
  2. <script type="application/json" id="vseth-context-data">{"globId": "%globId%"}</script>

(1.) will load the required theme css. (2.) is required so that the components library can read the components library can set its globId accordingly. You will have to put all your components in a <VSETHContext>[...]</VSETHContext>. If you don't provide any globId it will search for a #server_data element and read the globId from the server-provided data.

Static Applications associated with a single group

As your application doesn't have to be themable dynamically you can use a static <link rel="stylesheet" href="http://static.vseth.ethz.ch/groups/some-glob-id/theme.css" id="vseth-theme"/> link. You are also required to import the static navbar component [????] from the static server. Additionally you will have to set <script type="application/json" id="vseth-context-data">{"globId": "some-glob-id"}</script> to make sure the correct icon / signet is rendered in the navbar. You can use the rest of the components using their css class names.

Static Applications that can be deployed to multiple groups

These are quite similar to static applications associated with a single group but you will have to setup your server so that it injects the correct globId that the server receives at runtime as an environment variable.

Developer FAQ (not really a FAQ because nobody asked these before)

I needed a component AB in my application XY that your component library didn't provide. Can we integrate it into the component library?

Yes, of course, we look forward to any addition. Please create a merge request in the vseth-frontend repository.

Component XY doesn't work correctly. What should I do?

We would be delighted if you opened an issue in the corresponding repository.

The component XY didn't render correctly when the them AB is used. What can I do about that?

It would probably be a good idea to open an issue in the theme repo and @ the author of the theme if it's a custom one.

How can I help?

Feel free to assign yourself an open issue in one of the repositories.