In Chapter 7, we discussed how to build the structure of single-page applications. In this chapter, we will build an administrative dashboard on the home page of the SPA boilerplate that was created by using the AppRun CLI. This will demonstrate how to use AppRun to build a complex user interface and administrative interface.
An administrative interface is for administrators to configure and manage web applications. It usually is a stand-alone web application or a restricted area of an application. The administrative interface is important because it is the management tool of the applications and systems. For a consumer-facing e-commerce web application, the administrative interface is for the owner to manage the production, prices, and orders. In a line-of-business application, the administrative interface is for managing the business processes, back-end databases, and systems.
In many cases, the administrative interface has a dashboard on its home page. The administrative, or admin, dashboard provides the overall status of the applications being managed. It is a special kind of interface that usually has a complicated layout involving a lot of visualization widgets. You should try to design one that is pleasing to view and easy to use. Often it also needs to be responsive for different devices and screen sizes. The front-end part is an important part of the administrative interface and is what we will focus on in this chapter. The back end of the administrative interface is data-driven and requires security trimming, which means it displays the content based on the user permissions. The back end is beyond the scope of this chapter.
There are many third-party libraries in the JavaScript ecosystem that have already provided excellent data visualization on the front end. In general, there are two purposes for using third-party libraries: to build the page layout and style the elements as widgets and to create the widgets from the libraries. You will learn how to use the stateless components introduced in Chapter 4 to build the layout and style the elements. Also, you will learn how to integrate third-party libraries into the AppRun components using the extended AppRun architecture.
Example: An Admin Dashboard
The example admin dashboard mimics a real-world application. The top navigation is the first-level navigation that has menus to load various web pages such as the Home page, the About page, and the Contact page.
The top navigation is from the SPA boilerplate. The sidebar navigation is the second-level navigation that has the menus for the page. For example, the Home, Events, Team, and More menus are part of the Home page. We will explore more about the UI first.
Responsive UI
The responsive layout of the top navigation comes from the SPA boilerplate out of the box. We will create the side navigation menus in the “Sidebar Menu” section of this chapter. Also, we will create the side navigation menus based on an array contains the data that represents the menus dynamically.
Dashboard Widgets
The main content area of the home page has various kinds of widgets to visualize the data. There are widgets such as key performance indicator (KPI) cards, several types of notification/altering messages, a chart, and a map, as you can see from Figure 8-1 and Figure 8-2. There are also a data table widget and a widget calendar in the main content area.
Third-Party Libraries
The dashboard specification can be overwhelming the first time you look at it. The layout is complicated. The widgets are a variety of types, such as KPIs, alerts, charts, maps, data tables, and calendars. Creating all the widgets from scratch is impossible. Our plan of attack is to use the third-party libraries as much as possible.
The good news is that the development community has developed many libraries for pretty much everything, from page layout to data visualization widgets. There is probably a JavaScript library out there for anything you can think of. There is no need to re-invent the wheel. The framework we use to develop applications should always integrate easily with other libraries.
npm Scripts of This Chapter
Feature/Widget | Third-Party Library Name | Third-Party Library URL |
---|---|---|
Responsive layout Sidebar menu KPI cards Notifications/alerts | Bootstrap | |
Chart widget | Chart.js | |
Map widget | D3.js | |
Data table widget | DataTables (the jQuery plug-in) | |
Calendar widget | FullCalendar |
Extended Architecture
In the extended AppRun architecture, the event lifecycle has two optional functions: the mounted function and the rendered function. The mounted function is available only in the AppRun component architecture. The rendered function is available in the AppRun component architecture as well as in the AppRun global architecture.
When using stateful components in JSX, AppRun creates the component object behind the scenes. We don’t have access to the constructor to initialize the state. However, AppRun will call the mounted function if presented and will pass the JSX properties as the parameters to the mounted function. By using the mounted function, we can initialize the state based on the JSX properties.
The rendered function plays a different role in the AppRun event lifecycle. Upon each AppRun event, AppRun processes the event through the event handlers to get a new state. It calls the view function to turn the new state into the virtual DOM. It then renders the virtual DOM to the real DOM. Finally, if the AppRun application or AppRun components have defined the rendered function, AppRun calls the rendered function to give us an opportunity to change the actual DOM. The rendered function is the place where we can integrate with many third-party libraries perfectly.
With the AppRun extended architecture in mind, we are ready to build the example application. We will start by creating the page layout and styles.
Layout and Styles
We usually use a CSS framework to build the page layout and style the elements. For example, we will use Bootstrap for the admin dashboard application of this chapter.
Bootstrap is a free and open source front-end framework that contains the design templates for typography, forms, buttons, navigation, and other interface components. It was initially developed at Twitter as a framework to encourage consistency across internal tools. It has become one of the most popular front-end user interface frameworks for web applications.
We start developing the admin dashboard application by using the AppRun CLI–generated SPA boilerplate, which has already included the references to Bootstrap. We will use the Bootstrap CSS classes to create the admin dashboard layout, the responsive sidebar menus, and the rows and columns of the main content on the home page.
Bootstrap Dashboard Layout
Home Page Component
Dashboard and Sidebar Components
Using the stateless components, we break down the complicated HTML into smaller pieces from top to bottom. This abstracts away the complexity when it is not a concern at a certain stage. For example, when building the page layout, we only need to focus on that the dashboard has a sidebar and a widgets area. The elements inside the sidebar and the widgets area are considered when developing the Sidebar and Widgets functions. One level at a time is the much easier approach. The code is also easier to understand and maintain; just compare Listing 8-2 with Listing 8-1.
Once finished with the page layout, we can move to the sidebar and then the widget area.
Sidebar Menu
Menu Data
Menu Component
The Menu component supports nested child menus. It checks whether one menu item has child menus (line 2). If there are child menus, it creates the child menu structure (lines 3–11). Otherwise, it creates the regular menu item (lines 12–17).
The Bootstrap classes to make the menu responsive are flex-lg-column and flex-row (line 1). This means the menus should be displayed vertically in a column on a large screen. Otherwise, the menus should be displayed horizontally in a row. You can see that the Bootstrap classes are declarative. They clearly express our intention.
Rows and Columns
Row and Column
The Row and Column components are the <div> elements that have Bootstrap row and col classes. Both the Row and Column components have input parameters called props and children. The props parameter contains the JSX tag properties. The children parameter contains the child JSX tags, which are called by the two components directly without modification.
By using the props parameter, the two components accept additional CSS classes. The mergeClassName function is used to merge the additional CSS classes with the basic CSS classes. For example, <Row className="my-4" /> adds the my-4 class to the row. By the way, my-4 is the Bootstrap 4 spacing utility class that adds top and bottom margins to the row.1
Allowing the ability to add more classes to the stateless component is such a useful feature that we will demonstrate it again when discussing the notification and alert components.
Notifications and Alerts
Alert Component
Different Types of Alerts
It feels natural to add extra classes to the Alert component to define the message type by using the props parameter and the mergeClassName function.
Next, we will demonstrate another technique of using the props parameter in the Card component.
Cards
Card Component
Card List
The CardList component is a row in the widget area (line 2). It also organizes the KPI cards responsively using the CSS classes col-sm-4 and col-lg-2. When creating the Card component, the contents of the card (some emphasized text and some muted text) are passed into the Card component as the children parameters (lines 4–10).
So far, we have created AppRun stateless components in a top-down fashion to manage the UI complexity. We have also demonstrated how to use the props and children parameters. We encourage you to visit the open source project at https://github.com/yysun/apprun-bootstrap to get many AppRun components for Bootstrap. There is also an open source project that has the AppRun components: Framework7 ( https://framework7.io ) is a CSS framework for developing mobile applications; see https://github.com/yysun/apprun-f7 .
Components and Widgets
By using the AppRun stateless components, we can create some simple widgets that display only with dynamic element composition and styling such as the notification/alert widget and card widget. To create more complex widgets that have a rich user interface and user interactions, we will use the AppRun stateful components that integrate with third-party libraries. We will create four stateful components to demonstrate the approaches planned in Table 8-1.
Chart
Chart Component Pattern
The Chart component pattern renders the <canvas> node in the view function (line 5). It then creates the Chart object in the rendered function (line 9). That’s all that’s needed to create the structure of a Chart component. The rest of work is to follow the Chart.js document to develop the data structure to the charts.
Chart Component
Comparing Listing 8-11 with Listing 8-10, you will notice that you can plug the Chart.js code into the AppRun component to create the state (lines 7–17 and lines 19–92). The state is used to create the chart in the rendered function (line 99). The only difference is that the view function wraps the <canvas> node with a Card component (lines 93–95).
Adding a Card component to the chart is a particular requirement of the example application of this chapter. You can use the pattern (Listing 8-10) out of the box without adding the Card component. On the other hand, you can follow this example to add other elements or components if needed.
D3 Map
Map Component Pattern
Map Component
The Map component uses the AppRun D3 pattern in Listing 8-12, which uses the rendered function and the mounted and view functions to integrate D3.js. It is quite amazing that we can draw an interactive map by using only 30 lines of code (lines 12–41).
Data Tables
Table Component
The Table component loads the table data from the table-data.json file (line 2). It renders the regular HTML table in the view function (lines 6–27). In the rendered function, it applies the DataTables plug-in to the HTML table (lines 28–31).
You can see it is a simple approach to add search, sort, and pagination to the HTML table by using the DataTables jQuery plug-in.
Calendar
Calendar Component
FullCalender is also a jQuery plug-in. We can use the same method used for the DataTables to create the Calendar component. The view function creates a <div> node as the placeholder for rendering the calendar (lines 2–12). The rendered function applies the FullCalendar plug-in to the <div> node created in the view function with an object that has the configurations for the calendar (lines 20–32).
It is so much fun to integrate many great third-party libraries into the AppRun components. Again, we must stop here and move on to summarize all the techniques we have used. The Chart component demonstrates the pattern that creates the <canvas> node in the view function and creates the chart object in the <canvas> node in the rendered function. The Map component demonstrates the pattern that creates the <svg> node in the view function and creates the D3 SVG map in the <svg> node in the rendered function. It also demonstrates how to load data asynchronously. The Table component demonstrates the pattern of using jQuery plug-ins. It creates the <table> node in the view function and applies the jQuery plug-in to the <table> node in the rendered function. The Calendar component follows the jQuery plug-in pattern. It is only different in that it creates a <div> node as the placeholder.
Source Code and Examples
npm Scripts of This Chapter
Example | Script |
---|---|
The administrative dashboard | npm run admin |
AppRun components for Bootstrap | |
AppRun components for Framework7 |
Summary
We have seen how to use AppRun to build complex UIs in this chapter. AppRun was designed to support third-party libraries. The virtual DOM is resilient to allow other libraries to change to the DOM. Also, the extended AppRun architecture event lifecycle has the mounted and rendered functions to makes it easy to use other libraries in AppRun applications.
Using jQuery and the jQuery plug-ins is not an anti-pattern. It is welcomed and encouraged. We embrace third-party libraries and recommend you use them because it is an important AppRun application development technique.
In the next chapter, we will introduce another important technique, server-side rendering.