All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.mateu.mdd.vaadin.components.views.AbstractViewComponent Maven / Gradle / Ivy

There is a newer version: 1.1.60
Show newest version
package io.mateu.mdd.vaadin.components.views;

import com.google.common.base.Strings;
import com.vaadin.event.ShortcutAction;
import com.vaadin.icons.VaadinIcons;
import com.vaadin.shared.ui.ContentMode;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Layout;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.ValoTheme;
import io.mateu.mdd.core.app.AbstractAction;
import io.mateu.mdd.core.interfaces.ListView;
import io.mateu.mdd.core.layout.MiFormLayout;
import io.mateu.mdd.core.ui.MDDUIAccessor;
import io.mateu.mdd.shared.CSS;
import io.mateu.mdd.vaadin.MateuUI;
import io.mateu.mdd.vaadin.actions.AcctionRunner;
import io.mateu.mdd.vaadin.components.ComponentWrapper;
import io.mateu.mdd.vaadin.components.HomeComponent;
import io.mateu.mdd.vaadin.components.app.views.firstLevel.AreaComponent;
import io.mateu.mdd.vaadin.components.app.views.firstLevel.FakeComponent;
import io.mateu.mdd.vaadin.components.app.views.firstLevel.MenuComponent;
import io.mateu.mdd.vaadin.navigation.MateuViewProvider;
import io.mateu.mdd.vaadin.navigation.View;
import io.mateu.mdd.vaadin.navigation.ViewStack;
import io.mateu.mdd.vaadin.util.VaadinHelper;
import io.mateu.util.notification.Notifier;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;

public abstract class AbstractViewComponent> extends VerticalLayout {

    private final String uuid = UUID.randomUUID().toString();
    private VaadinIcons icon;
    protected Layout actionsSection;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        if (!super.equals(o)) return false;
        AbstractViewComponent that = (AbstractViewComponent) o;
        return uuid.equals(that.uuid);
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), uuid);
    }

    private Component header;
    private NavBarComponent navBar;
    private Label titleLabel;
    private Label subtitleLabel;
    private CssLayout actionsContainer;
    private CssLayout kpisContainer;
    private View view;
    protected CssLayout bar;
    protected CssLayout actions;
    protected CssLayout subheader;
    protected Map actionsByMethod = new HashMap<>();
    protected Map menuItemsById = new HashMap<>();
    protected Map> menuItemsByGroup = new HashMap<>();
    protected List menuItemIdsUnseen = new ArrayList<>();
    private String title;
    private String subtitle;
    private HorizontalLayout hiddens;
    private boolean backable;
    private boolean built;
    private AbstractViewComponent parentView;
    private Label iconLabel;
    private Component backButton;

    public AbstractViewComponent getParentView() {
        return parentView;
    }

    public VaadinIcons getIcon() {
        return icon;
    }

    public void setIcon(VaadinIcons icon) {
        this.icon = icon;
    }

    public void setParentView(AbstractViewComponent parentView) {
        this.parentView = parentView;
    }

    public CssLayout getKpisContainer() {
        return kpisContainer;
    }

    public AbstractViewComponent() {
    }

    public boolean esForm() {
        return false;
    }

    public void addActionsBar(boolean top) {
        if (!isBarHidden()) {

            if (top) {
                bar = new CssLayout();
                bar.addStyleName("actionsbar");
                bar.addStyleName(CSS.NOPADDING);
                menuItemsById = new HashMap<>();
                if (getActionsBarContainer() != null) getActionsBarContainer().addComponent(bar);
            } else {
                actionsSection = (MDDUIAccessor.isMobile())?new VerticalLayout():new MiFormLayout();
                actionsSection.addStyleName("section");
                if (false) {
                    actionsSection.setSizeUndefined();
                    actionsSection.addStyleName("section");
                }
                actionsSection.addStyleName("sectioncard");

                VerticalLayout fieldGroup;
                actionsSection.addComponent(fieldGroup = new VerticalLayout());
                fieldGroup.setWidthFull();
                fieldGroup.addStyleName(CSS.NOPADDING);

                HorizontalLayout fieldGroupHeader = null;
                fieldGroup.addStyleName("fieldgroup");
                fieldGroup.addComponent(fieldGroupHeader = new HorizontalLayout());
                fieldGroup.setWidthFull();
                fieldGroupHeader.setWidthFull();
                fieldGroupHeader.addStyleName("fieldgroupheader");

                String actionsTitle = getMainActionsTitle();
                String actionsText = getMainActionsText();

                Label c;
                fieldGroupHeader.addComponent(c = new Label(actionsTitle));
                c.addStyleName(ValoTheme.LABEL_H4);

                if (!"".equals(actionsText)) {
                    Label l;
                    fieldGroup.addComponent(l = new Label(actionsText, ContentMode.HTML));
                    l.setWidthFull();
                }

                getActionsContainer().addComponent(actionsSection);

                actions = new CssLayout();
                actions.addStyleName("formactionsbar");
                actions.addStyleName(CSS.NOPADDING);
                fieldGroup.addComponent(actions);
                fieldGroup.setComponentAlignment(actions, Alignment.BOTTOM_RIGHT);
            }

        }
    }

    public String getMainActionsText() {
        return "";
    }

    public String getMainActionsTitle() {
        return "Actions";
    }

    public void hideHeader() {
        header.setVisible(false);
    }

    public boolean expandOnOpen() {
        return false;
    }

    public boolean mustCreateHeader() {
        return true;
    }

    protected Component createHeader() {
        HorizontalLayout l = new HorizontalLayout();
        l.setSpacing(false);

        l.addStyleName("viewHeader");
        l.setWidthFull();

        Component left;
        l.addComponent(left = createTitleLabel());

        hiddens = new HorizontalLayout();
        hiddens.addStyleName("hidden");
        hiddens.setWidth("0px");

        l.addComponent(hiddens);
        l.setExpandRatio(left, 1.0f);

        return l;
    }

    public void setStack(ViewStack stack) {
        boolean add = false; //MDDUIAccessor.isMobile();
        int pos = 0;
        if (!add && stack.size() > 0) {
            while (!add && pos < stack.size()) {
                View v = stack.get(pos);
                Component c = v.getComponent();
                if (c instanceof EditorViewComponent || c instanceof ListViewComponent) {
                    add = true;
                    break;
                }
                pos++;
            }
        }
        if (add && this instanceof AbstractViewComponent) {
            ((AbstractViewComponent) this).setBackable(true);
            if (this instanceof EditorViewComponent) {
                ((EditorViewComponent) this).setKpisContainer(kpisContainer);
                ((EditorViewComponent) this).buildIfNeeded();
                ((EditorViewComponent) this).rebuildActions();
            }
        }
    }

    private void addBreadCrumb() {
        ViewStack stack = MateuUI.get().getStack();
        int breadCrumbsNumber = 0;
        for (int i = 0; i < stack.size(); i++) {
            View v = stack.get(i);
            if (v.getViewComponent() != null && v.getViewComponent() != this && (v.getViewComponent() instanceof ListViewComponent || v.getViewComponent() instanceof EditorViewComponent)) {
                if (breadCrumbsNumber > 0) navBar.addComponent(new Label("/"));
                navBar.addComponent(new Label(v.getViewComponent().getTitle()));
                breadCrumbsNumber++;
            }
        }
    }

    private Component createTitleLabel() {

        kpisContainer = new CssLayout();
        kpisContainer.addStyleName(CSS.NOPADDING);
        kpisContainer.addStyleName("kpisContainer");
        kpisContainer.setSizeUndefined();

        HorizontalLayout hl = new HorizontalLayout();
        hl.addStyleName(CSS.NOPADDING);
        hl.setWidthFull();

        actionsContainer = new CssLayout();
        actionsContainer.addStyleName(CSS.NOPADDING);

        if (mustCreateHeader()) {
            iconLabel = new Label("", ContentMode.HTML);
            iconLabel.addStyleName("viewIcon");

            titleLabel = new Label("", ContentMode.HTML);
            titleLabel.addStyleName("viewTitle");

            subtitleLabel = new Label("", ContentMode.HTML);
            subtitleLabel.addStyleName("viewSubtitle");

            VerticalLayout titles = new VerticalLayout(titleLabel, subtitleLabel);
            titles.addStyleName(CSS.NOPADDING);
            titles.setSpacing(false);
            titles.setWidthUndefined();


            if (false && getIcon() != null) iconLabel.setValue(getIcon().getHtml());
            else iconLabel.setVisible(false);


            hl.addComponents(iconLabel, titles, kpisContainer, actionsContainer);
            hl.setExpandRatio(actionsContainer, 1);
        } else {
            hl.addComponents(actionsContainer, kpisContainer);
            hl.setExpandRatio(actionsContainer, 1);
        }
        hl.setComponentAlignment(actionsContainer, Alignment.TOP_RIGHT);
        hl.setComponentAlignment(kpisContainer, Alignment.TOP_RIGHT);


        return hl;
    }


    public void updateViewTitle(String newTitle, String newSubtitle) {
        title = newTitle;
        subtitle = newSubtitle;
        updatePageTitle();
    }

    public void updatePageTitle() {
        if (titleLabel != null) {
            titleLabel.setValue(getTitle());
        }
        if (subtitleLabel != null) {
            subtitleLabel.setValue(getSubtitle());
        }
        if (iconLabel != null) {
            if (false && getIcon() != null) {
                iconLabel.setValue(getIcon().getHtml());
                iconLabel.setVisible(true);
            } else iconLabel.setVisible(false);
        }
    }

    public HorizontalLayout getHiddens() {
        return hiddens;
    }

    public String getTitle() {
        return title != null?title:toString();
    }

    public String getSubtitle() {
        return subtitle != null?subtitle:"";
    }

    public String getPageTitle() {
        return getTitle();
    }

    public A setTitle(String title) {
        this.title = title;
        return (A) this;
    }

    public View getView() {
        return view;
    }

    public void setView(View view) {
        this.view = view;
    }

    public Layout getActionsBarContainer() {
        return actionsContainer;
    }
    public Layout getActionsContainer() {
        return this;
    }


    public A buildIfNeeded() {
        if (!built) {
            try {
                build();
            } catch (Exception e) {
                Notifier.alert(e);
            }
        }
        return (A) this;
    }

    public A build() throws Exception {
        addStyleName("viewcomponent");
        setWidthFull();

        addComponent(navBar = createNavBar());
        addBack(navBar);
        if (mustAddBreadcrumb()) addBreadCrumb();

        if (mustAddHeader()) addComponent(header = createHeader());

        addStatusBar();

        addActionsBar(true);
        if (this instanceof ListViewComponent) addViewActionsMenuItems(getActionsContainer(), getActions());

        addComponent(subheader = new CssLayout());
        subheader.addStyleName(CSS.NOPADDING);
        subheader.setWidth("100%");
        subheader.setVisible(false);

        built = true;
        return (A) this;
    }

    public void addStatusBar() {
    }

    public boolean mustAddHeader() {
        return true;
    }

    public boolean mustAddBreadcrumb() {
        return true;
    }

    public NavBarComponent createNavBar() {
        return new NavBarComponent();
    }

    private void addBack(HorizontalLayout bar) {
            if (!isActionPresent("back")) {
                Button b;
                bar.addComponent(backButton = b = new Button("", VaadinIcons.ARROW_LEFT), 0);
                //bar.addComponent(i = b = new Button("Back", VaadinIcons.ARROW_LEFT));
                b.addStyleName(ValoTheme.BUTTON_QUIET);
                b.addStyleName("test-back");
                b.addClickListener(e -> {
                    try {

                        if (AbstractViewComponent.this.beforeBack()) MDDUIAccessor.goBack();

                    } catch (Throwable throwable) {
                        Notifier.alert(throwable);
                    }
                });
                b.setVisible(false);

                addMenuItem("back", backButton);

            } else {
                backButton = getMenuItemById("back");
            }
            if (isBackable()) backButton.setVisible(true);
    }

    public void addViewActionsMenuItems(Layout bar, List actions) {

        if (isActionPresent("back")) {
            getMenuItemById("back").setVisible(isBackable());
        }

        boolean firstButton = true;

        for (AbstractAction a : actions) {
                Component i = null;
                if (!isActionPresent(a.getId())) {
                    Button b;
                    i = b = new Button(a.getCaption(), a.getIcon());
                    if (!bar.getStyleName().contains("actionsbar")) b.addStyleName(ValoTheme.BUTTON_QUIET);
                    i.addStyleName("test-action-" + a.getId());
                    b.addClickListener(e -> {
                        try {

                            //añade validación, confirmación y updatea después de ejecutar
                            Runnable r = new Runnable() {
                                @Override
                                public void run() {

                                    try {
                                        new AcctionRunner().run(a);
                                    } catch (Throwable ex) {
                                        Notifier.alert(ex);
                                        removeStyleName("refreshonback");
                                    }

                                }
                            };

                            boolean doIt = true;
                            if (AbstractViewComponent.this instanceof EditorViewComponent && a.isValidationNeeded()) {
                                doIt = ((EditorViewComponent)AbstractViewComponent.this).validate();
                            }

                            if (doIt) {
                                if (!Strings.isNullOrEmpty(a.getConfirmationMessage())) {
                                    VaadinHelper.confirm(a.getConfirmationMessage(), () -> {

                                        r.run();

                                        //todo: actualizar vista con los cambios en el modelo

                                    });
                                } else r.run();
                            }

                        } catch (Throwable throwable) {
                            Notifier.alert(throwable);
                        }
                    });

                    if (!Strings.isNullOrEmpty(a.getGroup())) menuItemsByGroup.computeIfAbsent(a.getGroup(), k -> new ArrayList<>()).add(i);
                    addMenuItem(a.getId(), i);

                    if (!Strings.isNullOrEmpty(a.getStyle())) i.addStyleName(a.getStyle());

                    if (Strings.isNullOrEmpty(a.getGroup())) {
                        bar.addComponent(i);
                        if (esForm() && firstButton) {
                            b.setClickShortcut(ShortcutAction.KeyCode.ENTER);
                            b.addStyleName(ValoTheme.BUTTON_PRIMARY);
                            firstButton = false;
                        }
                    }

                    a.addShortCut(b);

                } else {
                    i = getMenuItemById(a.getId());
                }
                if (i != null && !Strings.isNullOrEmpty(a.getStyle())) i.addStyleName(a.getStyle());
                i.setVisible(a.isVisible());
            }

        if (bar != null) if  (bar.getComponentCount() == 0) bar.setVisible(false);
    }

    public boolean beforeBack() {
        return true;
    }

    public void markAllAsUnseen() {
        menuItemIdsUnseen = new ArrayList<>(menuItemsById.keySet());
    }

    public List getUnseenActions() {
        return menuItemIdsUnseen;
    }

    public void removeUnseen() {
        for (String id : menuItemIdsUnseen) menuItemsById.get(id).setVisible(false);
    }

    public boolean isActionPresent(String id) {
        boolean found = menuItemsById.containsKey(id);
        if (found) menuItemIdsUnseen.remove(id);
        return found;
    }

    public Component getMenuItemById(String id) {
        return menuItemsById.get(id);
    }

    public void addMenuItem(String id, Component i) {
        menuItemsById.put(id, i);
    }

    public List getActions(String key) {
        return new ArrayList<>();
    }

    public List getActions() {
        return new ArrayList<>();
    }

    public List getMainActions() {
        return new ArrayList<>();
    }


    public AbstractAction getActionByMethod(Method m) {
        return actionsByMethod.get(m);
    }

    public void setAction(Method m, AbstractAction action) {
        actionsByMethod.put(m, action);
    }


    public boolean isBackable() {
        return backable;
    }

    public void setBackable(boolean backable) {
        this.backable = backable;
        if (backButton != null) backButton.setVisible(backable);
    }

    public boolean isBarHidden() {
        return false;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy