Introduction
When building business web apps, the Master-Detail-View pattern is quite common.
The Master-View often contains a list or grid of items, which users can scroll, sort and filter to get an overview. Usually, the items in the Master-View are rendered with a subset of fields, to avoid information overloading or vertical scrolling.
When users want more details about an item, they usually select an item and this item will be shown in a Detail-View. This Detail-View usually shows all the information about the item as well as some actions that can be performed on this item, like edit, delete or print, for example.
Hilla offers different approaches to implement the Master-Detail-View pattern, and the recent 24.8 release just added another approach. In this blog post, I will show and compare three existing approaches and the new Master-Detail Layout component that was introduced in 24.8.
Example application
To show and compare the different approaches, I will use a simple example application. This application offers the ability to C.R.U.D. tasks. The tasks can be listed, sorted and filtered in a Master-View and created, read, updated and deleted in a Detail-View.
AutoCrud component
Hilla offers the AutoCrud component to provide a simple way to implement C.R.U.D. functionality in a Master-Detail-View pattern.
Master- and Detail-View are combined in one view. The AutoCrud components uses the AutoGrid component to list, sort and filter all tasks, and the AutoForm component to create, read, update and delete a task. Both components can be customized to a certain degree on the component-level, for example by specifying which columns and fields should be displayed. You can also customize the underlying AutoGrid and AutoForm components, for example by specifying custom column renderers or by adjusting the Form Layout that is used to render the Detail-View in the side panel.
The width of the side panel can be adjusted by the user, and the form has default break points to change its rendering when more or less space is available.
There is also a built-in support for mobile devices. If you tap on a task in the list, the Detail-View will be shown at full screen size.
The AutoCrud component does not provide a deep-linking mechanism for the Detail-View, which means you can’t share a link like tasks/1
that points directly to the Detail-View of the task with the ID 1. Another disadvantage is the decline in usability when you want to display a lot of information in the Master-View and the Detail-View, because both have to share the available space and the Detail-View overlaps the Master-View quickly.
Pros:
- Easy to implement
Cons:
- No (out-of-the-box) deep-linking to Detail-View
- Limited usability for complex objects (with lots of information)
Detail-Dialog
The next approach, I want to describe also combines the Master- and Detail-View in one view. It uses an AutoGrid component to list, sort and filter the tasks and once a user clicked on a task, the task is opened in a Dialog component that handles the Detail-View.
The dialog shown is modal by default, and it can be resizable and draggable. The AutoForm component in the dialog keeps its responsive layout, which means the dialog is still usable on mobile devices.
Speaking of mobile devices: The dialog can be closed in three different ways, but not all of them are supported or user-friendly on a mobile device. The dialog can be closed in the following ways: By pressing the Esc
key, clicking outside the Dialog, or programmatically, for example by clicking on a button.
Pros:
- Easy to implement
- Flexible Master- and Detail-Views
Cons:
- No (out-of-the-box) deep-linking to Detail-View
- Dialog limitations on mobile devices
Using routes
Approach number three is based on two separate views (or React components), each on its own route. The Master-View uses the AutoGrid component and is rendered on a route like /tasks
. The Detail-View uses the AutoForm component and is rendered on a route like /tasks/{taskId}
. Both views and their components can use the maximum space available and can be customized without any limitation of the other component being on the same page. This approach also supports deep-linking to Detail-Views, because each Detail-View has a URI.
But this approach has some disadvantages. The navigation between the two views needs to implemented. Fetching the task in the Detail-View using its ID, has to be implemented as well. From a user experience perspective, this approach has another disadvantage: The AutoGrid component in the Master-View will lose its state, when the user navigates to the Detail-View, because the component will be unmounted and removed from the DOM. This means, the AutoGrid component cannot remember its current scroll-position, the selected item, the current sorting and filtering. This results in a productivity decline when users navigate a lot between Master- and Detail-View and when they have to re-scroll, re-sort and re-filter again and again.
Pros:
- Flexible Master- and Detail-Views
- Deep-linking to Detail-View
Cons:
- Additional implementations for navigation and data fetching
- AutoGrid in Master-Views loses state on navigation
Master-Detail Layout component
Vaadin added a new Master-Detail Layout component in Version 24.8 as a preview feature. Due to the fact that Vaadin Flow does not have a component like AutoCrud, this new component brings more simplification when creating this kind of user interfaces in Flow. For Hilla instead, the additional value compared to the existing AutoCrud component is smaller.
Compared to AutoCrud the Master-Detail Layout component adds more control for things like overlay breakpoints and the Stack or Overlay Mode. It also supports a vertical split of Master- and Detail-View.
Configuring the Master-Detail Layout component to use the Stack Mode results in a user experience that is very similar to the routes-based approach described before. The Detail-View fully covers the Master-View.
The benefit compared to the routes-based approach is that the Master-View is not unmounted while the Detail-View is shown. This means it keeps its state, like the current filtering and sorting, and users will return to this exact state of the Master-View when they close the Detail-View. Unfortunately, this also means that there is still no deep-linking support for the Detail-View.
To achieve this, the Router integration of the Master-Detail Layout component needs to be added. This requires some additional effort to set up the Router Layout in the right way. The navigation and data-fetching has to be implemented as well. Please check out src/main/frontend/views/mdl-router-integration-tasks
in the source code of the example app on GitHub to find a working example for Router integration with the Master-Detail Layout component.
Pros:
- Easy to implement
- Flexible Master- and Detail-Views with Stack and Overlay mode
- Horizontal and vertical split of Master- and Detail-View
Cons:
- No deep-linking to Detail-View, except with Router integration
- Router integration requires additional implementations for navigation and data fetching
Summary
There are quite a few options to choose from, when you want to implement the Master-Detail-View pattern in Hilla. Each approach has its benefits, but none of them is perfect. Depending on your requirements, you will most likely find a solution that works well, but under certain circumstances you may have to invest a little extra effort when you want to achieve things like deep-linking for the Detail-View and want to avoid the loss of state of the Master-View at the same time.
You can find the source code of the shown example Hilla app at GitHub.
Image Credits:
- Cover image source: https://www.flickr.com/photos/thomashawk/53990010319
- Cover image license: https://creativecommons.org/licenses/by-nc/2.0/deed.en