NestedSlot presenter with own url- how to setup url for NestedSlot presenters

88 Views Asked by At

I have parent presenter: UsersListPresenter that contains nested presenter: UserPresenter in NestedSlot.

  public class UsersListPresenter extends ApplicationPresenter<UsersListPresenter.MyView, UsersListPresenter.MyProxy> implements UsersListUiHandlers,
OpenWindowEvent.OpenModaHandler, UserAddedEvent.UserAddedHandler {
    @ProxyStandard
    @NameToken(ClientRouting.Url.users)
    @UseGatekeeper(IsUserLoggedGatekeeper.class)
    public interface MyProxy extends TabContentProxyPlace<UsersListPresenter> {}

    @TabInfo(container = AppPresenter.class)
    static TabData getTabLabel(IsUserLoggedGatekeeper adminGatekeeper) {
        return new MenuEntryGatekeeper(ClientRouting.Label.users, 1, adminGatekeeper);
    }

    public interface MyView extends View, HasUiHandlers<UsersListUiHandlers> {
        void setUsers(List<UserDto> users);
        void addUser(UserDto user);
    }

    public static final NestedSlot SLOT_USER_WINDOW = new NestedSlot();
    //interface Driver extends SimpleBeanEditorDriver<UserDto, UserEditor> {}
    private static final UserService userService = GWT.create(UserService.class);
    private AppPresenter appPresenter;
    private UserTestPresenter userPresenter;

    @Inject
    UsersListPresenter(EventBus eventBus, MyView view, MyProxy proxy, AppPresenter appPresenter, UserTestPresenter userPresenter) {
        super(eventBus, view, proxy, appPresenter, AppPresenter.SLOT_TAB_CONTENT);
        this.appPresenter = appPresenter;
        this.userPresenter = userPresenter;
        getView().setUiHandlers(this);
    }
    @Override
    protected void onBind() {
        super.onBind();
        updateList();
        setInSlot(SLOT_USER_WINDOW, userPresenter);
        addRegisteredHandler(OpenWindowEvent.getType(), this);
    }
    @Override
    protected void onReveal() {
        super.onReveal();
        initializeApplicationUiComponents(ClientRouting.Label.users);
    }

    @Override
    public void onOpenModal(OpenWindowEvent event) {
        openModal(event.getUser());
    }
    @Override
    public void openModal(UserDto user) {
        userPresenter.openModal(user);
    }
}

public class UsersListView extends ViewWithUiHandlers<UsersListUiHandlers> implements UsersListPresenter.MyView {
    interface Binder extends UiBinder<Widget, UsersListView> {}

    @UiField
    SimplePanel windowSlot;

    @Inject
    UsersListView(Binder uiBinder) {
        initWidget(uiBinder.createAndBindUi(this));
    }
    @Override
    public void setInSlot(Object slot, IsWidget content) {
        if (slot == UsersListPresenter.SLOT_USER_WINDOW) {
            windowSlot.setWidget(content);
        }
    };
}

 public class UserTestPresenter extends Presenter<UserTestPresenter.MyView, UserTestPresenter.MyProxy> implements UserTestUiHandlers {
    public interface MyView extends View, HasUiHandlers<UserTestUiHandlers> {
        void openModal(UserDto user);
    }
    @ProxyStandard
    @NameToken("/user/{userid}")
    public interface MyProxy extends ProxyPlace<UserTestPresenter> {
    }

    private PlaceManager placeManager;

    @Inject
    public UserTestPresenter(EventBus eventBus, MyView view, MyProxy proxy, PlaceManager placeManager) {
        super(eventBus, view, proxy, UsersListPresenter.SLOT_USER_WINDOW);
        this.placeManager = placeManager;
        getView().setUiHandlers(this);

    }
    @Override
    public void prepareFromRequest(PlaceRequest request) {
        GWT.log("Prepare from request " + request.getNameToken());
    }
    @Override
    protected void onReveal() {
        super.onReveal();
    };
    public void openModal(UserDto user) {
        getView().openModal(user);
    }
    @Override
    public void onSave(UserDto user) {
        // TODO Auto-generated method stub
        MaterialToast.fireToast("onSaveClick in new presenter for " + user.toString());
    }
    @Override
    public void onClose() {
        PlaceRequest placeRequest = new PlaceRequest.Builder().nameToken("/users/{userid}").with("userid", "list").build();
        placeManager.revealPlace(placeRequest);
    }

public class UserTestView extends ViewWithUiHandlers<UserTestUiHandlers> implements UserTestPresenter.MyView {
    interface Binder extends UiBinder<Widget, UserTestView> {}

    @UiField
    MaterialRow main;
    @UiField
    MaterialWindow window;
    @UiField
    MaterialLabel userName, userFullName;
    @UiField
    MaterialButton saveButton;
    private HandlerRegistration saveButtonClickHandler;

    @Inject
    UserTestView(Binder uiBinder) {
        initWidget(uiBinder.createAndBindUi(this));
        // adding default click handler
        saveButtonClickHandler = saveButton.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {}
        });
    }

    @Override
    public void openModal(final UserDto user) {
        userName.setText(user.getEmail());
        userFullName.setText(user.getId() + " " + user.getEmail());
        saveButtonClickHandler.removeHandler();
        saveButtonClickHandler = saveButton.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                getUiHandlers().save(user);
            }
        });
        window.openWindow();
    }


}

when user from list is clicked the window with clicked users is opened. At this moment url should change from http://localhost:8080/cms/#/users/list to http://localhost:8080/cms/#/user/3

for better understanding below is screencast from that code: enter image description here

and now some job done, but still not ideal: enter image description here

here is my gwtp configuration:

public class ClientModule extends AbstractPresenterModule {

    @Override
    protected void configure() {
        bind(RestyGwtConfig.class).asEagerSingleton();
        install(new Builder()//
        .defaultPlace(ClientRouting.HOME.url)//
        .errorPlace(ClientRouting.ERROR.url)//
        .unauthorizedPlace(ClientRouting.LOGIN.url)//
        .tokenFormatter(RouteTokenFormatter.class).build());
        install(new AppModule());
        install(new GinFactoryModuleBuilder().build(AssistedInjectionFactory.class));
        bind(CurrentUser.class).in(Singleton.class);
        bind(IsAdminGatekeeper.class).in(Singleton.class);
        bind(IsUserLoggedGatekeeper.class).in(Singleton.class);
        bind(ResourceLoader.class).asEagerSingleton();
    }
}

As You can see I use tokenFormatter(RouteTokenFormatter.class)

how it can be achieved with gwtp framework?

1

There are 1 best solutions below

7
Ümit On

One way to achieve this is to change the URL of your UserListPresenter to support passing in the user id as an optional parameter:

@NameToken("/users/{userid}")
public interface MyProxy extends ProxyPlace<UserListPresenter> {
}

You need to override the prepareFromRequest method of your UserListPresenter and there you check if the userid is set and open your modal window if it is.

@Override
public void prepareFromRequest(PlaceRequest request) {
    String userid = request.getParameter("userid", "list");
    if (userid != "list") {
        # open modal
    }
    else {
        # close modal
    }
}

You also need to change the logic when you click your on a user in your list:

@Override
public void onOpenModal(OpenWindowEvent event) {
    PlaceRequest placeRequest = new PlaceRequest.Builder()
      .nameToken("/users/{userid}")
      .with("userid", event.getUser().getId())
        .build();
    placeManager.revealPlace(placeRequest);
}

This will change the URL and open the modal.