pkg/ui/ARCHITECTURE.md
This repository uses the Typescript language, and the React, and Redux libraries to build a large complex UI app. Familiarity with these 3 technologies is critical to understanding what's going on and making changes with intention.
All three technologies have wonderful documentation which you're encouraged to start with when learning.
A big obstacle to understanding how React and Redux work is the fact that both libraries hide the call graph from your application. This can make it hard to mentally trace code because the calls connecting portions of your app are simply not in your codebase. You are required to understand some React and Redux internals to make the application's architecture legible.
Why? React is a library for building interactive UIs. It lets us use a "Component" pattern to define composable views based on what data inputs we have and then the library takes care of updating those views when the data changes.
The React docs are very good at quickly walking you through what you need to know. You can either follow a Practical Tutorial or a tour of Main Concepts. Both are great, not too long, and will teach you what you need to be productive.
Note: It will be hard for you to make progress if you don't understand JSX syntax, and what "props" and "state" are with respect to React Components.
In addition, the Thinking in React page contains some great paradigm-shifting ideas and also links to the props vs state FAQ question that is usually the first source of confusion for new developers.
The React lifecycle diagram
is a great tool for understanding how simple React's mental model can be. The key
to understanding how the Component model works is knowing that anytime the props
or state change within your Component, the React runtime will automatically call
render() again on your component and all the components underneath it in the
hierarchy to determine if anything new should be rendered to the DOM.
Why? Redux is a library for managing complex application state in your UI. We use it to retrieve and store all the information DB Console needs from CRDB in one big tree of data and then slice portions of it out to feed into React Components for rendering. In addition, any user interaction with the app that requires interaction with CRDB, will almost certainly pass through the Redux framework.
The Redux docs are very detailed but approachable and use simple examples. It is recommended that you work through the Overview to get a high-level understanding. In particular the data flow diagram can help with the basics.
Note: it will be hard for you to make progress if you don't understand what the store, reducers, and actions are at a high level.
For the most part, change you make to DB Console will involve reading in new data from existing endpoints in order to render something different. Your focus should be on the Redux selectors which are functions of the global state.
More specifically, we use the reselect library that provides helpers for
automatically creating memoized selector functions of our global state. For
example, one place where we use these is in the Statements Page to compute the
data we need to render inside our table. The data provided by CRDB isn't in a
format that can be directly put into the table component so we need to do some
pre-processing on it (whether the UI should really be responsible for this is
outside the scope of this doc but that's certainly a good question to ask!).
Here's a diagram that can help explain how the data on the Statements Page table gets there:
You may need to modify a selector function to pass the new piece of data down to the component's props for rendering. Otherwise, it may just transparently be available in your component's props if it's simply adding a new field and your selectors aren't radically changing the data shape after it comes back from the API.
You will need to define a new cachedDataReducer instance or something similar
if you want to add a big chunk of data to the app state. See apiReducers.ts
for examples of how these are defined.
You can see this using the Redux DevTools plugin. Open DB Console, then launch DevTools, click on the Redux tab, and then click "State" in the section selector, and then the "Tree" tab right below. This will show you an interactive tree with the application state.
CachedDataReducer?This is a small internally created library that manages API calls to CRDB and tracks their execution with Redux. It makes the access of endpoints somewhat uniform in nature. In addition the library can automatically refresh the data for you and report errors if it can't be retrieved etc.
Note: Many Redux "best practices" are quite new so documentation you read online likely won't reflect the patterns you see in this codebase today. It's up to you to assess how valuable it might be to refactor or write new Redux code to build your feature