Context Based Dashboard

How would I implement a context-based dashboard?

E.g.: I have a DashboardLayout that is inherited by all dashboard views.
Additionally there’s a overview page, a settings page and so on.
In the header bar of the dashboard layout there is a combo box to switch the context to.

How would I store the context and how can I access that context in the layout, overview and settings page? (the context would be a jpa entity, is it better to store the id, or the whole entity?)

I don’t understand your requirements

Can you make an example?

Auth0 has that in their dashboard if you know that.

“context” refers to the thing I want to switch (context is a project in my case)
If you switch the context, the dashboard is now used to manage the new context, but under the same url
image.png

On “Switch context”, all projects of the user should be listed, but how that’s done is on my implementation side

Did you get this solved? I’m not sure if I understood the issue, but if using Spring, I typically store that kind of detail in UI scope bean and then different parts of the UI can get the “context” via the same bean injected into them.

But you can store that also for example to your parent layout and fetch the context from that (e.g. using findAncestor(Component.class) method).

If you want to avoid dependencies with your components, make them listen some custom “context changed” event that you fire from the component that allows to select the new context. To fire the events, you can even use the built-in event bus in each components:

`@Route
public class MainView extends VerticalLayout {

public MainView(IpApiService service) {
     
    Button b = new Button("Change context", e-> {
        getEventBus().fireEvent(new ContextChangedEvent(this));
    });
    add(b, new Dashboard());
    
}

public String getContext() {
    return "foo";
}

public static class ContextChangedEvent extends ComponentEvent<MainView> {

    public ContextChangedEvent(MainView view) {
        super(view, false);
    }
    
}


public static class Dashboard extends VerticalLayout {

    public Dashboard() {
    }
    
    void initDashboard() {
        // TODO consume services etc to fill in details
        String context = findAncestor(MainView.class).getContext();
        Notification.show("Just Do It!");
    }

    @Override
    protected void onAttach(AttachEvent attachEvent) {
        super.onAttach(attachEvent);
        initDashboard();
        findAncestor(MainView.class).addListener(ContextChangedEvent.class, e -> initDashboard());
    }

}

}

`

Hey, no I didn’t solve this yet, but I think your solution is a good starting point for me :slightly_smiling_face: I basically have a layout, which has a header on which you can change the context via a drop down menu. The view should then use the context to render accordingly (data from context, etc.). So all views would need to have access to the context via the layout (as it is stored in the layout). I think I could implement that with your solution, or am I missing something? You can imagine a context as a Project by a User.

Sounds about right.

But as said, it can be implemented in many ways. As all the pieces in your UI uses the same parent layout instance, that is quite good candidate to store shared data (if you are not using dependency injection).

Would the layout be reused for new browser tabs/browser windows? or is the layout created for each tab?

Each tab, sharing components between tabs (UIs) won’t work as you would expect

I guess it gets recreated each time

Okay, alright. :slightly_smiling_face: Maybe I combine it then with a cookie or the http session

I think storing it in the VaadinSession suits my needs the best. Is there a way to listen to attribute changes? So that if I have a view open in 2 different windows, and I change the context in one window, I can refresh the other window to now render the new context?

Are you sure you also want other window to react on the context change? If so there are couple things to take into consideration: getting the other UIs updated (Push/polling) and UI synchronization. If you happen to use Spring or CDI, I’d use a session scoped bean to share users UIs and trigger changes via that.

And then that would also become the most natural place for your “context”.

“Single class” example of the principle using Spring
Application.java (2.54 KB)

I’m not 100% sure if I need all browser tabs to be synchronized to one context, but I was curious if the possibility is there. But now I know it would be possible. Thank you for your help :slightly_smiling_face: Really appreciate that.