Log in to a main screen with sidebar navigation

I’ve been learning a good bit about Vaadin lately, including Navigators, in order to get my web app to do what I would like for it to do. So far, I’ve been able to have a simple Login View lead to a simple Main View, mostly by following the
wiki about simple logins
, with a bit of customization from the
LoginForm add-on
. Works like a charm. The next step was for me to get a lovely menu layout that is shown when the user logins in, much like the
Valo Theme Demo
. I was able to replicate almost the entire thing easily by following
the source for it on GitHub
, with responsiveness and all. Now I just need to put the two things together.
Having a login screen:

Take the user to a main view with a sidebar menu:

…with all of the responsiveness intact, of course. What is the best approach to handle this? I’ve tried using a sub-Navigator on the Main View, but I get a non-responsive UI that doesn’t go all the way down the page:

Solution discovered!

There were actually two things going wrong. (I always seem to run into these in pairs, strangely.) First, it wasn’t extending to the entire height of the browser window. This is simply because I never set my MainView class as setSizeFull(true). So, in my constructor for this view, I just added that line:

... public MainView(SchedulingUI mainUI) { // The components that make up this main view. this.mainUI = mainUI; this.setSizeFull(); ... Not sure if I need this. in front of it, but it works, anyway.

The second issue is that this view isn’t responsive, despite calling Responsive.setResponsive() on it. This MainView class extends CustomComponent, which apparently means that Responsive.setResponsive() doesn’t work on it. So, I just had manually added the “valo-menu-responsive” style to the UI, like so:

...
MainView.this.mainUI.addStyleName("valo-menu-responsive");
...

That allowed it to finally be responsive.

Oh, I actually did have a third problem that I didn’t mention before: After logging in, doing a browser refresh caused a blank screen to appear instead of the Main View or even the Login View again. I tried a Hail Mary of just adding the @PreserveOnRefresh annotation to the main UI class. Problem solved.

So, at least for the moment, I am very happy! I do hope that this ends up helping someone else, too.

Mmm, great that you solved it! It’s really a problem that the responsive menu styles in Valo are currently not documented anywhere. It’s really overdue and on my list.

One note that I’d like to make is that our current best-practice recommendation is that login view should

not

be handled by the navigator (so don’t do it by the Book – the example there doesn’t follow the best practice). So, the navigator should
not
normally be bound to the UI, but to a ComponentContainer in the main view. The main reason is that the login view is not “content” as such, which you’d need to refer directly, but just part of the process of using the application. The main purpose of Navigator is to navigate “business functionalities”, such as some identifiable content, which are usually shown in a sub-view of the main view. Login is not a “business functionality”.

Yeah, I was following that wiki article about how to
create a simple login
, combining it with a menu-style layout–both of which use a Navigator.

I’ve seen that Jens Jansson also recommends that a login page should not use a Navigator
in a different thread
. However, I do not know how to create it otherwise. Is there a nice tutorial set up that could help me do so? Or, at least, could you please point me in the right direction with how to make such a login page work without a Navigator?

I did a little looking around, but still cannot find any alternative method to create the Login page for the web app besides Navigator. Should it be a separage Page? Or a second UI? How do I go about implementing either of those while keeping the Vaadin Session the same (so it can store username and access flags)?

I even found that the Book of Vaadin
recommends using Navigator
to create the various views and navigate between them. I guess that needs to be updated?

Chris,

Take a look at https://github.com/vaadin/dashboard-demo.

Yes, the book needs to be updated.

I think it should go the old way, where you manage the login view and main view by yourself by setting the view class to the UI with setContent().

Something like:

class MyUI extends UI {
  public void init(...) {
    setContent(new LoginView(user ->
        setContent(new MainView(user))));
  }
}

(Here we pass a login listener callback to the LoginView, to be able to do the view logic here in the UI class, but the LoginView could of course handle the creation of the MainView and switching to it, in which case we’d only do “setContent(new LoginView())” in the UI class.)

Then, in the MainView, use Navigator to control some SingleComponentContainer inside it, such as a Panel.

Nice! Thank you, @Edison and @Marko! I’ll give this a whirl as soon as my schedule allows.

One small curiosity: Will this method take into account a user who presses the browser’s Back/Forward/Refresh buttons? i.e., if a user logs out and walks away, then someone else approaches the computer and hits the browser’s Back button, will it take that person to the previous page, which had the logged-in content? Or will it be smart enough to say “Nope! You need to log in, buddy!”

Also, I’m guessing the URI fragments won’t show up until a user is logged in and starts using the Navigator.

Once the user logs out or the session times out, the application state is reset and the user gets the login view, where the Navigator is not used and the URI fragment does not have any effect. That’s one basic safeguard against navigating back to logged-in state, although your app should also have some authorization verification for any view changes.

The Dashboard demo indeed gives one approach, although it contains a lot of stuff irrelevant to most applications, such as Google Analytics tracking.